This code-through uses real cost-of-living data from the Bureau of Economic Analysis (BEA) called Regional Price Parities (RPPs). RPP is an index where U.S. = 100. Values above 100 indicate higher prices (more expensive), and below 100 indicate lower prices.
We will:
Load real RPP data for U.S. states (2023) from the FRED release page.
Make three ggplot2 charts: a ranked bar chart, a histogram, and a simple scatter.
Add titles, labels, and themes.
RPP helps compare how far a dollar goes across states. Visualizing it builds plotting skills and intuition about geographic price differences.
You’ll learn how to:
Read public data from the web into R.
Use dplyr to do light wrangling.
Build ggplot2 charts: geom_col, geom_histogram, geom_point (+ a basic trend line).
Cost of Living by State (BEA RPP, 2023)
Below we load the 2023 cost-of-living data for U.S. states from FRED (sourced from BEA) and tidy it into a data frame.
fred_url <- "https://fred.stlouisfed.org/release/tables?eid=233639&rid=403"
page_txt <- rvest::read_html(fred_url) |> rvest::html_text2()
states <- c(state.name, "District of Columbia")
extract_state_rpp <- function(state_label, txt) {
pos <- str_locate(txt, fixed(state_label))[1]
if (is.na(pos)) return(NULL)
window <- str_sub(txt, pos, pos + 500)
all_items <- str_match(window, "Regional Price Parities: All Items\\s+([0-9]+\\.[0-9]+)")[,2]
goods <- str_match(window, "RPPs: Goods\\s+([0-9]+\\.[0-9]+)")[,2]
rents <- str_match(window, "RPPs: Services: Rents\\s+([0-9]+\\.[0-9]+)")[,2]
other_serv <- str_match(window, "RPPs: Services: Other\\s+([0-9]+\\.[0-9]+)")[,2]
tibble(
state = state_label,
year = 2023,
rpp_all = suppressWarnings(as.numeric(all_items)),
rpp_goods = suppressWarnings(as.numeric(goods)),
rpp_rents = suppressWarnings(as.numeric(rents)),
rpp_other = suppressWarnings(as.numeric(other_serv))
)
}
rpp_list <- lapply(states, extract_state_rpp, txt = page_txt)
rpp <- rpp_list[!vapply(rpp_list, is.null, logical(1))] |>
dplyr::bind_rows() |>
janitor::remove_empty("cols")
rpp <- dplyr::filter(rpp, !is.na(rpp_all))
rpp_plot <- dplyr::filter(rpp, state != "District of Columbia")
knitr::kable(head(rpp_plot), caption = "RPP preview (first rows)") |>
kableExtra::kable_styling(full_width = FALSE)| state | year | rpp_all | rpp_goods | rpp_rents | rpp_other |
|---|---|---|---|---|---|
| Alabama | 2023 | 89.970 | 95.064 | 61.563 | 98.687 |
| Alaska | 2023 | 101.715 | 100.372 | 96.643 | 103.313 |
| Arizona | 2023 | 101.105 | 97.472 | 108.580 | 102.263 |
| Arkansas | 2023 | 86.508 | 92.135 | 56.669 | 95.260 |
| California | 2023 | 112.581 | 107.530 | 157.839 | 104.826 |
| Colorado | 2023 | 101.382 | 98.118 | 130.532 | 96.241 |
A basic example shows how to create a horizontal bar chart of All-Items RPP (U.S.=100). This makes it easy to compare more vs less expensive states.
rpp_ranked <- rpp_plot |> arrange(desc(rpp_all)) |>
mutate(state = factor(state, levels = state))
ggplot(rpp_ranked, aes(x = state, y = rpp_all)) +
geom_col(fill = "steelblue") +
coord_flip() +
geom_hline(yintercept = 100, linetype = "dashed") +
labs(
title = "Cost of Living by State (RPP, All Items)",
subtitle = "Index (U.S. = 100), 2023 — BEA Regional Price Parities",
x = "State", y = "RPP (All Items)"
) +
theme_minimal()More specifically, this can be used for a histogram (distribution of All-Items RPP).
ggplot(rpp_plot, aes(x = rpp_all)) +
geom_histogram(binwidth = 3, color = "black", fill = "skyblue") +
geom_vline(xintercept = 100, linetype = "dashed") +
labs(
title = "Distribution of State RPP (All Items)",
subtitle = "Most states cluster near 100 (U.S. average)",
x = "RPP (All Items)", y = "Number of States"
) +
theme_light()What’s more, it can also be used for a scatter plot: Rents and Overall Prices Because housing plays a major role in cost of living, we can see how rent prices relate to overall price levels by plotting RPP: Services – Rents against RPP: All Items with a fitted trend line.
ggplot(rpp_plot, aes(x = rpp_rents, y = rpp_all)) +
geom_point(size = 2.8, alpha = 0.85, color = "darkgreen") +
geom_smooth(method = "lm", se = FALSE, color = "black") +
labs(
title = "Rents vs Overall Cost of Living",
subtitle = "State RPP: Services — Rents vs All Items (2023)",
x = "RPP: Services — Rents", y = "RPP: All Items"
) +
theme_classic()Most notably, it’s valuable for a ranked bar chart. In this section, we’ll identify which states stand out the most in terms of cost of living. We’ll find the top and bottom five states and visualize them to highlight extremes in price levels across the U.S.
top_bottom <- rpp_plot %>%
arrange(desc(rpp_all)) %>%
mutate(rank = row_number()) %>%
filter(rank <= 5 | rank > (n() - 5))
ggplot(top_bottom, aes(x = reorder(state, rpp_all), y = rpp_all, fill = rpp_all)) +
geom_col(show.legend = FALSE) +
coord_flip() +
geom_text(aes(label = round(rpp_all, 1)), hjust = -0.2, size = 3.5) +
labs(
title = "States with the Highest and Lowest Cost of Living (RPP, 2023)",
subtitle = "Top and bottom five states by Regional Price Parity (All Items)",
x = "State",
y = "RPP (All Items)"
) +
scale_fill_gradient(low = "lightgreen", high = "darkgreen") +
theme_minimal(base_size = 12)
Learn more about [package, technique, dataset] with the following:
BEA: Regional Price Parities (program page): https://www.bea.gov/data/prices-inflation/regional-price-parities-state-and-metro-area
Bureau of Economic Analysis
FRED: “Regional Price Parities by State” (2023 release table): https://fred.stlouisfed.org/release/tables?eid=233639&rid=403
ggplot2 docs: https://ggplot2.tidyverse.org/
R for Data Science: https://r4ds.had.co.nz/
This code through references and cites the following sources:
U.S. Bureau of Economic Analysis (2024). Regional Price Parities by State and Metro Area. BEA RPP Program Page (https://www.bea.gov/data/prices-inflation/regional-price-parities)
Federal Reserve Bank of St. Louis (2024). Regional Price Parities, Annual: Regional Price Parities by State (2023 Table). FRED Release Page (https://fred.stlouisfed.org/release/tables?eid=233639&rid=403)
Wickham, H. (2016). ggplot2: Elegant Graphics for Data Analysis.(https://ggplot2.tidyverse.org/)