Skip to main content

Section C.1 The rnaturalearth Package

The package rnaturalearth is an R package created by Andy South to hold and facilitate interaction with Natural Earth map data ([267]). Natural Earth is a public domain map dataset collected and maintained by the North American Cartographic Information Society. This dataset contains both vector and raster data, which are available to download and use in your crime-mapping endeavours. The package rnaturalearth allows us to access this database from within R, and to return the results as either sp or sf objects.
To do so, we need to install and load the package, and have a little understanding of the ways we can access and subset the data. We will give some small examples here but recommend the documentation and vignettes available with the package for further detail.
So step 1 is to install the package if you have not yet done so, and then load it with the library() function:
library(rnaturalearth)
Let’s start by plotting the outline of all the countries in the world. We can retrieve all countries in the dataset with the ne_countries() function. Inside the function we specify the parameter returnclass = which allows us to choose whether we want a sf or sp object. Here let’s choose sf:
all_countries <- ne_countries(returnclass = "sf")
If we wanted now to plot this, we can use any of the many methods covered in this book from plot() to ggplot() to tmap and so on.
library(ggplot2)

ggplot() +
  geom_sf(data = all_countries) +
  theme_void()
A featureless map of the world, with countries outlined in grey and shaded light grey. Oceans and seas are white.
Figure C.1.1. Map of countries of the world
And here we see the boundaries for all the countries in the dataset. We can also have a look at the attribute data included by viewing the sf object with the View() function.
View(all_countries)
You can see most of the information contained all relate to the ways to identify the different geometries, such as geounit or name or various codes. You can use these to filter, so that we only include certain countries we are interested in, or you can use this to join additional attribute data from elsewhere.
Let’s say we wanted to select only Uganda. We could subset from the all_countries object we called above:
library(dplyr)

uganda <- all_countries %>% filter(name == "Uganda")
Or we could filter within the original call, which saves us having to download all the data in the first place:
uganda_2 <- ne_countries(country = 'Uganda', returnclass = "sf")
You should be able to see the two results are the same.
u1 <- ggplot() + geom_sf(data = uganda) + theme_void()

u2 <- ggplot() + geom_sf(data = uganda_2) + theme_void()

gridExtra::grid.arrange(u1, u2, nrow = 1)
Two identical rough grey outlines of Uganda’s border, with the interior shaded in light grey.
Figure C.1.2. Two identical maps showing border of Uganda
If we are focusing on one country, we might want to see some boundaries within said country. For this, we can use the function ne_states() when we request the file, and this will include boundaries.
uganda <- ne_states(country = "Uganda", returnclass = "sf")
Now, if we have a look, we can see the different districts within Uganda have been also downloaded.
ggplot() + geom_sf(data = uganda) + theme_void()
Uganda broken up into districts by grey borders. Each district is the same light grey shade.
Figure C.1.3. Map of districts of Uganda
It is possible that sometimes this is not the ideal sub-geometry for your analysis, in which case you’ll have to go to other resources; but in some cases it might match up with your needs, in which case this will have been a very convenient way to be sourcing some geography data!
You can also change the scale of resolution at which you want to download your boundaries.
# small
uganda_1 <- ne_countries(country = "Uganda", returnclass = "sf", scale = 110)

# medium
uganda_2 <- ne_countries(country = "Uganda", returnclass = "sf", scale = 50)

# large
uganda_3 <- ne_countries(country = "Uganda", returnclass = "sf", scale = 10)

# plot them to compare
u1 <- ggplot() + geom_sf(data = uganda_1) + theme_void()
u2 <- ggplot() + geom_sf(data = uganda_2) + theme_void()
u3 <- ggplot() + geom_sf(data = uganda_3) + theme_void()

gridExtra::grid.arrange(u1, u2, u3, nrow = 1)
Three side by side grey maps of Uganda. The borders of the first map looks very polygonal, while the detail increases in each successive map.
Figure C.1.4. Three maps of Uganda with different scale of resolution for the boundary
You can see as we move to lower numbers we get better resolution, which results in more detail around the border of the country (but also in larger file sizes!). It will be a decision for you to make about what is relevant and appropriate for the specific map you are making.
A final note on rnaturalearth before we move on. With the ne_states() function, we specified which country we wanted with the country argument. This was OK for Uganda, but what if we wanted to plot something in France instead?
france <- ne_states(country = "France", returnclass = "sf")

ggplot() + geom_sf(data = france) + theme_void()
A map which is mostly white space, with France, broken into regions, appearing squished and very small near the top. Small, hard to see islands are scattered at the bottom right and left side of the map. French Guinea can be made out on the left side as well.
Figure C.1.5. Map of France which shows also overseas territories of France
You see France appears, but so do the overseas territories of France, such as French Guiana, Guadeloupe, French Polynesia, and so on. It is possible you want to focus only on France. In this case, you can specify, instead of country, the parameter geounit. Like so:
france <- ne_states(geounit = "France", returnclass = "sf")

ggplot() + geom_sf(data = france) + theme_void()
A grey outline of France and its districts, shaded in light grey.
Figure C.1.6. Map of France that shows only France without overseas territories
Now we see only France. But what if you do want to include it all? Well, in that case, one approach you might try is to add these territories in a way they appear closer to France, by inserting them by way of the inset map. We demonstrate how to add an inset map in Chapter 5.