Recently, I needed to map census tracts in Utah for a project on water use in Salt Lake City. To make the maps I needed, I made an R package based on Ari Lamstein’s choroplethrCaCensusTract package. The package is available on Github and I describe how to use it here. Install the package by typing:

library(devtools)
install_github("juliasilge/choroplethrUTCensusTract")
library(choroplethrUTCensusTract)

The package makes choropleth maps based on a 2010 Cartographic Boundary Shapefile of Utah, taken from the U.S. Census Bureau. To make maps, your data frame must have one column called “region” that exactly matches how regions are named in the package map. Let’s take a look.

data(ut.tract.regions)
head(ut.tract.regions)
##        region TRACTCE county.fips.numeric county.fips.character
## 1 49001100100  100100               49001                 49001
## 2 49003960200  960200               49003                 49003
## 3 49003960702  960702               49003                 49003
## 4 49005000401  000401               49005                 49005
## 5 49011125301  125301               49011                 49011
## 6 49011125702  125702               49011                 49011

The “region” column is an identifier which is the county FIPS code combined with the census tract ID number. Note that some Utah counties have such low populations that there is only one census tract within some counties.

To create a choropleth map with this package, the other column the data frame must have is a “value” column, the quantity you wish to map into the regions. The package includes some example data from the American Community Survey. Let’s look at df_pop_ut_tract, which contains 2013 population estimates for census tracts in Utah.

data(df_pop_ut_tract)
ut_tract_choropleth(df_pop_ut_tract, 
                    title = "2013 Population in Utah Census Tracts",
                    legend = "Population")

Perhaps you would like to zoom in on just a few counties, perhaps Iron, Washington, Kane, and Garfield Counties, the four counties in the southwest corner of Utah. To do this, just call county_zoom with a vector of the FIPS codes for the counties you are interested in.

ut_tract_choropleth(df_pop_ut_tract, 
                    title = "2013 Population in Southwestern Utah Census Tracts",
                    num_colors = 1,
                    county_zoom = c(49021, 49053, 49025, 49017),
                    legend = "Population")

You can take a similar approach with a vector of census tract IDs for a tract zoom. The high population tract there in Washington County is the location of St. George, Utah’s most populous city outside of the Wasatch Front. Notice that I used num_colors = 1; this uses a continuous scale for the map colors instead of a discrete scale.

The choroplethrUTCensusTract package also contains American Community Survey demographics for the census tracts in Utah in the df_ut_tract_demographics data set. To map one of the values in the data set, you must set the value column to the quantity you are interested in. Let’s zoom in on just Salt Lake County.

data(df_ut_tract_demographics)
df_ut_tract_demographics$value <- df_ut_tract_demographics$percent_hispanic
ut_tract_choropleth(df_ut_tract_demographics, 
                    title = "Hispanic Population in Salt Lake County, Utah",
                    county_zoom = 49035,
                    num_colors = 1,
                    legend = "Percent")
## Warning in self$bind(): The following regions were missing and are being
## set to NA: 49035980000

Notice that we got a warning when there wasn’t any data in that census tract on the west side of town; that is where the airport is.

The df_ut_tract_demographics data frame includes several other demographic measures, such as per capita income. Set the value column to the specific quantity to be mapped.

df_ut_tract_demographics$value <- df_ut_tract_demographics$per_capita_income
ut_tract_choropleth(df_ut_tract_demographics, 
                    title = "Per Capita Income in Salt Lake County, Utah",
                    county_zoom = 49035,
                    num_colors = 1,
                    legend = "Dollars")
## Warning in self$bind(): The following regions were missing and are being
## set to NA: 49035980000

Notice that we got another warning for missing data at the airport where no one lives.

Advanced Options

There are more advanced options available for customizing these maps if you to create a UtTractChoropleth object. The rendered maps are ggplot2 plots so you can use many available scales and functions to change the colors, sizes of the text, and so forth. One customization I often use is a call to geom_polygon as shown below to remove the gray borders around the plotting regions.

library(ggplot2)
library(RColorBrewer)
choro = UtTractChoropleth$new(df_pop_ut_tract)
choro$title = "2013 Population in Utah Census Tracts"
choro$set_num_colors(1)
choro$ggplot_polygon = geom_polygon(aes(fill = value), color = NA)
choro$ggplot_scale = scale_fill_gradientn(name = "Population", 
                                          colours = brewer.pal(8, "RdPu"))
choro$render() + theme(plot.title = element_text(size = 18))