<p>In previous posts, we built a <a href="https://rviews.rstudio.com/2016/12/16/reproducible-finance-with-r-a-shiny-etf-map/">map to access global ETFs</a> and a simple <a href="https://rviews.rstudio.com/2017/04/21/a-shiny-app-for-importing-and-forecasting-commodities-prices-from-quandl/">Shiny app to import and forecast commodities data from Quandl</a>. Today, we will begin a project that combines those previous apps. Our end goal is to build an interactive map to access macroeconomic data via Quandl, allowing the user to choose an economic indicator and click on a country to access that indicator’s time series. For example, if a user wants to import and graph GDP-per-capita data from China, that user will be able to select <code>GDP per Capita</code> from a drop down and then click on China to display the time series. As usual, we’ll start with a Notebook for data import, test visualizations, and map building.</p>
<p>Careful readers will note that we are not simply reusing code from those previous projects; that is because we are going to introduce some new packages to our toolkit. Specifically:</p>
<ul><li><p>Instead of downloading a spatial data frame from <a href="http://www.naturalearthdata.com/">Natural Earth</a>, we will use the new R package <a href="https://cran.r-project.org/web/packages/rnaturalearth/rnaturalearth.pdf">rnaturalearth</a> and it’s function <code>ne_countries()</code> to import our geographic data.</p></li>
<li><p>Relatedly, we are not going work with a “spatial” data frame, but rather with a simple features data frame of class <code>sf</code>. Learn more <a href="https://cran.r-project.org/web/packages/sf/vignettes/sf1.html">here</a>.</p></li>
<li><p>Finally, when we test our data import of several macroeconomic data sets, we will use the <code>map()</code> function from the <a href="https://cran.r-project.org/web/packages/purrr/purrr.pdf">purrr</a> package instead of relying on <code>lapply()</code>, as we did previously when passing ticker symbols to <code>getSymbols()</code>. If you’re like me, you won’t be sad to be done with <code>lapply()</code>.</p></li>
</ul><p>Let’s get to it!</p>
<p>We are going to be working with a macroeconomic data source from the World Bank called World Development Indicators <a href="http://data.worldbank.org/products/wdi">(WDI)</a>. The <code>Quandl</code> code for WDI is <code>WWDI</code> and thus we’ll append <code>WWDI/</code> to each data set call.</p>
<p>One difference from our previous work with <code>Quandl</code> is that previously we imported and visualized global time series, such as the price of oil, gold or copper. By global, I mean these time series were not associated with a particular country. That simplified our job a bit because we did not need to supply a country code to <code>Quandl</code>. Today, we do need to include a country code.</p>
<p>Let’s start with a simple example and import GDP-per-capita data for China, whose country code is <code>CHN</code>. We will pass the string <code>WWDI/CHN_NY_GDP_PCAP_KN</code> to <code>Quandl</code>, which consists of the WDI code <code>WWDI/</code>, appended by the China country code <code>CHN</code>, appended by the GDP-per-capita code <code>_NY_GDP_PCAP_KN</code>.</p>
<pre><code>library(Quandl)
# Pass the code string to Quandl. 
China_GDPPC &lt;- Quandl(&quot;WWDI/CHN_NY_GDP_PCAP_KN&quot;, type = 'xts') %>% 
  # Add a nice column name
  `colnames&lt;-`(&quot;GDP Per Capita&quot;)

