Dissolve polygons in R

[This article was first published on rstats – philmikejones.me, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Dissolving polygons is another fairly elementary GIS task that I need to perform regularly. With R this is can be a bit involved, but once done is fully reproducible and the code can be re-used. This post is essentially a companion piece to Clipping polygons in R; I wrote both because I often forget how to complete these tasks in R.

Getting started

Let’s gather together everything we need to complete this example. We need a shapefile of small geographies to ‘dissolve’, a lookup table to tell us which polygons dissolve into which, and we need a couple of R spatial packages to run everything. Let’s get started.

# The default behaviour of this script is to create a folder called 'dissolve-example'
# and download and run everything from here.
# You can change this by modifying the next two lines

# Load a few packages. dplyr makes merges easier

# Set up shapefile to dissolve. I'm using English regions
              destfile = "lad-region-lookup.zip")
unzip("lad-region-lookup.zip", exdir = ".")
region <- readOGR(".", "England_gor_2011")

# Check the shapefile has loaded correctly
# We're going to dissolve all regions in to one country (England!)
# For this we'll create a lookup table and merge with the spatial data
# Hopefully for your 'real' data you have a lookup table of all polygons and
# their larger geography already!
lu <- data.frame()
lu <- rbind(lu, region@data)
lu$CODE <- as.character(lu$CODE)
lu$NAME <- as.character(lu$NAME)
lu$country <- NA
lu$country <- "England"


We now need to merge the lookup table into our spatial object data frame. We should end up with one row per zone to dissolve, each with a reference for the relevant larger geography. I think the trick is to make sure the row names match exactly, and if you can match the polygon IDs as well with spChFIDs().

# Merge lu (LookUp) into polygons,
region@data$CODE <- as.character(region@data$CODE)
region@data <- full_join(region@data, lu, by = "CODE")

# Tidy merged data
region@data <- select(region@data, -NAME.x)
colnames(region@data) <- c("code", "name", "country")

# Ensure shapefile row.names and polygon IDs are sensible
row.names(region) <- row.names(region@data)
region <- spChFIDs(region, row.names(region))


Now we can do the dissolve. I use gUnaryUnion (and indeed I think unionSpatialPolygons in the maptools package uses this by default).

# Now the dissolve
region <- gUnaryUnion(region, id = region@data$country)

If you want to just plot this using base plot you can stop there. If you want to do anything with the data or plot using ggplot you need to recreate the data frame.

# If you want to recreate an object with a data frame
# make sure row names match
row.names(region) <- as.character(1:length(region))

# Extract the data you want (the larger geography)
lu <- unique(lu$country)
lu <- as.data.frame(lu)
colnames(lu) <- "country"  # your data will probably have more than 1 row!

# And add the data back in
region <- SpatialPolygonsDataFrame(region, lu)

# Check it's all worked

Your plot should look like this:

Dissolved polygons
Example dissolved polygons

And your data frame should look like this:

##   country
## 1 England

To leave a comment for the author, please follow the link and comment on their blog: rstats – philmikejones.me.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)