drawing


Introduction

The American Community Survey (ACS) is an ongoing survey conducted by the U.S. Census Bureau that collects detailed information about the nation (U.S. Census Bureau, 2026). The series of maps and charts in this report show how ACS data can be accessed with R’s tidycensus package. This report focuses on Colorado’s percent of the population with graduate degrees in Part A and on the Denver metro area’s median home values in Part B.


Data Preparation

The tidycensus package is designed to reduce the data preparation needed to analyze and visualize the Census data. In effect, the package fully prepares the data for exploration in the tidyverse (Walker and Herman, n.d.). Thus, the only preparation needed is to load the tidycensus library and other libraries for this report.

Prepare the work space by loading numerous packages.

library(tidycensus)
library(mapview)
library(tigris)
library(sf)
library(tidyverse)
library(RColorBrewer) 
library(scales)
library(plotly)
library(ggiraph)
library(leaflet)

Analysis: Part A

Part A focuses on Census data that delineates the percentage of Colorado’s population that has a graduate degree. This data is accessible via the “DP02_0066P” variable, according to the lab instructions (PSU, n.d.). Analyzing this data can answer questions such as “which Colorado counties have the largest and smallest percentages of graduate degree holders?”

# Acquire data for Colorado by county
CO_degrees <- get_acs(geography = "county",
                      variables = "DP02_0066P",
                      year = 2023,
                      state = "CO")
## Getting data from the 2019-2023 5-year ACS
## Using the ACS Data Profile

Sorting the ACS data in descending order reveals which Colorado counties have the largest percentages of graduate degree holders. Boulder, Pitkin, Clear Creek, Gilpin, and Broomfield counties have the largest percentages, according to the ACS 5-Year data.

# Arrange and view county estimates in descending order
arrange(CO_degrees, desc(estimate))
## # A tibble: 64 × 5
##    GEOID NAME                         variable   estimate   moe
##    <chr> <chr>                        <chr>         <dbl> <dbl>
##  1 08013 Boulder County, Colorado     DP02_0066P     29.4   0.9
##  2 08097 Pitkin County, Colorado      DP02_0066P     26.5   4.3
##  3 08019 Clear Creek County, Colorado DP02_0066P     26.3   3.9
##  4 08047 Gilpin County, Colorado      DP02_0066P     25.9   7.7
##  5 08014 Broomfield County, Colorado  DP02_0066P     23.7   1.5
##  6 08035 Douglas County, Colorado     DP02_0066P     22     0.8
##  7 08031 Denver County, Colorado      DP02_0066P     21.9   0.6
##  8 08069 Larimer County, Colorado     DP02_0066P     20.7   0.7
##  9 08117 Summit County, Colorado      DP02_0066P     20     3.1
## 10 08091 Ouray County, Colorado       DP02_0066P     19.5   3.2
## # ℹ 54 more rows

Whereas sorting the ACS data in ascending order reveals which Colorado counties have the smallest percentages of graduate degree holders. These counties are Lincoln, Crowley, Kit Carson, Bent, and Moffat, according to the ACS 5-Year data.

# Arrange and view county estimates in ascending order
arrange(CO_degrees, estimate)
## # A tibble: 64 × 5
##    GEOID NAME                        variable   estimate   moe
##    <chr> <chr>                       <chr>         <dbl> <dbl>
##  1 08073 Lincoln County, Colorado    DP02_0066P      4.5   1.4
##  2 08025 Crowley County, Colorado    DP02_0066P      5.1   2.9
##  3 08063 Kit Carson County, Colorado DP02_0066P      5.3   1.7
##  4 08011 Bent County, Colorado       DP02_0066P      5.4   2.1
##  5 08081 Moffat County, Colorado     DP02_0066P      5.4   1.7
##  6 08071 Las Animas County, Colorado DP02_0066P      5.7   1.4
##  7 08043 Fremont County, Colorado    DP02_0066P      6.1   0.9
##  8 08087 Morgan County, Colorado     DP02_0066P      6.2   1.5
##  9 08009 Baca County, Colorado       DP02_0066P      6.5   1.9
## 10 08033 Dolores County, Colorado    DP02_0066P      6.8   4.2
## # ℹ 54 more rows

It is important to note that the information provided by the ACS are estimates that have associated margins of error. Thus, the actual counties that have the highest and lowest percentages of graduate-degree holders might be different than the counties listed above. The following plots show each county’s estimate and margin of error for its population with a graduate degree. The colors shown in the plots mimic the Colorado state flag (shown above).

