This tutorial explains a method of mapping small-area deprivation for the Republic of Ireland using R.

We’ll be using two open source datasets, the first of which is the National Deprivation Index for Ireland developed by a team at Trinity College Dublin, which is based on aggregate data from the 2016 Census.

That will be linked to ‘small area’ boundary data which will allow us to make plots showing deprivation across Ireland.

Load in the necessary packages

We’re making use of a few mapping packages, some general tidyverse code and a colour palette from the viridis package.

library(tidyverse)
library(readr)
library(curl)
library(sf)
library(rmapshaper)
library(viridis)

National Deprivation Index

Separate to this tutorial I’ve downloaded the National Deprivation Index which comes in an excel file with multiple sheets. That doesn’t play well with R so I’ve extracted just the sheet we need and converted it to a .csv file which is hosted on my GitHub.

This file also includes some variables relating to 2011, which we’re going to drop. Due to some small area boundary changes between 2011 and 2016 (some combined, some split), there are some rows which have no 2016 score/ranking, so we’ll also drop those. I’m also going to rename the ‘ID_LABEL’ variable to make things more straight-forward later.

ndi <- read_csv("https://raw.githubusercontent.com/will-ball/Ireland-Deprivation-Mapping/master/Data/2016dep.csv") %>%
  select(-Population_2011, -Score_2011, -Decile_2011) %>%
  filter(!is.na(Decile_2016)) %>%
  rename(sa_code = ID_LABEL)
head(ndi)
## # A tibble: 6 x 6
##   sa_code    ED_ID  COUNTY Population_2016 Score_2016 Decile_2016
##   <chr>      <chr>  <chr>            <dbl>      <dbl>       <dbl>
## 1 A017001001 E01011 Carlow             395     -0.996           4
## 2 A017002001 E01012 Carlow             344     -1.07            3
## 3 A017002002 E01012 Carlow             405     -0.272           6
## 4 A017002003 E01012 Carlow             276     -1.26            2
## 5 A017003001 E01013 Carlow             243     -1.15            3
## 6 A017003002 E01013 Carlow             319     -0.656           5

And we’re left with the 18,641 SAs, and the larger geographies of Electoral Division (ED_ID) and County. We also have the population for SAs, their scores and the ranking as a decile (10 groups).

Small-area geography shapefile

I’ve downloaded the .shp file from here. I’ve dropped some unnecessary variables and also renamed some so that joining with the ndi works.

This file helpfully also includes the names for NUTS2, NUTS3, County and Electoral District geographies which is great for creating maps of just those areas. If this wasn’t present it would be necessary to find a lookup table between geographies and join that to our file.

temp_1 <- tempfile()
temp_2 <- tempfile()
source <- "http://data-osi.opendata.arcgis.com/datasets/68b14cef8cf247b191ee2737e7e6993d_1.zip"
temp_1 <- curl_download(url = source, destfile = temp_1, quiet = FALSE)
unzip(temp_1, exdir = temp_2)
sf_Ireland <- read_sf(file.path(temp_2,"0d80d6a5-6314-4a4b-ac2f-09f3767f054b2020329-1-1rx3r8i.iy91.shp"))
sf_Ireland <- sf_Ireland %>% # ms_simplify(sf_Ireland)  %>% 
  select(-NUTS1, -NUTS1NAME, -NUTS2, -NUTS3,
         -SMALL_AREA, -CSOED, -OSIED, - COUNTY) %>% 
  rename(sa_code = GEOGID, county = COUNTYNAME, ed_name = EDNAME,
         nuts2name = NUTS2NAME, nuts3name = NUTS3NAME)
