Mapping in R Workshop

Author

Justin Dyck

Published

April 28, 2022

Load Required Packages

There are quite a few different mapping packages out there for R, but I like to use 3 main packages when it comes to just mapping. These are:

  • ‘sf’ for loading shapefiles, transforming coordinate systems, dealing with spatial data, etc. This is basically your “GIS” package.
  • ‘tmap’ for creating static maps.
  • ‘leaflet’ for creating interactive maps.
library(tidyverse)
library(colorspace)
library(sf)
library(leaflet)
library(tmap)

sf_use_s2(FALSE) #Turn off s2 type spatial library, as tmap doesn't like it.

Load Data

Here I’ve provided a sample shapefile that you can load into the R memory. Then we’ll create a random data variable and link it back into the shapefile for mapping later. Working with spatial data sets is mostly handled with the sf package. Here I’m only using two functions from the package, but for more tools that sf offers you can read here: https://r-spatial.github.io/sf/articles/

ShapeFile = st_read("districts2012.shp") %>%   #Read in the ShapeFile for your map
  st_transform(ShapeFile, crs = 4326)                       # Transform the ShapeFile to the projection that leaflet likes
Reading layer `districts2012' from data source 
  `/media/justin/Extension/Work Projects/Data Science/Workshops/MappingWorkshop/districts2012.shp' 
  using driver `ESRI Shapefile'
Simple feature collection with 74 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 311758.6 ymin: 5427444 xmax: 1109224 ymax: 6658731
Projected CRS: NAD83 / UTM zone 14N
RandomData = tibble(rhad = unique(ShapeFile$rhad)) %>%      #Create some random data to add to the map
  filter(!is.na(rhad)) %>% 
  mutate(values = rpois(72, 10))


MapData = ShapeFile %>%                           #Join the ShapeFile to the RandomData
  left_join(RandomData,
            by = c("rhad"="rhad"))

Using tmap

The tmap package is an excellent way to create simple static maps from your shapefile and data. There is a lot of customization that can go into these maps, s for more reading see the vignette here: https://cran.r-project.org/web/packages/tmap/vignettes/tmap-getstarted.html

tm_shape(MapData) +                                               #tm_shape starts the map
  tm_polygons("values",                                           #tm_polygons tells it to build a map using the polygons in the shapefile and fill them with our data
              palette = sequential_hcl(12, "reds 3", rev = T),
              title = "RD Counts") +
  tm_scale_bar(position = c("left","BOTTOM"))+                    #Add a scale bar
  tm_layout(title = "Random Data in MB",                          #layout options to make things pretty and annotate if necessary
            legend.position = c("right","bottom"),
            inner.margins = c(0.05,0.05,0.12,0.05),
            frame=T,
            legend.show=T,
            bg.color = "white",
            legend.bg.color = "white",
            legend.frame = T)

Using leaflet

The leaflet package is a powerful R package that makes use of the leaflet JavaScript library. Many web applications use leaflet, as it’s open source and user friendly. You can also call leaflet directly from tmap or ggplot, but I like to use the native syntax for leaflet, as it’s easier to customize elements of the map depending on the purpose. These maps are great ways to display maps in things like dashboards, interactive data applications, or other interactive reports. In R, they work in rmarkdown with html output, or in Shiny. More details here: https://rstudio.github.io/leaflet/

pal = colorNumeric(
  palette = sequential_hcl(12, "reds 3", rev=T),
  domain = MapData$values
)                                                 # Here is where we define the color palette, note that it is defined using the colorspace package's 'reds 3' color palette

# Here's where it gets put all together using leaflet (creates an interactive map that is output in the rmarkdown output)
leaflet() %>% 
  addProviderTiles(providers$CartoDB.Positron) %>% # background map
  setView(lng =  -97.8, # set the view and zoom (long and lat)
          lat = 54.6, 
          zoom = 5) %>% 
  addPolygons(data = MapData, weight=1, color="#000000", #add our data and palette we defined above
              opacity=0.4,
              fillOpacity = 0.6, smoothFactor = 0.1,
              fillColor = ~pal(MapData$values)
  ) %>%
  addLegend("bottomleft", pal = pal, values = quantile(MapData$values,na.rm=T), #add legend!
            title = "",
            opacity = 1
  )

Publishing

Depending on where the map eventually sits, there are many different ways to provide them to the end user. These may include:

  • Saving a tmap with the jpeg() function. Or other similar functions, in the same way you would save a plot image to paste into a manuscript or report.
  • Using rmarkdown to write a pdf manuscript or report. tmap’s can be called in line (similar to calling an image in latex, but using R-code rather than latex).
  • html reports / vignettes (like this one) supports both tmap or interactive html images like leaflet!
  • The flexdashboard package (https://rstudio.github.io/flexdashboard/articles/using.html), is a great way to use rmarkdown to create simple dashboards. This will support static or interactive maps.
  • The Shiny package (https://shiny.rstudio.com/). This is a powerful tool to create complex dashboards and interactive data applications. The learning curve is a bit higher here, but it is well worth the investment if looking for a job outside of academia.