Assigning specific colors to polygons in a shapefile using R

3k Views Asked by At

I am comparing results of the 2010 and 2014 mid-term elections in the state of Virginia. I am doing this by using a file that has the Virginian congressional districts over the map of Virginia. I want to color the districts that elected a Republican canidate red and color the districts that elected a Democratic canidate blue.
There is more to the project but once I figure out how to do this one thing I will be able to figure out how I will go about the rest of the project.

I am using the files found here:

http://www.arcgis.com/home/item.html?id=dc20260d27654c64bfa0c2979a317597

This is the code I am using to plot the shapefile:

library(maptools)
library(shapefiles)

CCBound <- readShapePoly("tl_rd13_51_cd113")
CCBound2 <- CCBound

system.time(plot(CCBound2))

This gives me a nice map of Virginia with the ten congressional districts outlined.

How should I go about coloring in the districts as I stated above?

2

There are 2 best solutions below

0
On BEST ANSWER

Here's a ggplot solution. You seem to be asking for a base R method, but IMO it's worthwhile to learn ggplot for the added flexibility. This should get you started.

I had to make some assumptions about the format of your data, since you didn't provide it. The code below is just shows how the data is organized in this example

# 2010 and 2014 Congressional Election results in Virginia. 
data.2010 <- data.frame(district=sprintf("%02i",1:11),
                   R=c(63.9,53.1,27.2,62.3,50.8,76.3,59.2,37.3,51.2,62.9,48.8),
                   D=c(34.8,42.4,70.0,37.5,47.0,00.0,34.1,61.0,46.4,34.8,49.2))
data.2014 <- data.frame(district=sprintf("%02i",1:11),
                   R=c(63.0,57.9,000.0,60.3,61.0,75.5,60.9,31.7,74.9,56.6,40.4),
                   D=c(34.5,42.1,100.0,37.5,35.8,00.0,36.9,63.0,00.0,40.4,56.9))
data <- cbind(year=rep(c(2010,2014),each=11),rbind(data.2010,data.2014))
data$delta <- with(data,D-R)
head(data)
#   year district    R    D delta
# 1 2010       01 63.9 34.8 -29.1
# 2 2010       02 53.1 42.4 -10.7
# 3 2010       03 27.2 70.0  42.8
# 4 2010       04 62.3 37.5 -24.8
# 5 2010       05 50.8 47.0  -3.8
# 6 2010       06 76.3  0.0 -76.3

This plots the maps.

library(ggplot2)
library(rgdal)
setwd("c:/users/jlh/desktop/map/virginia.congressional.districts")
map <- readOGR(dsn=".",layer="tl_rd13_51_cd113")
map.data <- data.frame(id=rownames(map@data),district=map@data$CD113FP)
map.data <- merge(map.data,data)
map.df   <- fortify(map)
map.df   <- merge(map.df,map.data)
ggplot(map.df,aes(x=long,y=lat,group=group))+
  geom_polygon(aes(fill=delta),color="grey20")+
  facet_wrap(~year,nr=2)+
  scale_fill_gradient2(low="red",high="blue",mid="white",limits=c(-100,100))+
  coord_map()+labs(x="",y="")+
  theme_bw()+
  theme(panel.grid=element_blank(),
        panel.border=element_blank(),
        axis.text=element_blank(),
        axis.ticks=element_blank())

enter image description here

Note that in 2014 in the 3rd District the Democrat ran unopposed, while the 6th and 9th Districts were contested, but there was no Democrat running.

The posts here, and here have a explanation of the workflow.

0
On

The CCBound object is a SpatialPolygonsDataFrame. Basically, it is a list of polygons plus a data.frame with as many rows as the polygon number which gives some information on each polygon. You can check the data.frame through:

    CCBound@data

From it, we learn that there are 11 districts. From there, you can built a vector of colors with the red or blue value according to who won the district. The values in the vector must be in the same order as the districts in CCbound@data. Once you have built this vector, you can call the plot function with the col argument. If cols is the colors vector, you can just try:

    plot(CCBound,col=cols)