# Take a look at the result.
tail(China_GDPPC, n = 6)</code></pre>
<pre><code>##            GDP Per Capita
## 2010-12-31       30876.04
## 2011-12-31       33658.85
## 2012-12-31       36126.73
## 2013-12-31       38737.58
## 2014-12-31       41354.61
## 2015-12-31       43991.55</code></pre>
<p>That looks pretty good, but note that the data goes only to December of 2015 - not ideal, but fine for our illustrative purposes.</p>
<p>Our eventual Shiny app, though, will give the user a choice among many economic time series, and we want to test the import and visualization of all those choices. In addition to GDP-per-capita, let’s test GDP-per-capita growth, real interest rate, exchange rate, CPI, and labor force participation rate. Those offer a nice snapshot of a country’s economy.</p>
<p>To run our test in the code chunk below, we will first build a vector of data set codes. Note that each of them start with <code>WWDI/</code>, then <code>CHN</code>, and then the relevant code. Next, we will pipe that vector to <code>Quandl</code> using the <code>map()</code> function. <code>map()</code> takes a function, in this case the <code>Quandl()</code> function, and applies it to the elements in a vector, in this case our vector of data set codes. We also want to specify <code>type = &quot;xts&quot;</code>.</p>
<p>If we stopped our pipe there, the output would be a list of six time series and that would suit our testing purposes, but I don’t love having to look at a list of six. Thus, we’ll keep on piping and use the <code>reduce()</code> function from the <code>purrr</code> package and call <code>merge()</code> to combine the six lists into one xts object. That is much easier to deal with, and easier to pass to <code>dygraphs</code> for our test visualization. The last piped function will invoke <code>colnames&lt;-</code> to clean up the column names.</p>
<pre><code>library(purrr)
# Create a vector of economic indicators that can be passed to Quandl via map().
# Include names and values for easy naming of xts columns.
econIndicators &lt;- c(&quot;GDP Per Capita&quot; = &quot;WWDI/CHN_NY_GDP_PCAP_KN&quot;,
                  &quot;GDP Per Capita Growth&quot; = &quot;WWDI/CHN_NY_GDP_PCAP_KD_ZG&quot;,
                  &quot;Real Interest Rate&quot; = &quot;WWDI/CHN_FR_INR_RINR&quot;,
                  &quot;Exchange Rate&quot; = &quot;WWDI/CHN_PX_REX_REER&quot;,
                  &quot;CPI&quot; = &quot;WWDI/CHN_FP_CPI_TOTL_ZG&quot;,
                  &quot;Labor Force Part. Rate&quot; = &quot;WWDI/CHN_SL_TLF_ACTI_ZS&quot;)

# You might want to supply your Quandl api key. It's free to get one.
Quandl.api_key(&quot;d9EidiiDWoFESfdk5nPy&quot;)

China_all_indicators &lt;- 
  # Start with the vector of Quandl codes
  econIndicators %>% 
  # Pass them to Quandl via map(). 
  map(Quandl, type = &quot;xts&quot;) %>% 
  # Use the reduce() function to combine them into one xts objects.
  reduce(merge) %>% 
  # Use the names from the original vector to set nicer column names.
  `colnames&lt;-`(names(econIndicators))
# Have a look.
tail(China_all_indicators, n = 6)</code></pre>
<pre><code>##            GDP Per Capita GDP Per Capita Growth Real Interest Rate
## 2011-12-31       33658.85              9.012854          -1.472149
## 2012-12-31       36126.73              7.332031           3.523236
## 2013-12-31       38737.58              7.226936           3.692594
## 2014-12-31       41354.61              6.755778           4.732429
## 2015-12-31       43991.55              6.376423           4.270386
## 2016-12-31             NA                    NA                 NA
##            Exchange Rate      CPI Labor Force Part. Rate
## 2011-12-31      102.6904 5.410850                   76.7
## 2012-12-31      108.4435 2.624921                   77.0
## 2013-12-31      115.2980 2.627119                   77.3
## 2014-12-31      118.9863 1.996847                   77.6
## 2015-12-31      131.6298 1.442555                     NA
## 2016-12-31      124.1864 2.007556                     NA</code></pre>
<p>That seems to have done the job, and note that both CPI and Exchange have data up to December of 2016. Much better, and a sign that there will be date variation among countries and indicators. That won’t be crucial today, but it could be if we needed consistent dates for all of our data sets.</p>
<p>As a final step, let’s use <code>dygraph()</code> to visualize these time series to make sure things function properly before moving to Shiny.</p>
<pre><code>library(dygraphs)
dygraph(China_all_indicators$`GDP Per Capita`, main = &quot;GDP Per Capita&quot;)</code></pre>
<div></div>
<pre><code>dygraph(China_all_indicators$`GDP Per Capita Growth`, main = &quot;GDP Per Capita Growth&quot;)</code></pre>
<div></div>
<pre><code>dygraph(China_all_indicators$`Real Interest Rate`, main = &quot;Real Interest Rate&quot;)</code></pre>
<div></div>
<pre><code>dygraph(China_all_indicators$`Exchange Rate`, main = &quot;Exchange Rate&quot;)</code></pre>
<div></div>
<pre><code>dygraph(China_all_indicators$`CPI`, main = &quot;CPI&quot;)</code></pre>
<div></div>
<pre><code>dygraph(China_all_indicators$`Labor Force Part. Rate`, main = &quot;Labor Force Part. Rate&quot;)</code></pre>
<div></div>
<p>GDP-per-capita has been on a steady march higher, labor force participation plummeted in the 90’s and 2000’s, probably as the labor market became more market-oriented, and real interest rates look quite choppy. Plenty to explore, and it signals that our Shiny app might be a nice exploratory tool.</p>
<p>For now, it’s on to map-building!</p>
<p>In previous posts, we have started map-building by grabbing a spatial object from the internet. Today, we will use the new <code>rnaturalearth</code> package and its fantastic function <code>ne_countries()</code>. We will specify <code>type = &quot;countries&quot;</code> and <code>returnclass = 'sf'</code>. We could have set <code>returnclass = 'sp'</code> if we wanted to work with a spatial data frame, but I have been migrating over to the <code>sf</code> package and simple features data frames for mapping projects. Lots to learn here, but in general, it seems to use more tidy concepts than the <code>sp</code> package.</p>
<pre><code>library(rnaturalearth)
library(sp)
world &lt;- ne_countries(type = &quot;countries&quot;,  returnclass = 'sf')

