Below is the now-familiar table of small-area fair market rent estimates for Rutherford County ZIP codes, followed by two maps of the data.
The first map, ZIP codes by rent category, emphasizes which ZIP codes have above-average rents and which ZIP codes have below-average rents. You learned how to make this map during a previous class. The second map, ZIP codes by average rent, has been customized to use increasingly darker shades of green to highlight ZIP codes with increasingly expensive average rents.
Today’s class is about learning how to customize R-based data maps in this and other ways.
Rutherford FMR, by size and ZIP | |||||||
ZIP | Studio | BR1 | BR2 | BR3 | BR4 | ZIP_Average | Rent_Category |
---|---|---|---|---|---|---|---|
37037 | 1660 | 1710 | 1920 | 2410 | 2940 | 2128 | Above average |
37086 | 1580 | 1620 | 1820 | 2290 | 2790 | 2020 | Above average |
37128 | 1510 | 1550 | 1740 | 2190 | 2670 | 1932 | Above average |
37129 | 1420 | 1460 | 1640 | 2060 | 2510 | 1818 | Above average |
37153 | 1410 | 1450 | 1630 | 2040 | 2490 | 1804 | Above average |
37167 | 1290 | 1330 | 1490 | 1870 | 2280 | 1652 | Below average |
37085 | 1260 | 1290 | 1450 | 1820 | 2210 | 1606 | Below average |
37127 | 1240 | 1270 | 1430 | 1800 | 2190 | 1586 | Below average |
37130 | 1180 | 1210 | 1360 | 1710 | 2080 | 1508 | Below average |
37132 | 1180 | 1210 | 1360 | 1710 | 2080 | 1508 | Below average |
37118 | 1100 | 1130 | 1270 | 1590 | 1960 | 1410 | Below average |
37149 | 1100 | 1130 | 1270 | 1590 | 1960 | 1410 | Below average |
Copy and run this code to remake the first map - the one that simply distinguishes between ZIP codes with “Above average” and “Below average” overall rent estimates.
# Getting and loading required packages
if (!require("tidyverse"))
install.packages("tidyverse")
if (!require("gtExtras"))
install.packages("gtExtras")
if (!require("leafpop"))
install.packages("leafpop")
if (!require("sf"))
install.packages("sf")
if (!require("mapview"))
install.packages("mapview")
if (!require("RColorBrewer"))
install.packages("RColorBrewer")
library(tidyverse)
library(gtExtras)
library(sf)
library(mapview)
library(leafpop)
library(RColorBrewer)
# Reloading the rent data
FMR_RuCo <- read_csv("https://raw.githubusercontent.com/drkblake/Data/refs/heads/main/FMR_RuCo.csv")
# Showing the rent data
FMR_RuCo_table <- gt(FMR_RuCo) %>%
tab_header("Rutherford FMR, by size and ZIP") %>%
cols_align(align = "left") %>%
gt_theme_538
FMR_RuCo_table
# Downloading the ZIP code map file
download.file(
"https://www2.census.gov/geo/tiger/GENZ2020/shp/cb_2020_us_zcta520_500k.zip",
"ZCTAs2020.zip"
)
# Unzipping the ZIP code map file
unzip("ZCTAs2020.zip")
# Loading the ZIP code file into R as "ZCTAMap"
ZCTAMap <- read_sf("cb_2020_us_zcta520_500k.shp")
# Making ZIP a character variable
FMR_RuCo$ZIP <- as.character(FMR_RuCo$ZIP)
# Joining the files
FMR_RuCo_Map <- left_join(FMR_RuCo, ZCTAMap, by = c("ZIP" = "ZCTA5CE20"))
# Dropping unneeded columns
FMR_RuCo_Map <- FMR_RuCo_Map %>%
select(-c(AFFGEOID20, GEOID20, NAME20, LSAD20, ALAND20, AWATER20))
# Converting FMR_RuCo_Map
FMR_RuCo_Map <- st_as_sf(FMR_RuCo_Map)
# Making the map
Rent_Category_Map <- mapview(
FMR_RuCo_Map,
zcol = "Rent_Category",
layer.name = "Rent category",
popup = popupTable(
FMR_RuCo_Map,
feature.id = FALSE,
row.numbers = FALSE,
zcol = c("ZIP", "Studio", "BR1", "BR2", "BR3", "BR4")
)
)
# Showing the map
Rent_Category_Map
Switching a mapview map’s “key” is as simple as changing the data
frame variable that the mapview()
function’s
zcol
argument points to. For example, to switch from the
“ZIP codes by rent category” map to one with a key that shows each ZIP
code, simply change:
zcol = "Rent_Category"
to zcol = "ZIP"
And to change the key’s heading to reflect what the key shows, change:
layer.name = "Rent category"
to
layer.name = "ZIP code"
You can leave all of the other mapview()
arguments
unchanged. Note, too, that whatever variable you point the
zcol
argument toward is the one that “pops up” as you hover
over the map’s regions. Here’s the code and the resulting map:
# Mapping by ZIP code
ZIP_Map <- mapview(
FMR_RuCo_Map,
zcol = "ZIP",
layer.name = "ZIP code",
popup = popupTable(
FMR_RuCo_Map,
feature.id = FALSE,
row.numbers = FALSE,
zcol = c("ZIP", "Studio", "BR1", "BR2", "BR3", "BR4")))
# Showing the map
ZIP_Map
I’m not sure the ZIP code emphasis is all that helpful. Let’s change
the focus to the ZIP_Average
variable by:
Changing zcol = "ZIP"
to
zcol = "ZIP_Average"
Changing layer.name = "ZIP code"
to
layer.name = "Average rent"
And while we’re at it, let’s change the map’s color scheme. The one
in the ZIP code map is the one the mapview()
function gives
you by default. To get other schemes, load the RColorBrewer
package, which we did in the first block of code:
if (!require("RColorBrewer")) install.packages("RColorBrewer")
… then specify a color scheme by placing the RColorBrewer package’s
brewer.pal()
function among the mapview()
function’s arguments. The brewer.pal()
function requires
two arguments: the number of shades in the scheme you
have chosen, and the scheme’s name. Here’ we’ll use the
BuGn scheme, which has nine shades:
col.regions = brewer.pal(9, "BuGn")
… and put it right after the mapview() function’s zcol argument. Here’s the whole thing, and the results:
# Mapping by ZIP_Average
Avg_Rent_Map <- mapview(
FMR_RuCo_Map,
zcol = "ZIP_Average",
col.regions = brewer.pal(9, "BuGn"),
layer.name = "Average rent",
popup = popupTable(
FMR_RuCo_Map,
feature.id = FALSE,
row.numbers = FALSE,
zcol = c("ZIP", "Studio", "BR1", "BR2", "BR3", "BR4")))
# Showing the map
Avg_Rent_Map
RColorBrewer offers 35 color schemes. You can see all of them by running this code:
display.brewer.all()
… which will get you something like the chart below. The name of each
color scheme is on the left. Count the shades in a given color scheme to
get the number for the first argument in the brewer.pal()
function:
One more trick up the mapview package’s sleeve: If you have generated two maps, you can arrange them in ways that make it easy to compare them.
Making a slider map
One approach, for example, is to put one on top of the other, then add a vertical “slider bar” that will uncover one map and hide the other. The result is called a “slider map.”
Here’s some code that regenerates the Rent_Category_Map, from above, but changes its color scheme to two-tone grey (because the original yellow and purple would look terrible), then combines it and the Avg_Rent_Map into a slider map:
Rent_Category_Map <- mapview(
FMR_RuCo_Map,
zcol = "Rent_Category",
col.regions = brewer.pal(2, "Greys"),
layer.name = "Rent category",
popup = popupTable(
FMR_RuCo_Map,
feature.id = FALSE,
row.numbers = FALSE,
zcol = c("ZIP", "Studio", "BR1", "BR2", "BR3", "BR4")
)
)
Rent_Category_Map | Avg_Rent_Map
Making a side-by-side map
A side-by-side map offers a second way to compare two maps. As the name implies, both maps get shown side-by-side, and the cursor is synchronised, so that hovering over and area in one map highlights the same area in the other map.
Making one requires installing and loading the leafsync package, then using the package’s sync() function with each map name as an argument. Below is the code, followed by the resulting map.
if (!require("leafsync"))
install.packages("leafsync")
library(leafsync)
sync(Rent_Category_Map, Avg_Rent_Map)
Make all four of the maps above - the Rent Category map, the ZIP Code map, the slider map, and the side-by-side map - but choose a different color scheme. The “Blues” scheme is a favorite of mine. But fiddle around a bit to find one you like.
When your maps look the way you want them to, use R Markdown to publish them, along with their code, on RPubs.com. Show me your work before the end of class, and you will be free to leave early.