Imagine you had the skills to make a map like the one below, using the latest ZIP-code-level rent data available for Rutherford County from the U.S. Department of Housing and Urban Development.
If acquiring such skills sounds interesting and useful to you, then you should take this course.
Honestly, it’s not exactly easy. I made the map using the R code shown below. It probably will look like gobbledygook to you. But by the end of the class, I guarantee it will make sense to you.
R is a free, open-source coding language designed for analyzing data, making graphics, creating maps, and more. People all over the world use it, and you’ll find whole websites and YouTube channels dedicated to explaining how it works. Once you learn how to get started with R and its (also free) programming environment, RStudio, there’s simply no limit to what you can figure out how to do with it.
Media students generally aren’t into either coding or math. It’s OK, though. The class is designed for beginners. No prior coding experience is needed.
As for math, if you understand addition, subtraction, multiplication and division, you’re all set. This is not a class about math, or even about doing math. It is a class about getting your computer to use math to tell you things you want to find out - like where to find bargains on rent.
Each Monday, I’ll introduce you to some new coding tactics and show you some of the things you can use them for. Each Wednesday, I’ll introduce and explain the week’s coding assignment and give you some time in class to get started on it. Each Friday will be a laid-back lab session during which you and the two or so classmates in your collaboration group can continue working on the assignment and get answers from me to any questions you have.
You’ll never have to write an R script from scratch, and certainly not from memory. Instead, I’ll give you a mostly written script and ask you to customize it get get it to do something.
Each week’s coding assignment will be due by 11:59 p.m. Friday. I’ll expect you and the others in your collaboration group to help one another as needed. Ultimately, though, you, and only you, will be responsible for completing and submitting your assignment. There will be no “group projects” in the course.
There will be a midterm exam and a final exam. Both will be open-book, open-note, open-web, talk to me, phone-a-friend, etc., and you’ll have a full week of class periods to work on each one. These exams, plus the weekly coding exercises and credit for attendance, will determine your semester grade.
If you’ve taken a course from me before, you know that I use a grading scale that is unusual but, in my view, more sensible and fair. Basically, it goes like this:
A: 81 - 100 percent
B: 61 - 80 percent
C: 41 - 60 percent
D: 21 - 40 percent
F: 0 - 20 percent
There’s a long explanation in my syllabi about why I use this scale instead of the usual one. In sum, it makes more mathematical sense, aligns better with the scale your GPA uses, and gives you equal amounts of credit for equal amounts of accomplishment. In scientific terms, it’s called a “ratio scale,” one of four types of empirical measurement scales. In my view, it’s better suited for grading purposes than the usual approach, which is a misapplied “ordinal scale.”
A former newspaper reporter, I came to MTSU in 1996 after earning my Ph.D. at the University of North Carolina, Chapel Hill. I’ve been teaching this stuff ever since, and I know what I’m doing. You can learn more about me at drkblake.com. Also: Ask around about me. Look up my ratings online. Come talk to me, if you like.
Below is the R code that made the map shown above. Like I said, it probably looks like a meaningless mess. In truth, though, it’s flawlessly logical and consistent. If it weren’t, it wouldn’t work. See decoding R code, below, for a first step toward being able follow what an R script is doing.
# Installing required packages
if (!require("tidyverse"))
install.packages("tidyverse")
if (!require("mapview"))
install.packages("mapview")
if (!require("leaflet"))
install.packages("leaflet")
if (!require("leaflet.extras2"))
install.packages("leaflet.extras2")
if (!require("tidycensus"))
install.packages("tidycensus")
if (!require("sf"))
install.packages("sf")
if (!require("openxlsx"))
install.packages("openxlsx")
if (!require("scales"))
install.packages("scales")
library(tidyverse)
library(ggplot2) #From the tidyverse package
library(readr) #From the tidyverse package
library(leaflet)
library(tidycensus)
library(sf)
library(mapview)
library(openxlsx)
library(leaflet.extras2)
library(leafpop)
library(scales)
options(tigris_use_cache = TRUE)
options(scipen = 999)
ZIPList <- c(
"37127",
"37128",
"37129",
"37130",
"37132",
"37085",
"37118",
"37149",
"37037",
"37153",
"37167",
"37086"
)
FMR <- read.xlsx(
"https://www.huduser.gov/portal/datasets/fmr/fmr2025/fy2025_safmrs.xlsx",
sheet = 1
)
FMR <- FMR[FMR$ZIP.Code %in% ZIPList, ]
keepvars <- c("ZIP.Code",
"SAFMR.0BR",
"SAFMR.1BR",
"SAFMR.2BR",
"SAFMR.3BR",
"SAFMR.4BR")
FMR <- FMR[keepvars]
colnames(FMR) <- c("ZIP", "Studio", "BR1", "BR2", "BR3", "BR4")
FMR$Zero_BR <- FMR$Studio
FMR$One_BR <- FMR$BR1
FMR$Two_BR <- FMR$BR2
FMR$Three_BR <- FMR$BR3
FMR$Four_BR <- FMR$BR4
FMR$Studio <- dollar(FMR$Studio)
FMR$BR1 <- dollar(FMR$BR1)
FMR$BR2 <- dollar(FMR$BR2)
FMR$BR3 <- dollar(FMR$BR3)
FMR$BR4 <- dollar(FMR$BR4)
ZCTAMap <- get_acs(
geography = "zcta",
variables = c(Population = "B01001_001"),
year = 2021,
survey = "acs5",
output = "wide",
geometry = TRUE
)
# Filtering and formatting the map data
RCMap <- ZCTAMap[ZCTAMap$GEOID %in% ZIPList, ]
RCMap <- rename(RCMap, ZIP = GEOID)
RCMap_plus <- RCMap %>%
left_join(FMR, by = c("ZIP" = "ZIP"))
mapviewOptions(basemaps.color.shuffle = FALSE)
ZIPMap <- mapview(
RCMap_plus,
zcol = "Two_BR",
col.regions = RColorBrewer::brewer.pal(9, "Blues"),
alpha.regions = .5,
layer.name = "2 BR Fair Market Rent",
popup = popupTable(
RCMap_plus,
feature.id = FALSE,
row.numbers = FALSE,
zcol = c("ZIP", "Studio", "BR1", "BR2", "BR3", "BR4")
)
)
ZIPMap
R can do all sorts of data visualizations, too. For example, how about a nice horizontal bar chart comparing each ZIP code’s two-bedroom rent?
# Prep the data
ChartData <- RCMap_plus %>%
st_drop_geometry() %>%
select(ZIP, Two_BR, BR2) %>%
distinct()
# Make the chart
chart <- ggplot(ChartData, aes(x = reorder(ZIP, Two_BR), y = BR2)) +
geom_bar(stat = "identity", fill = "steelblue") +
coord_flip() +
geom_text(
aes(label = BR2),
hjust = 1.05,
color = "white",
position = position_dodge(0.9),
size = 3.5
) +
labs(x = "ZIP code", y = "2 BR Rent")
# Show the chart
chart
The most helpful pattern to understand is the one R typically uses to get things done. Consider this snippet of R code, from early in the first script:
FMR <- read.xlsx(
"https://www.huduser.gov/portal/datasets/fmr/fmr2025/fy2025_safmrs.xlsx",
sheet = 1
)
The read.xlsx
part is a “function,” which is like a
little miniprogram that R knows how to run all by itself, kind of like
how your body knows how to raise your arm when you want your arm raised.
This particular function tells R to read an Excel spreadsheet file from
a location on the web. Specifically, it’s the Excel file from HUD
containing the latest fair market rent data.
The stuff between parentheses after the readlxlsx
function are “arguments” that give R some specifics about how to read
the file, sort of like how you have to tell your body some specifics
about raising your arm - “raise my right arm” (rather than my left one),
and “raise it above my head” (rather than only half way). In this case,
the arguments tell R the URL of the spreadsheet file to read (so that R
won’t read some other file instead) and the tab within the spreadsheet
to read (in case there are two or more tabs; spreadsheet files can have
lots of tabs, each holding different information). The wording and
punctuation of functions and their arguments doesn’t always make sense
right off the bat. But each R function that exists has thorough
documentation and numerous examples.
Finally, the FMR
part is an “object.” It could have
been called just about anything; I picked “FMR” because it’s an
abbreviation for “Fair Market Rent.” The <-
part is the
“assignment operator.” It’s telling R to create the FMR
object and apply the read.xlsx
function to
FMR
. Translated from left to right into something like
plain English, the code is saying, “Make an empty data table called FMR,
then fill it with the results of the read.xlsx
function.”
See? You’ve learned something already. It’s data science, not rocket science. Here’s a little longer, but still short and fun, introduction to R - and an example of the kind of R help you’ll find all over the web: