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.
Mapping in R Workshop
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.
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/
= st_read("districts2012.shp") %>% #Read in the ShapeFile for your map
ShapeFile 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
= tibble(rhad = unique(ShapeFile$rhad)) %>% #Create some random data to add to the map
RandomData filter(!is.na(rhad)) %>%
mutate(values = rpois(72, 10))
= ShapeFile %>% #Join the ShapeFile to the RandomData
MapData 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/
= colorNumeric(
pal 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.