## [[1]]
## NULL
##
## [[2]]
## NULL
##
## [[3]]
## NULL
##
## [[4]]
## NULL
##
## [[5]]
## NULL
##
## [[6]]
## NULL
##
## [[7]]
## NULL
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## Loading required package: gt
##
## Linking to GEOS 3.13.0, GDAL 3.10.1, PROJ 9.5.1; sf_use_s2() is TRUE
## [[1]]
## [1] "lubridate" "forcats" "stringr" "dplyr" "purrr" "readr"
## [7] "tidyr" "tibble" "ggplot2" "tidyverse" "stats" "graphics"
## [13] "grDevices" "utils" "datasets" "methods" "base"
##
## [[2]]
## [1] "gtExtras" "gt" "lubridate" "forcats" "stringr" "dplyr"
## [7] "purrr" "readr" "tidyr" "tibble" "ggplot2" "tidyverse"
## [13] "stats" "graphics" "grDevices" "utils" "datasets" "methods"
## [19] "base"
##
## [[3]]
## [1] "leafpop" "gtExtras" "gt" "lubridate" "forcats" "stringr"
## [7] "dplyr" "purrr" "readr" "tidyr" "tibble" "ggplot2"
## [13] "tidyverse" "stats" "graphics" "grDevices" "utils" "datasets"
## [19] "methods" "base"
##
## [[4]]
## [1] "sf" "leafpop" "gtExtras" "gt" "lubridate" "forcats"
## [7] "stringr" "dplyr" "purrr" "readr" "tidyr" "tibble"
## [13] "ggplot2" "tidyverse" "stats" "graphics" "grDevices" "utils"
## [19] "datasets" "methods" "base"
##
## [[5]]
## [1] "mapview" "sf" "leafpop" "gtExtras" "gt" "lubridate"
## [7] "forcats" "stringr" "dplyr" "purrr" "readr" "tidyr"
## [13] "tibble" "ggplot2" "tidyverse" "stats" "graphics" "grDevices"
## [19] "utils" "datasets" "methods" "base"
##
## [[6]]
## [1] "RColorBrewer" "mapview" "sf" "leafpop" "gtExtras"
## [6] "gt" "lubridate" "forcats" "stringr" "dplyr"
## [11] "purrr" "readr" "tidyr" "tibble" "ggplot2"
## [16] "tidyverse" "stats" "graphics" "grDevices" "utils"
## [21] "datasets" "methods" "base"
##
## [[7]]
## [1] "tidycensus" "RColorBrewer" "mapview" "sf" "leafpop"
## [6] "gtExtras" "gt" "lubridate" "forcats" "stringr"
## [11] "dplyr" "purrr" "readr" "tidyr" "tibble"
## [16] "ggplot2" "tidyverse" "stats" "graphics" "grDevices"
## [21] "utils" "datasets" "methods" "base"
## Your original .Renviron will be backed up and stored in your R HOME directory if needed.
## Your API key has been stored in your .Renviron and can be accessed by Sys.getenv("CENSUS_API_KEY").
## To use now, restart R or run `readRenviron("~/.Renviron")`
## [1] "494018a70f114d4f76b10537730ccc9c7dbfe36b"
## Getting data from the 2019-2023 5-year ACS
## Using the ACS Data Profile
## Rows: 12 Columns: 8── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): Rent_Category
## dbl (7): ZIP, Studio, BR1, BR2, BR3, BR4, ZIP_Average
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## Reading layer `cb_2020_us_zcta520_500k' from data source
## `C:\Users\brock\OneDrive\Documents\cb_2020_us_zcta520_500k.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 33791 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -176.6967 ymin: -14.37374 xmax: 145.8304 ymax: 71.34122
## Geodetic CRS: NAD83
## [1] "Column Names in FMR_RuCo_Map:"
## [1] "ZIP" "Studio" "BR1" "BR2"
## [5] "BR3" "BR4" "ZIP_Average" "Rent_Category"
## [9] "AFFGEOID20" "GEOID20" "NAME20" "LSAD20"
## [13] "ALAND20" "AWATER20" "geometry" "GEOID"
## [17] "NAME" "Rentals" "Rentals_MOE" "Households"
## [21] "Households_MOE"
# Install and load required packages
packages <- c("tidyverse", "gtExtras", "leafpop", "sf", "mapview", "RColorBrewer", "tidycensus")
install_if_missing <- function(p) {
if (!requireNamespace(p, quietly = TRUE)) install.packages(p)
}
lapply(packages, install_if_missing)
lapply(packages, library, character.only = TRUE)
# Set Census API key (use your own API key)
census_api_key("494018a70f114d4f76b10537730ccc9c7dbfe36b", install = TRUE, overwrite = TRUE)
# Fetching Census data
Census_Data <- get_acs(
geography = "zcta",
variables = c("DP04_0047E", "DP04_0047M", "DP04_0045E", "DP04_0045M"),
year = 2023,
survey = "acs5",
output = "wide"
)
# Renaming columns (including MOE values)
Census_Data <- Census_Data %>%
rename(Rentals = DP04_0047E,
Rentals_MOE = DP04_0047M,
Households = DP04_0045E,
Households_MOE = DP04_0045M) %>%
mutate(ZIP = as.character(GEOID)) # Ensure ZIP is character type for merging
# Load fair market rent data
FMR_RuCo <- read_csv("https://raw.githubusercontent.com/drkblake/Data/refs/heads/main/FMR_RuCo.csv") %>%
mutate(ZIP = as.character(ZIP))
# Download and extract ZIP code shapefile
zip_url <- "https://www2.census.gov/geo/tiger/GENZ2020/shp/cb_2020_us_zcta520_500k.zip"
zip_file <- "ZCTAs2020.zip"
download.file(zip_url, zip_file)
unzip(zip_file)
# Read shapefile using st_read()
ZCTAMap <- st_read("cb_2020_us_zcta520_500k.shp") %>%
rename(ZIP = ZCTA5CE20) %>%
mutate(ZIP = as.character(ZIP)) # Ensure ZIP is character type for merging
# Merge rent data with ZIP code map
FMR_RuCo_Map <- left_join(FMR_RuCo, ZCTAMap, by = "ZIP")
# Merge with Census data (this now includes MOE values)
FMR_RuCo_Map <- left_join(FMR_RuCo_Map, Census_Data, by = "ZIP")
# Calculate the average rent for each ZIP code (add ZIP_Average column)
FMR_RuCo_Map <- FMR_RuCo_Map %>%
mutate(ZIP_Average = rowMeans(select(FMR_RuCo_Map, Studio, BR1, BR2, BR3, BR4), na.rm = TRUE))
# Convert to spatial data frame
FMR_RuCo_Map <- st_as_sf(FMR_RuCo_Map)
# Debug: Check column names
print("Column Names in FMR_RuCo_Map:")
print(names(FMR_RuCo_Map))
# Check if required columns exist
required_cols <- c("ZIP", "Studio", "BR1", "BR2", "BR3", "BR4",
"Rentals", "Rentals_MOE", "Households", "Households_MOE", "ZIP_Average")
missing_cols <- setdiff(required_cols, names(FMR_RuCo_Map))
if (length(missing_cols) > 0) {
stop("Missing columns in FMR_RuCo_Map: ", paste(missing_cols, collapse = ", "))
}
# Mapping ZIP codes by average rent, including Census data in pop-ups
ZIP_Map <- suppressWarnings(
mapview(
FMR_RuCo_Map,
zcol = "ZIP_Average",
col.regions = brewer.pal(9, "Blues"),
layer.name = "Average Rent",
popup = popupTable(
FMR_RuCo_Map,
feature.id = FALSE,
row.numbers = FALSE,
zcol = required_cols
)
)
)
# Show the map
ZIP_Map