# Take a peek at the name, gdp_md_est column and economy columns. 
# The same way we would peek at any data frame.
head(world[c('name', 'gdp_md_est', 'economy')], n = 6)</code></pre>
<pre><code>## Simple feature collection with 6 features and 3 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -73.41544 ymin: -55.25 xmax: 75.15803 ymax: 42.68825
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
##                   name gdp_md_est                   economy
## 0          Afghanistan      22270 7. Least developed region
## 1               Angola     110300 7. Least developed region
## 2              Albania      21810      6. Developing region
## 3 United Arab Emirates     184300      6. Developing region
## 4            Argentina     573900   5. Emerging region: G20
## 5              Armenia      18770      6. Developing region
##                         geometry
## 0 MULTIPOLYGON(((61.210817091...
## 1 MULTIPOLYGON(((16.326528354...
## 2 MULTIPOLYGON(((20.590247430...
## 3 MULTIPOLYGON(((51.579518670...
## 4 MULTIPOLYGON(((-65.5 -55.2,...
## 5 MULTIPOLYGON(((43.582745802...</code></pre>
<p>This output looks similar to an <code>sp</code> object, but it’s not identical. In particular, note the <code>geometry</code> column, which contains the multipolygon latitude and longitude coordinates. It’s a matter of personal preference, but I find this <code>sf</code> object more intuitive in terms of how the geometry corresponds with the rest of the data.</p>
<p>Now we’ll create our shading and popups. Note that this code is identical to when we were working with spatial data frames.</p>
<pre><code>library(leaflet)
# Create shading by GDP. Let's go with purples.
gdpPal &lt;- colorQuantile(&quot;Purples&quot;, world$gdp_md_est, n = 20)

# Create popup country name and income group so that something happens
# when a user clicks the map.
popup &lt;- paste0(&quot;&lt;strong>Country: &lt;/strong>&quot;, 
                world$name, 
                &quot;&lt;br>&lt;strong>Market Stage: &lt;/strong>&quot;, 
                world$income_grp)</code></pre>
<p>Now, it’s time to build our leaflet map. This code is nearly identical to our code from previous projects, but with one major change. As we saw above, we need to pass in a country code to <code>Quandl</code>, not a country name and not a ticker symbol. Thus, we don’t want to set <code>layerId = name</code>, but we also don’t need to add anything special to our <code>world</code> object. It already contains a column called <code>iso_a3</code>, and that column contains the country codes used by <code>Quandl</code>. Fantastic!</p>
<p>We just need to set <code>layerId = ~iso_a3</code> and we will be able to access country codes in our Shiny app when a user clicks the map. This is quite fortunate, but it also highlights a good reason to spend time studying the <code>world</code> object. It might contain other data that will be useful in future projects.</p>
<pre><code>leaf_world &lt;- leaflet(world) %>%
  addProviderTiles(&quot;CartoDB.Positron&quot;) %>% 
  setView(lng =  20, lat =  15, zoom = 2) %>%
      addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = .7, 
      
      # Note the layer ID. Not a country name! It's a country code! 
      
      color = ~gdpPal(gdp_md_est), layerId = ~iso_a3, popup = popup)

leaf_world</code></pre>
<div></div>
<p>Because <code>Quandl</code> uses the <a href="https://blog.quandl.com/api-for-economic-data">ISO 3-letter code</a> to identify a country, and because the <code>rnaturalearth</code> <code>sf</code> object already contains a column with iso_a3 country codes, building our map wasn’t very hard. It’s worth pointing out that in various projects, we have now built maps with three different layerIDs. In the Global ETF Map project, we built one map with <code>layerID = name</code>, using the built-in <code>name</code> column in the <code>rnaturalearth</code> object, and we built another map with <code>layerID = tickers</code>, using a column of tickers that we added ourselves with the <code>merge()</code> function. Now, today, we have a map with <code>layerID = iso_a3</code>, using the built-in column of country codes. We are building up a nice portfolio of maps with different layerIDs should we ever want or need them in the future.</p>
<p>That’s all for today. We’ll save that <code>leaflet_world</code> object for use in our Shiny app! See you next time.</p>