<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/gdp-data-via-api/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://rviews.rstudio.com/2018/09/12/gdp-via-api/"> R Views</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Today, we will look at the GDP data that is released every quarter or so by the Bureau of Economic Analysis <a rel="nofollow" href="https://www.bea.gov/data/gdp/gross-domestic-product" target="_blank">(BEA)</a>, and get familiar with the BEA API (see the documentation <a rel="nofollow" href="https://apps.bea.gov/API/bea_web_service_api_user_guide.htm" target="_blank">here</a>). For a primer on GDP in general, BEA publishes this <a rel="nofollow" href="https://www.bea.gov/sites/default/files/methodologies/nipa_primer.pdf" target="_blank">guide</a>.</p>
<p>To access the BEA API, we will need two packages, <code>httr</code> and <code>jsonlite</code>.</p>
<pre><code>library(tidyverse)
library(tidyquant)
library(httr)
library(jsonlite)</code></pre>
<p>We also need to know the API address and parameters to <code>get</code>. This information can be found in the API documentation referenced above. We supply our API key, the name of the data set (<code>NIPA</code>), the table name (<code>T10101</code>, which holds GDP data), and a frequency (<code>Q</code>, for quarterly).</p>
<pre><code>&quot;https://apps.bea.gov/api/data/?&amp;UserID=Your-API-Key Here&amp;method=GetData&amp;DataSetName=NIPA&amp;TableName=T10101&amp;Frequency=Q&amp;
Year=ALL&amp;ResultFormat=JSON&quot;</code></pre>
<p>We will pass that URL to the <code>fromJSON()</code> function of the <code>jsonlite</code> package to access the API, and include <code>simplifyDataFrame = FALSE</code> and <code>simplifyMatrix = FALSE</code> to turn off some of the built-in data helpers.</p>
<pre><code>key_string &lt;- 
paste(&quot;https://apps.bea.gov/api/data/?&amp;UserID=&quot;, 
      my_api_key,
&quot;&amp;method=GetData&amp;DataSetName=NIPA&amp;TableName=T10101&amp;Frequency=Q&amp;Year=ALL&amp;ResultFormat=JSON&quot;, 
      sep = &quot;&quot;)

bea_gdp_api &lt;- 
  fromJSON(key_string,
  simplifyDataFrame = FALSE, 
  simplifyMatrix = FALSE) 

str(bea_gdp_api, max=3)</code></pre>
<pre><code>List of 1
 $ BEAAPI:List of 2
  ..$ Request:List of 1
  .. ..$ RequestParam:List of 8
  ..$ Results:List of 5
  .. ..$ Statistic        : chr &quot;NIPA Table&quot;
  .. ..$ UTCProductionTime: chr &quot;2018-09-12T16:30:26.567&quot;
  .. ..$ Dimensions       :List of 9
  .. ..$ Data             :List of 7125
  .. ..$ Notes            :List of 1</code></pre>
<p>That worked, but the returned data is a monster (remove that <code>max = 3</code> argument and see what happens)!</p>
<p>Let’s use <code>pluck()</code> from the <code>purrr</code> package to extract the data we want by calling <code>pluck(&quot;BEAAPI&quot;,&quot;Results&quot;,&quot;Data&quot;)</code>. That command <code>plucks</code> the list called <code>BEAAPI</code>, then the list called <code>Results</code>, then the list called <code>Data</code>.</p>
<pre><code>bea_gdp_api &lt;- 
  fromJSON(&quot;https://apps.bea.gov/api/data/?&amp;UserID=084F6B76-36BE-431F-8F2A-54429DF5E04C&amp;method=GetData&amp;DataSetName=NIPA&amp;TableName=T10101&amp;Frequency=Q&amp;Year=ALL&amp;ResultFormat=JSON&quot;,
  simplifyDataFrame = FALSE, 
  simplifyMatrix = FALSE) %>% 
  pluck(&quot;BEAAPI&quot;,&quot;Results&quot;,&quot;Data&quot;)

str(bea_gdp_api[1])</code></pre>
<pre><code>List of 1
 $ :List of 9
  ..$ TableName      : chr &quot;T10101&quot;
  ..$ SeriesCode     : chr &quot;A191RL&quot;
  ..$ LineNumber     : chr &quot;1&quot;
  ..$ LineDescription: chr &quot;Gross domestic product&quot;
  ..$ TimePeriod     : chr &quot;1962Q1&quot;
  ..$ METRIC_NAME    : chr &quot;Fisher Quantity Index&quot;
  ..$ CL_UNIT        : chr &quot;Percent change, annual rate&quot;
  ..$ UNIT_MULT      : chr &quot;0&quot;
  ..$ DataValue      : chr &quot;7.3&quot;</code></pre>
<p>OK, we’re getting somewhere now – a list of 7125 lists of 9 elements. Looking at those 9 elements, we want the <code>TimePeriod</code>, the <code>LineDescription</code>, the <code>DataValue</code>, and for reasons we’ll see later, the <code>SeriesCode</code>. So, we want 4 items from each of those 7125 lists, and ideally we would like to convert them to a tibble.</p>
<p>We can use <code>map_df()</code> from <code>purrr</code> to apply the <code>extract()</code> function from <code>magrittr</code> and select just the list elements we want, and convert the results to a tibble. By appending <code>_df</code>, we are telling <code>map</code> to return a data frame.</p>
<pre><code>bea_gdp_api &lt;- 
  fromJSON(key_string,
  simplifyDataFrame = FALSE, 
  simplifyMatrix = FALSE) %>% 
  pluck(&quot;BEAAPI&quot;,&quot;Results&quot;,&quot;Data&quot;) %>% 
  map_df(magrittr::extract, c(&quot;LineDescription&quot;, &quot;TimePeriod&quot;, 
                              &quot;SeriesCode&quot;, &quot;DataValue&quot;)) 

str(bea_gdp_api)</code></pre>
<pre><code>Classes 'tbl_df', 'tbl' and 'data.frame':   7125 obs. of  4 variables:
 $ LineDescription: chr  &quot;Gross domestic product&quot; &quot;Gross domestic product&quot; &quot;Gross domestic product&quot; &quot;Gross domestic product&quot; ...
 $ TimePeriod     : chr  &quot;1962Q1&quot; &quot;1962Q2&quot; &quot;1962Q3&quot; &quot;1962Q4&quot; ...
 $ SeriesCode     : chr  &quot;A191RL&quot; &quot;A191RL&quot; &quot;A191RL&quot; &quot;A191RL&quot; ...
 $ DataValue      : chr  &quot;7.3&quot; &quot;3.7&quot; &quot;5.0&quot; &quot;1.3&quot; ...</code></pre>
<p>Much, much better. We now have a tibble, with 4 columns and 7125 rows. Let’s do some cleanup with <code>rename()</code> for better column names, and then make sure that the <code>percent_change</code> and <code>quarter</code> column are in a good format.</p>
<pre><code>bea_gdp_api &lt;- 
  bea_gdp_api %>% 
  group_by(LineDescription) %>% 
  rename(account = LineDescription, 
         quarter = TimePeriod, 
         percent_change = DataValue) %>% 
  mutate(percent_change = as.numeric(percent_change),
         quarter = yq(quarter))</code></pre>
<p><code>bea_gdp_api</code> is now a tibble that holds the quarterly percentage change for each of the GDP accounts used by the BEA, including total GDP change. Let’s take a closer look at each of the accounts whose data we have.</p>
<pre><code>bea_gdp_api %>% 
  count()</code></pre>
<pre><code># A tibble: 21 x 2
# Groups:   account [21]
   account                                                      n
   </code></pre>