sf_Ireland
## Simple feature collection with 18641 features and 13 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -10.66297 ymin: 51.41991 xmax: -5.996287 ymax: 55.44658
## geographic CRS: WGS 84
## # A tibble: 18,641 x 14
##    OBJECTID GUID  nuts2name nuts3name county ed_name SA_PUB2011 sa_code  AREA
##       <int> <chr> <chr>     <chr>     <chr>  <chr>   <chr>      <chr>   <int>
##  1        1 4c07~ Southern  South-We~ Cork ~ Aultagh 047014001  A04701~     0
##  2        2 4c07~ Southern  South-We~ Cork ~ Ballym~ 047034002  A04703~     0
##  3        3 4c07~ Southern  South-We~ Cork ~ Boulte~ 047056001  A04705~     0
##  4        4 4c07~ Southern  South-We~ Cork ~ Teadies 047300001  A04730~     0
##  5        5 4c07~ Northern~ West      Galwa~ Letter~ 067162001  A06716~     0
##  6        6 4c07~ Northern~ West      Galwa~ Cushki~ 067078001~ A06707~     0
##  7        7 4c07~ Northern~ West      Mayo   Owenna~ 157041002~ A15704~     0
##  8        8 4c07~ Northern~ West      Galwa~ Conga   067069001  A06706~     0
##  9        9 4c07~ Northern~ West      Mayo   Abhain~ 157128002  A15712~     0
## 10       10 4c07~ Northern~ West      Mayo   Erriff  157077001~ A15707~     0
## # ... with 18,631 more rows, and 5 more variables: CHANGECODE <int>,
## #   ESRI_OID <int>, Shape__Are <dbl>, Shape__Len <dbl>, geometry <MULTIPOLYGON
## #   [°]>

Join

We’re going to combine the NDI dataset with the shapefile for small areas. Then we coerce it into a ‘sf’ format. At the same time we’ll make sure Decile_2016 is seen as an ordinal variable (an ordered factor in R)

join <- left_join(sf_Ireland, ndi, by = "sa_code") %>%
  st_as_sf(.)

join$Decile_2016 <- as.factor(join$Decile_2016)

head(join)
## Simple feature collection with 6 features and 18 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -9.905271 ymin: 51.70406 xmax: -8.830632 ymax: 53.62969
## geographic CRS: WGS 84
## # A tibble: 6 x 19
##   OBJECTID GUID  nuts2name nuts3name county ed_name SA_PUB2011 sa_code  AREA
##      <int> <chr> <chr>     <chr>     <chr>  <chr>   <chr>      <chr>   <int>
## 1        1 4c07~ Southern  South-We~ Cork ~ Aultagh 047014001  A04701~     0
## 2        2 4c07~ Southern  South-We~ Cork ~ Ballym~ 047034002  A04703~     0
## 3        3 4c07~ Southern  South-We~ Cork ~ Boulte~ 047056001  A04705~     0
## 4        4 4c07~ Southern  South-We~ Cork ~ Teadies 047300001  A04730~     0
## 5        5 4c07~ Northern~ West      Galwa~ Letter~ 067162001  A06716~     0
## 6        6 4c07~ Northern~ West      Galwa~ Cushki~ 067078001~ A06707~     0
## # ... with 10 more variables: CHANGECODE <int>, ESRI_OID <int>,
## #   Shape__Are <dbl>, Shape__Len <dbl>, geometry <MULTIPOLYGON [°]>,
## #   ED_ID <chr>, COUNTY <chr>, Population_2016 <dbl>, Score_2016 <dbl>,
## #   Decile_2016 <fct>

Plot

Now that we have the NDI deciles and the small area shapefiles together in one object, we can make a plot.

To make a plot for a specific area you should alter the ‘filter’ line which has been commented out here. You can plot by the county or ed_name variables. Don’t forget to change the titles accordingly

theme_set(theme_minimal())
plot <- join %>% 
 # filter(county == "Limerick City and County") %>% 
  ggplot() +                                      
  geom_sf(aes(fill = Decile_2016),
          color = NA) +
  scale_fill_viridis(option = "plasma",
                     discrete = T,
                     breaks = levels(join$Decile_2016),
                     drop = FALSE,
                     name = "Deprivation Decile",
                     labels = c("1 - Least Deprived", "2", "3", "4", "5", "6", "7", "8", "9",
                                  "10 - Most Deprived")) +
  scale_color_viridis() +
  labs(x = NULL, y = NULL,                                                          
       title = "Deprivation Deciles by Small Area (2016) for Ireland",
       subtitle = "Sources: Teljeur et al (2019) and \nOrdnance Survey Ireland under Creative Commons Attribution 4.0", 
       caption = "Plot by @WillBall12") +  
  theme(axis.line=element_blank(), 
        axis.ticks=element_blank(), 
        axis.text=element_blank(),
        axis.title=element_blank(),
        panel.grid = element_blank(),
        plot.caption.position = 'plot',
        plot.title.position = 'plot')

plot

Examples at other levels

Here’s some examples selected from other levels of geography.

NUTS2

NUTS3

County

Electoral District