So far we have done colors in maps (choropleths) using ggplot2. That’s usually the best route, but some shapefiles are so big, or so disamenable to fortifying, that we have to use R base graphics. This requires more work on our part, but it can be done.

First let’s get a shapefile. I’m going to load one from the USAboundaries package (install from CRAN), but we’ll get a shapefile sp object the same as if we had loaded it with rgdal.

library(dplyr)
## 
## Attaching package: 'dplyr'
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(sp)
library(USAboundaries)
shp <- us_boundaries(as.Date("1810-01-01"))

We can plot this shapefile easily.

plot(shp)

We should note something about the shapefile’s structure. Notice that is has “slots”, and that one of those slots is data. This is a data frame with information about the shapefile. There is one row in the data frame for each polygon in the polygons slot.

str(shp, max.level = 2)
## Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots
##   ..@ data       :'data.frame':  26 obs. of  17 variables:
##   ..@ polygons   :List of 26
##   ..@ plotOrder  : int [1:26] 8 19 5 12 25 4 24 18 16 11 ...
##   ..@ bbox       : num [1:2, 1:2] -133.2 28.9 -66.9 54.7
##   .. ..- attr(*, "dimnames")=List of 2
##   ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
str(shp@data)
## 'data.frame':    26 obs. of  17 variables:
##  $ id_num     : int  25 26 28 44 56 62 70 75 77 82 ...
##  $ name       : Factor w/ 100 levels "Alabama","Alabama Territory",..: 14 19 16 25 32 35 40 43 46 45 ...
##  $ id         : Factor w/ 100 levels "ak_dept","ak_district",..: 14 15 16 23 33 35 39 43 44 45 ...
##  $ version    : int  4 1 1 3 1 4 1 1 2 2 ...
##  $ start_date : Factor w/ 121 levels "1783/09/03","1784/03/01",..: 22 9 1 17 25 25 11 24 22 9 ...
##  $ end_date   : Factor w/ 115 levels "1784/02/29","1786/09/13",..: 115 54 115 115 26 26 69 25 36 115 ...
##  $ change     : Factor w/ 200 levels "Alaska was fully organized as a territory in the United States.",..: 28 139 132 25 151 151 100 21 36 139 ...
##  $ citation   : Factor w/ 178 levels "(\"Proclamation,\" Weekly Oklahoma State Capital [newspaper], 7 June 1890; U.S. Stat., vol. 26, ch. 182[1890], sec. 4/p. 83; Mo"| __truncated__,..: 23 44 15 41 119 67 21 120 23 44 ...
##  $ start_n    : int  18041231 17910330 17830903 18020424 18090301 18090301 17920601 18050704 18041231 17910330 ...
##  $ end_n      : int  20001231 18460906 20001231 20001231 18161210 18161210 18591129 18121206 18200314 20001231 ...
##  $ area_sqmi  : num  4975 100 2013 58781 150049 ...
##  $ terr_type  : Factor w/ 5 levels "District of Columbia",..: 3 1 3 3 4 4 3 4 3 3 ...
##  $ full_name  : Factor w/ 100 levels "Alabama","Alabama Territory",..: 14 18 16 25 32 35 40 43 46 45 ...
##  $ abbr_name  : Factor w/ 100 levels "AK","AK Dept",..: 14 15 16 23 33 35 39 43 44 45 ...
##  $ name_start : Factor w/ 220 levels "Alabama (1819-12-14)",..: 25 37 34 46 55 65 71 75 80 78 ...
##  $ start_posix: POSIXct, format: "1804-12-31" "1791-03-30" ...
##  $ end_posix  : POSIXct, format: "2000-12-31" "1846-09-06" ...

We’re going to use dplyr to add a new color column to that data frame. This is the step where you would figure out what color to assign to the polygons in your data frame. Usually you would do this by writing some function which will break some variable into categories, and associate those categories with a color.

shp@data  <- shp@data %>%
  mutate(color = ifelse(terr_type == "State", "red", "green"))

Now that each polygon has a color associated with it, we can make a plot with color. We can use the col = argument to plot().

plot(shp, col = shp@data$color)