Here’s a quick map of the U.S. Department of Housing and Urban
Development’s current two-bedroom Fair Market Rent estimates for the
four Rutherford County ZIP codes closest to MTSU’s campus. Below the
map, tables show estimates for all rental unit sizes at present, five
years ago, and the change since five years ago.
Current two-bedroom Fair Market Rents for MTSU-area ZIP
codes
FMR five years ago |
ZIP |
Zero_BR_5YearsAgo |
One_BR_5YearsAgo |
Two_BR_5YearsAgo |
Three_BR_5YearsAgo |
Four_BR_5YearsAgo |
37127 |
$850 |
$900 |
$1,070 |
$1,400 |
$1,720 |
37128 |
$1,030 |
$1,100 |
$1,300 |
$1,700 |
$2,080 |
37129 |
$930 |
$990 |
$1,180 |
$1,540 |
$1,890 |
37130 |
$840 |
$890 |
$1,060 |
$1,380 |
$1,700 |
37132 |
$840 |
$890 |
$1,060 |
$1,380 |
$1,700 |
FMR this year |
ZIP |
Zero_BR_ThisYear |
One_BR_ThisYear |
Two_BR_ThisYear |
Three_BR_ThisYear |
Four_BR_ThisYear |
37127 |
$1,410 |
$1,460 |
$1,620 |
$2,050 |
$2,520 |
37128 |
$1,680 |
$1,740 |
$1,930 |
$2,440 |
$3,000 |
37129 |
$1,630 |
$1,690 |
$1,870 |
$2,360 |
$2,910 |
37130 |
$1,300 |
$1,350 |
$1,490 |
$1,880 |
$2,320 |
37132 |
$1,300 |
$1,350 |
$1,490 |
$1,880 |
$2,320 |
Change |
ZIP |
Zero_BR_Change |
One_BR_Change |
Two_BR_Change |
Three_BR_Change |
Four_BR_Change |
37127 |
$560 |
$560 |
$550 |
$650 |
$800 |
37128 |
$650 |
$640 |
$630 |
$740 |
$920 |
37129 |
$700 |
$700 |
$690 |
$820 |
$1,020 |
37130 |
$460 |
$460 |
$430 |
$500 |
$620 |
37132 |
$460 |
$460 |
$430 |
$500 |
$620 |
This R script extracted, analyzed, formatted and displayed the data.
If you would like to learn how to use R for data-driven reporting,
consider enrolling in my Data
Skills for Media Professionals course at MTSU.
# Installing required packages
if (!require("dplyr")) install.packages("dplyr")
if (!require("tidyverse")) install.packages("tidyverse")
if (!require("mapview")) install.packages("mapview")
if (!require("tidycensus")) install.packages("tidycensus")
if (!require("sf")) install.packages("sf")
if (!require("openxlsx")) install.packages("openxlsx")
if (!require("scales")) install.packages("scales")
if (!require("gt")) install.packages("gt")
if (!require("gtExtras")) install.packages("gtExtras")
library(dplyr)
library(tidyverse)
library(ggplot2) #From the tidyverse package
library(readr) #From the tidyverse package
library(tidycensus)
library(sf)
library(mapview)
library(openxlsx)
library(scales)
library(gt)
library(gtExtras)
options(tigris_use_cache = TRUE)
options(scipen = 999)
# Getting the map data
ZIPList <- c("37127",
"37128",
"37129",
"37130",
"37132")
ZCTAMap <- get_acs(geography = "zcta",
variables = c(Population = "B01001_001"),
year = 2020,
survey = "acs5",
output = "wide",
geometry = TRUE)
# Filtering and formatting the map data
RCMap <- ZCTAMap[ZCTAMap$GEOID %in% ZIPList,]
RCMap <- rename(RCMap, ZIP = GEOID)
# For FMR URLs, see:
# https://www.huduser.gov/portal/datasets/fmr/smallarea/index.html#2023_data
# https://www.huduser.gov/portal/datasets/fmr/smallarea/index.html#2018_data
FMRNow = read.xlsx("https://www.huduser.gov/portal/datasets/fmr/fmr2025/fy2025_safmrs.xlsx",sheet=1)
FMRNow <- FMRNow[FMRNow$ZIP.Code %in% ZIPList,]%>%
distinct(.keep_all = TRUE)
# FMRBefore = read.xlsx("https://www.huduser.gov/portal/datasets/fmr/fmr2020/fy2020_safmrs_rev.xlsx",sheet=1)
# FMRBefore <- FMRBefore[FMRBefore$ZIP.Code %in% ZIPList,]%>%
# distinct(.keep_all = TRUE)
# This is the original code
# Had to write custom code for the 2020 FMR data
# Because HUD changed the variable names.
# Custome code is below -- Ken, May 17, 2025
FMRBefore = read.xlsx("https://www.huduser.gov/portal/datasets/fmr/fmr2020/fy2020_safmrs_rev.xlsx",sheet=1)
FMRBefore <- FMRBefore[FMRBefore$zcta %in% ZIPList,]%>%
distinct(.keep_all = TRUE) %>%
rename(ZIP.Code = zcta,
SAFMR.0BR = safmr_0br,
SAFMR.1BR = safmr_1br,
SAFMR.2BR = safmr_2br,
SAFMR.3BR = safmr_3br,
SAFMR.4BR = safmr_4br)
Merged <- merge(FMRBefore,FMRNow, by = "ZIP.Code")
keepvars <- c("ZIP.Code",
"SAFMR.0BR.x",
"SAFMR.1BR.x",
"SAFMR.2BR.x",
"SAFMR.3BR.x",
"SAFMR.4BR.x",
"SAFMR.0BR.y",
"SAFMR.1BR.y",
"SAFMR.2BR.y",
"SAFMR.3BR.y",
"SAFMR.4BR.y")
Merged <- Merged[keepvars]
colnames(Merged) <- c("ZIP",
"Studio_5YearsAgo",
"One_bedroom_5YearsAgo",
"Two_bedroom_5YearsAgo",
"Three_bedroom_5YearsAgo",
"Four_bedroom_5YearsAgo",
"Studio_ThisYear",
"One_bedroom_ThisYear",
"Two_bedroom_ThisYear",
"Three_bedroom_ThisYear",
"Four_bedroom_ThisYear")
Merged <- Merged %>%
mutate(Studio_change = Studio_ThisYear - Studio_5YearsAgo,
One_bedroom_change = One_bedroom_ThisYear - One_bedroom_5YearsAgo,
Two_bedroom_change = Two_bedroom_ThisYear - Two_bedroom_5YearsAgo,
Three_bedroom_change = Three_bedroom_ThisYear - Three_bedroom_5YearsAgo,
Four_bedroom_change = Four_bedroom_ThisYear - Four_bedroom_5YearsAgo)
Merged <- Merged %>%
mutate(Zero_BR_5YearsAgo = dollar(Studio_5YearsAgo),
One_BR_5YearsAgo = dollar(One_bedroom_5YearsAgo),
Two_BR_5YearsAgo = dollar(Two_bedroom_5YearsAgo),
Three_BR_5YearsAgo = dollar(Three_bedroom_5YearsAgo),
Four_BR_5YearsAgo = dollar(Four_bedroom_5YearsAgo),
Zero_BR_ThisYear = dollar(Studio_ThisYear),
One_BR_ThisYear = dollar(One_bedroom_ThisYear),
Two_BR_ThisYear = dollar(Two_bedroom_ThisYear),
Three_BR_ThisYear = dollar(Three_bedroom_ThisYear),
Four_BR_ThisYear = dollar(Four_bedroom_ThisYear),
Zero_BR_Change = dollar(Studio_change),
One_BR_Change = dollar(One_bedroom_change),
Two_BR_Change = dollar(Two_bedroom_change),
Three_BR_Change = dollar(Three_bedroom_change),
Four_BR_Change = dollar(Four_bedroom_change),)
RCMap_plus <- RCMap %>%
left_join(Merged, by = c("ZIP" = "ZIP"))
mapviewOptions(basemaps.color.shuffle = FALSE)
ZIPMap <- mapview(RCMap_plus, zcol = "Two_BR_ThisYear",
layer.name = "ZIP Codes",
popup = FALSE)
ZIPMap
# Making a .kml Map File
st_write(RCMap_plus,"FMRMap.kml", append = FALSE)
# Making a CSV data file
RCMap_plus_data <- st_drop_geometry(RCMap_plus, drop = TRUE)
write_csv(RCMap_plus_data,"FMRData.csv")
# Making tables
FMRBeforeTable <- Merged %>%
select(ZIP,
Zero_BR_5YearsAgo,
One_BR_5YearsAgo,
Two_BR_5YearsAgo,
Three_BR_5YearsAgo,
Four_BR_5YearsAgo)
Table1 <- FMRBeforeTable %>%
gt() %>%
tab_header(
title = "FMR five years ago") %>%
gt_theme_538()
FMRNowTable <- Merged %>%
select(ZIP,
Zero_BR_ThisYear,
One_BR_ThisYear,
Two_BR_ThisYear,
Three_BR_ThisYear,
Four_BR_ThisYear)
Table2 <- FMRNowTable %>%
gt() %>%
tab_header(
title = "FMR this year") %>%
gt_theme_538()
FMRChangeTable <- Merged %>%
select(ZIP,
Zero_BR_Change,
One_BR_Change,
Two_BR_Change,
Three_BR_Change,
Four_BR_Change)
Table3 <- FMRChangeTable %>%
gt() %>%
tab_header(
title = "Change") %>%
gt_theme_538()
Table1
Table2
Table3