cori.data.hu

Access and analyze U.S. Census Bureau Housing Unit Estimates at the national, state, and county level from 2000 to present. Measures total housing stock — occupied and vacant — as part of CORI's housing supply data ecosystem.

Drew Rosebush 2026-08-31

Overview

The cori.data.hu package provides access to U.S. Census Bureau Housing Unit Estimates at the county, state, and national level from 2000 to the present. It measures the total housing stock — occupied and vacant units combined — built from the decennial Census baseline plus annual additions from permitted construction, non-permitted construction, mobile home shipments, and estimated housing loss.

Housing units data differs from building permits data in an important way: permits measure new supply being added in a given year, while housing units measure the total stock available. Combined, the two datasets support analysis of how supply is changing relative to the existing base. All data are returned in the standard cori.data long format: one row per geoid / year / variable.

Installation & quick start

remotes::install_github("ruralinnovation/cori.data.hu")
library(cori.data.hu)

# All available variables
get_hu_codebook()

# Total housing units — all counties, all years
get_housing_units(geography = "county")

# Housing units per 1,000 population for New Hampshire counties
get_housing_units(
  variables = "housing_units_per_1k_people",
  geoids    = c("33009", "33011"),
  years     = 2010:2024
)

What this data tells us about rural America

Housing is the physical substrate of rural economic development — the asset that determines whether a community can translate economic momentum into population and workforce growth. A community may have strong broadband, an active entrepreneurial ecosystem, employment anchors, and quality of life assets that attract interest from remote workers and returnees — and still be unable to grow if there is nowhere for people to live. In this sense, housing stock is not background infrastructure; it is the capacity of a place to receive and retain people.

Introduction

Adapted from the Introduction vignette on GitHub.

cori.data.hu provides annual housing unit estimates from the U.S. Census Bureau’s National, State, and County Housing Unit Totals, Data cover 2000–present and measure the total housing stock built from the decennial Census baseline plus annual construction and loss estimates.

Source: U.S. Census Bureau, Population Estimates Program Coverage: 2000–present, updated annually (release typically May) Geography: County (5-digit FIPS), state (2-digit FIPS), national ("00")

Variables

get_hu_codebook() |>
  dplyr::select(variable, label, unit, notes) |>
  knitr::kable()

Reading data

All data are returned in long format: one row per geoid / year / variable.

df <- get_housing_units(geography = "county")
dplyr::glimpse(df)

Filter to specific variables, years, or counties:

nh_hu <- get_housing_units(
  variables = "housing_units_per_1k_people",
  geoids    = grep("^33", unique(df$geoid), value = TRUE),
  years     = 2010:2024
)
dplyr::glimpse(nh_hu)

Rural vs. nonrural

library(cori.charts)
library(ggplot2)
library(ruraldefinitions)
library(dplyr)

load_fonts()

rural_avg <- df |>
  filter(variable == "housing_units_per_1k_people") |>
  left_join(select(cbsa_2023, geoid, is_rural), by = "geoid") |>
  filter(!is.na(is_rural), !is.na(value), !is.na(agg_var)) |>
  group_by(year, is_rural) |>
  summarise(
    value = sum(value * agg_var, na.rm = TRUE) / sum(agg_var, na.rm = TRUE),
    .groups = "drop"
  )

ggplot(rural_avg, aes(x = year, y = value, color = is_rural)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2.5) +
  scale_color_manual(
    values = c("Rural" = "#2F6E9B", "Nonrural" = "#7EBDC2"),
    labels = c("Rural" = "Rural counties", "Nonrural" = "Nonrural counties")
  ) +
  scale_x_continuous(breaks = seq(2000, 2024, by = 5)) +
  scale_y_continuous(labels = scales::label_number(accuracy = 0.1)) +
  theme_cori() +
  theme(legend.position = "bottom") +
  labs(
    title    = "Rural counties carry more housing units per capita than nonrural",
    subtitle = "Population-weighted average housing units per 1,000 population, 2000\u20132024",
    x        = NULL, y = NULL, color = NULL,
    caption  = "Source: CORI analysis of U.S. Census Bureau Housing Unit Estimates."
  )

County spotlight: Grafton County, NH

grafton <- get_housing_units(
  variables = "housing_units_per_1k_people",
  geoids    = c("33009", "33", "00")
) |>
  mutate(
    group = case_when(
      geoid == "33009" ~ "Grafton County, NH",
      geoid == "33"    ~ "New Hampshire",
      geoid == "00"    ~ "United States"
    ),
    group = factor(group, levels = c("Grafton County, NH", "New Hampshire", "United States"))
  )

ggplot(grafton, aes(x = year, y = value,
                    color = group, linetype = group, linewidth = group)) +
  geom_line(na.rm = TRUE) +
  geom_point(size = 2.5, na.rm = TRUE) +
  scale_color_manual(values = c(
    "Grafton County, NH" = "#2F6E9B",
    "New Hampshire"      = "#7EBDC2",
    "United States"      = "#9DA7B0"
  )) +
  scale_linetype_manual(values = c(
    "Grafton County, NH" = "solid",
    "New Hampshire"      = "dashed",
    "United States"      = "dotted"
  )) +
  scale_linewidth_manual(values = c(
    "Grafton County, NH" = 1.2,
    "New Hampshire"      = 0.8,
    "United States"      = 0.8
  )) +
  scale_x_continuous(breaks = seq(2000, 2024, by = 5)) +
  scale_y_continuous(labels = scales::label_number(accuracy = 0.1)) +
  theme_cori() +
  theme(legend.position = "bottom") +
  labs(
    title    = "Housing units per 1,000 residents \u2014 Grafton County, NH",
    subtitle = "Compared to New Hampshire and the United States, 2000\u20132024",
    x        = NULL, y = NULL, color = NULL, linetype = NULL, linewidth = NULL,
    caption  = paste0(
      "Source: CORI analysis of U.S. Census Bureau Housing Unit Estimates.\n",
      "Population denominator from Census Population Estimates Program via cori.data.pep."
    )
  )
  • Package: cori.data — meta-package that includes cori.data.hu
  • Package: cori.data.bps — building permits measure new supply added annually; pairs with HU for stock vs. flow analysis
  • Package: cori.data.pep — population denominators used to compute housing units per capita
NOTE

Data attribution: Housing Unit Estimates are produced by the U.S. Census Bureau. When citing analysis using this package, reference: U.S. Census Bureau, Housing Unit Estimates, www.census.gov/programs-surveys/popest.