Why should I take this course?

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.


Latest Fair Market Rents in Rutherford County

Click a ZIP code to see typical rents for a studio apartment up through a four-bedroom home. Updated annually, fair market rent is the estimated monthly cost at or below which 40 percent of the vacant, standard-quality rental units of a given size in a given area could be rented, utilities included. Data source: the U.S. Department of Housing and Urban Development.

Cool … but, is that hard to do?

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.

I’ve never used code, and I hate math

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.

What will class be like?

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.

What about grading?

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.”

Who are you?

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.

R code

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

How about a graphic?

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

Two-Bedroom Fair Market Rent by Rutherford County ZIP Code

The latest typical rents for a two-bedroom rental home in each Rutherford County ZIP code. Updated annually, fair market rent is the estimated monthly cost at or below which 40 percent of the vacant, standard-quality rental units of a given size in a given area could be rented, utilities included. Data source: the U.S. Department of Housing and Urban Development.


Decoding R code

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
)

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: