In a recent post (which you can find here) we identified the first publish date for all spatial packages listed in the Analysis of Spatial Data Task View on the R website. The most recent of these, published in March 2014, is the
leafletR package by Christian Graul. We were surprised and impressed that, if you have a GeoJSON file, you can create a Leaflet map with a single line of R code. In this post, though, we demonstrate with an end-to-end example starting with a shapefile.
With even a basic web programming background, working with Leaflet is straightforward. The leafletR package, though, is designed to make it particularly easy for R users with limited web programming experience get their maps on the web.
Get the data
For this demonstration we decided to use extremely un-sexy data from the US Census on population by county. We initially load the required libraries, pull the data down from the Census web site and unzip. For this demonstration we will limit to New York State counties.
Here we download and unzip a shapefile from the US Census.
library(leafletR) library(rgdal) #for reading/writing geo files library(rgeos) #for simplification library(sp) # note that this file is somewhat big so it might take a couple # of minutes to download url<-"http://www2.census.gov/geo/tiger/TIGER2010DP1/County_2010Census_DP1.zip" downloaddir<-"d:/Leaflet" destname<-"tiger.zip" download.file(url, destname) unzip(destname, exdir=downloaddir, junkpaths=TRUE)
A little clipping and projecting
We’ve downloaded and unzipped the file. Now we’re ready to bring the shapefile into R for a little formatting.
filename<-list.files(downloaddir, pattern=".shp", full.names=FALSE) filename<-gsub(".shp", "", filename) # ----- Read in shapefile (NAD83 coordinate system) # ----- this is a fairly big shapefile and takes 1 minute to read dat<-readOGR(downloaddir, filename) # ----- Create a subset of New York counties subdat<-dat[substring(dat$GEOID10, 1, 2) == "36",] # ----- Transform to EPSG 4326 - WGS84 (required) subdat<-spTransform(subdat, CRS("+init=epsg:4326")) # ----- change name of field we will map names(subdat)[names(subdat) == "DP0010001"]<-"Population"
Simplify your shapefile if necessary
Many shapefiles we work with have significant detail that results in very large GeoJSON files. Without simplifying this county file ends up as a 3mb GeoJSON file so we will use the
rgeos library to simplify. Note that in a setting where preserving topology really matters I would be more likely to use the tools in QGIS or ArcGIS but for this demonstration we will restrict ourselves to R.
Note that another option would be to convert the large GeoJSON to TopoJSON using Mike Bostock’s node.js module. It is easy to use and dramatically reduces the size of GeoJSON files. Working with a TopoJSON file in Leaflet, though, is not as straightforward. For a discussion you can see this issue and this example. You can also see an example of TopoJSON in action, linked with charts using D3, at our site here .
# ----- save the data slot subdat_data<-subdat@data[,c("GEOID10", "Population")] # ----- simplification yields a SpatialPolygons class subdat<-gSimplify(subdat,tol=0.01, topologyPreserve=TRUE) # ----- to write to geojson we need a SpatialPolygonsDataFrame subdat<-SpatialPolygonsDataFrame(subdat, data=subdat_data)
Ready to play with LeafletR
With the shapefile in R we are ready to create the GeoJSON file. We will create the cuts we want to map and then create the Leaflet map.
# ----- Write data to GeoJSON leafdat<-paste(downloaddir, "/", filename, ".geojson", sep="") writeOGR(subdat, leafdat, layer="", driver="GeoJSON") # ----- Create the cuts cuts<-round(quantile(subdat$Population, probs = seq(0, 1, 0.20), na.rm = FALSE), 0) cuts<-0 # ----- for this example make first cut zero # ----- Fields to include in the popup popup<-c("GEOID10", "Population") # ----- Gradulated style based on an attribute sty<-styleGrad(prop="Population", breaks=cuts, right=FALSE, style.par="col", style.val=rev(heat.colors(6)), leg="Population (2010)", lwd=1) # ----- Create the map and load into browser map<-leaflet(data=leafdat, dest=downloaddir, style=sty, title="index", base.map="osm", incl.data=TRUE, popup=popup) # ----- to look at the map you can use this code browseURL(map)
Here the final map
You now have an HTML file called index.html that you can upload. We uploaded this particular file to GitHub as a Gist and you can view it here.
Although this is a post on leafletR you can see that most of the code above is devoted to getting and formatting the data while creating the Leaflet map itself is just a single line of code (or two if you count the styling). The leafletR package is a handy way for R users to create online maps quickly.
It took me a while to figure out how to read back in the geojson data using readOGR, i.e. complete the round trip from writeOGR(subdat, leafdat, layer=””, driver=”GeoJSON”)
So, in case it helps anyone else this is the syntax:
readOGR(dsn = leafdat, layer = “OGRGeoJSON”)
Although you may need to specify the full path, which in this example would be this command:
readOGR(dsn = file.path(downloaddir, leafdat), layer = “OGRGeoJSON”)
The tricky part was that the layer needs to be OGRGeoJSON. Who would have guessed?
Hi Gene, thanks. This is so tricky that I wrote a blog post on this a week ago! Apparently there is work on an rgdal2 package but it is not ready yet.
thanks for this post.
I’ve been messing around with leaflet package in R and now that I’ve got my nice map I would like to embed it (with all its interactivities: labels when mouse hover over, popups when you click a marker, etc.) in a post in my wordpress website. I am new to WP too and I can’t find a way to upload this HTML. I know I am going a bit off topic maybe, but if you have a tip that would be more than welcomed. Thanks!