How to make an interactive map using R, GeoJSON and leaflet

This interactive map was created by using data from the United Nations, shapefiles with country polygons, leaflet and R-statistics for data preparation and creation of GeoJSON file.

[xyz-ihs snippet=”UN-GR”]

Click here to see larger map.

Required data

cshp:
Shapefile which contains the borders of all countries in the world. This data is provided by www.naturalearthdata.com and can be read with R-package ‘rgdal’. To install rgdal ‘gdal-config’ has to be installed on the computer (click  here for more information).

# Load 'rgdal' library in R
library(rgdal)

# Download Shapefile
url.c='http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_0_countries.zip'
dfile='ne_10m_admin_0_countries.zip'
download.file(url.c, destfile=dfile, method='wget')

# Unzip Shapefile
unzip('ne_10m_admin_0_countries.zip', exdir='countries')
#Remove .zip file
file.remove('ne_10m_admin_0_countries.zip')

# Read Shapefile of Countries
cshp=readOGR('countries', 'ne_10m_admin_0_countries')

dat:
The original data is provided on the web page of the United Nations Statistics Division in xls-format. It contains:

  • Population, total and by sex (in thousands)
  • Sex ratio (women/100 men)

To read this file into R the package XLConnect can be used. Therefore, see How to read Excel files into R with package ‘XLConnect’.

Before doing any visualisation some data preparations have to be done:
## Romove footnote in the country names
## Name the countries of dat as the countries in shapefile cshp
## Sort the data by country names as in the shapefile cshp

The prepared data can be downloaded UN_Gender-Relations.csv. The data of the UN doesn’t contain the information of all countries which are provided in the shapefile cshp, so there are missing values, indicated as NA, in the prepared data. To read this file into R download it in you working directory by using the following commands:

# Read prepared data from ClimVis.de
download.file('http://climvis.de/wp-content/uploads/2014/07/UN_Gender-Relations.csv', destfile='UN_Gender-Relations.csv', method='wget')
dat=read.csv('UN_Gender-Relations.csv', head=T, sep=';')

 

Create GeoJSON with R

The coordinates of the multi polygons and the related informations, like country name and  the value of the sex ratio, are stored in a GeoJSON file. For more information about GeoJSON see: http://geojson.org/geojson-spec.html

Data frame with all informations

To create a GeoJSON file with R, all required informations have to be in a data frame:

# From cshp: 'WOE_ID' and 'NAME_LONG'
vdat=cshp@data[,c('WOE_ID','NAME_LONG')]
rownames(dat)=rownames(vdat)

# From dat: 'Sex.ratio'
vdat=cbind(vdat,dat[,2])

 

Text on mousover

In the next step the missing values NA are replaced by ‘ ‘. The vector txth contains the text which is shown by hovering over a state. If there is a missing value the shown text is ‘No data provided by the UN’ for all other values the text will be ‘women per 100 men’. This vector is bound to the data frame vdat and the columns are named.

# Missing values are replaced with ' '
vdat[which(is.na(vdat[,3])==T) ,3]=' '

# Shown text on hover
txth=c()
txth[which(vdat[,3]==' ')]='No data provided by the UN'
txth[which(vdat[,3]!=' ')]='women per 100 men'
vdat=cbind(vdat,txth)

# Column name of vdat
colnames(vdat)=c('WOE_ID','name','value1','value2')

 

Simplifying the shapefile

To avoid very large GeoJSON files it is necessary to do a simplifying of the shapefile. Therefore, the R-package rgeos can be used.

# Simplifying
library(rgeos)
nshp<-gSimplify(cshp,tol=0.1, topologyPreserve=TRUE)

 

Writing GeoJSON

In the next step a SpatialPolygonsDataFrame is created to write the GeoJSON file. For both, commands from the package rgdal are used.

# SpatialPolygonsDataFrame
spdf=SpatialPolygonsDataFrame(nshp, data=vdat)

# Write GeoJSON
jsfile='../leaflet/polygons.js'
if(file.exists(jsfile)){file.remove(jsfile)}
writeOGR(spdf, jsfile, layer="", driver="GeoJSON")

To declare the polygons as a variable in JavaScript the first line has to be: var statesData =
Therefore, the bash command sed is used.

# Declare var statesData
system(paste("sed -i '1ivar statesData = '", jsfile))

 

leaflet

For this interactive map four files are required:

index.html
The index.html file from this leaflet tutorial was modified.
To decide on the intervals see: How to use R package ‘classInt’ to choose univariate class intervals and Intervals in JavaScript and R.

polygons.js
A JavaScript file which contains the polygons of all countries in GeoJSON format. See description above on how to create it using R

leaflet.js
Leaflet JavaScript file. No modifications were made.

leaflet.css
Leaflet CSS file. No modifications were made.

For more information on how to use leaflet for interactive maps visit the leaflet homepage http://leafletjs.com/examples.html. There is also a very good tutorial from ZevRoss: Using R to quickly create an interactive online map using the leafletR package