A static margin-of-error plot for Colorado.

# Create the plot
CO_degrees_plot <- ggplot(CO_degrees, aes(x = estimate, y = reorder(NAME, estimate))) + 
  
  # Add error bars and symbology
  geom_errorbar(aes(xmin = estimate - moe, xmax = estimate + moe),
                width = 0.75, 
                linewidth = 0.75,
                color = "blue4") +
  
  # Change point symbology
  geom_point(shape = 21,
             fill = "gold1",
             color = "brown3",
             size = 2,
             stroke = 1) + 
  
  # Clean up the y-axis by removing redunant text
  scale_y_discrete(labels = function(x) str_remove(x, " County, Colorado")) + 
  
  # Add labels to the plot
  labs(title = "Percent of Population with a Graduate Degree by Colorado County",
       subtitle = "2019 - 2023 5-year ACS",
       caption = "Figure 1: 2019-2023 5-year ACS census data acquired with R and tidycensus. 
       Error bars represent margin of error around estimates.",
       x = "ACS Estimate with Margin of Error (%)",
       y = "") + 
  
  # Use a minimal theme 
  theme_minimal(base_size = 10)

# View the plot
CO_degrees_plot

This margin-of-error plot can be converted to an interactive chart with the plotly package.

# Convert the margin-of-error plot to an interactive chart
ggplotly(CO_degrees_plot, tooltip = "x") %>%
  
  # Overwrite title to include subtitle 
  layout(title = list(text = paste0("Percent of Population with a Graduate Degree by Colorado County",
                                    "<br>",
                                    "<sub>",
                                    "<b>2019 - 2023 5-year ACS</b>")),
         # Overwrite x-axis to include caption
         xaxis = list(title = "ACS Estimate with Margin of Error (%) 
                      <sub>Figure 2: 2019 - 2023 5-year ACS data acquired with R and 
                      tidycensus. Error bars represent margin of error around estimates."),
         
         # Increase margin to show longer x-axis
         margin =list(b=80))

The static margin-of-error plot can be converted to an interactive chart with the ggiraph package as well.

# Create an interactive margin-of-error plot
CO_plot_ggiraph <- ggplot(CO_degrees, aes(x = estimate, 
                                       y = reorder(NAME, estimate),
                                       tooltip = estimate,
                                       data_id = GEOID)) +
  
  # Add error bars and symbology
  geom_errorbar(aes(xmin = estimate - moe, xmax = estimate + moe), 
                width = 0.75, 
                linewidth = 0.75,
                color = "blue4") + 
  
  # Add interactive point and change symbology
  geom_point_interactive(shape = 21,
                         fill = "gold1",
                         color = "brown3",
                         size = 1.5,
                         stroke = 0.75) +
  
  # Clean up the y-axis by removing redunant text
  scale_y_discrete(labels = function(x) str_remove(x, " County, Colorado")) + 
  
  # Add labels to the plot
  labs(title = "Percent of Population with a Graduate Degree by Colorado County",
       subtitle = "2019 - 2023 5-year ACS",
       caption = "Figure 3: 2019 - 2023 5-year ACS data acquired with R and tidycensus. 
       Error bars represent margin of error around estimates.",
       x = "ACS Estimate with Margin of Error (%)",
       y = "") + 
  
  # Use a minimal theme 
  theme_minimal(base_size = 10)

# Plot the graph 
girafe(ggobj = CO_plot_ggiraph,
       
       # change size to improve legibility
       width_svg = 6.5, height_svg = 7) %>%
  
  # Label data point on hover
  girafe_options(opts_hover(css = "fill:cyan;"))

Analysis: Part B

Part B focuses on Census data that delineates the median home values in dollars of Colorado’s Denver metro area which comprises the counties of Adams, Arapahoe, Broomfield, Denver, Douglas, and Jefferson. This data is accessible via the “B25077_001” variable, according to the U.S. Census Bureau (2023). Mapping this data at the block group level can reveal where homes are the most and least expensive.

Interested in where the B25077_001 variable originated? Use the tidycensus load_variables() function to see.

# Load the available variables
vars <- load_variables(2023, "acs5")

# Show examples
vars
## # A tibble: 28,261 × 4
##    name        label                                    concept        geography
##    <chr>       <chr>                                    <chr>          <chr>    
##  1 B01001A_001 Estimate!!Total:                         Sex by Age (W… tract    
##  2 B01001A_002 Estimate!!Total:!!Male:                  Sex by Age (W… tract    
##  3 B01001A_003 Estimate!!Total:!!Male:!!Under 5 years   Sex by Age (W… tract    
##  4 B01001A_004 Estimate!!Total:!!Male:!!5 to 9 years    Sex by Age (W… tract    
##  5 B01001A_005 Estimate!!Total:!!Male:!!10 to 14 years  Sex by Age (W… tract    
##  6 B01001A_006 Estimate!!Total:!!Male:!!15 to 17 years  Sex by Age (W… tract    
##  7 B01001A_007 Estimate!!Total:!!Male:!!18 and 19 years Sex by Age (W… tract    
##  8 B01001A_008 Estimate!!Total:!!Male:!!20 to 24 years  Sex by Age (W… tract    
##  9 B01001A_009 Estimate!!Total:!!Male:!!25 to 29 years  Sex by Age (W… tract    
## 10 B01001A_010 Estimate!!Total:!!Male:!!30 to 34 years  Sex by Age (W… tract    
## # ℹ 28,251 more rows

Access this data for the Colorado counties listed above with the get_acs() function.

# Acquire 2023 ACS data for the counties comprising the Denver metro area
CO_med_home <- get_acs(geography = "block group",
                       variables = "B25077_001",
                       state = "CO",
                       year = 2023,
                       county = c("Denver", "Adams", "Arapahoe", "Jefferson", "Douglas", "Broomfield"),
                       geometry = TRUE) # Include for map

Quickly create an interactive map of the block groups’ median home values.

# Relocate the legend 
mapviewOptions(legend.pos = "bottomright")

# Create a map showing the estimated median home value and rename the legend
mapview(CO_med_home, 
        zcol = "estimate", 
        layer.name = "Median Home Value ($)") @map %>%
  
  # Add title and caption
  addControl("<h4>Median home values in the Denver metro area", position = "topright") %>%
  addControl("<h6>Figure 4: 2019-2023 ACS data <br>acquired with R and tidycensus.", position = "bottomright")

A static version of the map can be created with the ggplot package.

# Create a choropleth map with a continuous color palette
ggplot(CO_med_home, aes(fill = estimate)) + 
  geom_sf() + 
  
  # Add a simple gray background
  theme_gray() + 
  
  # Customize the symbology
  scale_fill_distiller(name = "Median Home \nValue (USD)", 
                       palette = "RdYlBu", 
                       
                       # make the legend scale nicer looking (auto)
                       breaks = pretty_breaks(),
                       
                       # Add commas and dollar sign to legend values
                       labels = scales::label_dollar(prefix = "$")) + 
  
  # Customize the labels
  labs(title = "Median Home Value (USD)",
       subtitle = "Denver Metro Area, Colorado",
       fill = "ACS Estimate",
       caption = "Figure 5: 2019-2023 ACS data acquired with R and tidycensus.
       The counties comprising the metro area are: Adams, Arapahoe, 
       Broomfield, Denver, Douglas, and Jefferson")

Analyzing the map reveals that homes in the Cherry Hills Village and the Greenwood Village in south-central Denver have the highest median home values in the city. Additionally, homes along the mountainous Front Range in the west have higher prices than homes in the eastern plains. The large gray block groups in the central-north east are a combination of airports and a wildlife preserve.


Sources

PSU. (No date). GEOG588 Lab #5 Assignment. Retrieved April 1, 2026 from https://psu.instructure.com/courses/2451238/pages/lab-number-5-assignment?module_item_id=47591676.

U.S. Census Bureau. (2026). American Community Survey. U.S. Department of Commerce. Retrieved April 1, 2026 from https://www.census.gov/programs-surveys/acs.html.

U.S. Census Bureau. (2023). American Community Survey, ACS 5-Year Estimates. [Data]. U.S. Department of Commerce. Retrieved March 31, 2026 through tidycensus package.

Walker K. and Herman M. (No date). tidycensus. Retrieved April 1, 2026 from https://walker-data.com/tidycensus/.

Wikipedia. (2026). Flag of Colorado. [Image]. Retrieved April 1, 2026 from https://en.wikipedia.org/wiki/Flag_of_Colorado.