The table compares population growth and population density across Nashville-area counties. Davidson County has the highest population density at approximately 1,419 residents per square mile, followed by Rutherford County at approximately 582 residents per square mile. Williamson County has a lower density of approximately 447 residents per square mile even though it experienced the highest percentage population growth among the counties studied. These results suggest that several surrounding counties are experiencing rapid population growth while remaining less densely populated than Davidson County.

Population Change and Density in Nashville-Area Counties
County CurrentPop EarlierPop Region Change Percent_change Square_Miles Density Density_Category
Davidson 715388 598184 Davidson 117204 0.196 504 1419.421 High Density
Rutherford 360646 292425 Doughnut 68221 0.233 620 581.687 High Density
Williamson 260351 208242 Doughnut 52109 0.250 583 446.571 Medium Density
Sumner 204424 174773 Doughnut 29651 0.170 529 386.435 Medium Density
Wilson 158805 129918 Doughnut 28887 0.222 571 278.117 Medium Density
Maury 107791 88738 Non-doughnut 19053 0.215 613 175.842 Medium Density
Robertson 75539 67517 Doughnut 8022 0.119 476 158.695 Medium Density
Cheatham 41829 39087 Doughnut 2742 0.070 302 138.507 Medium Density
Dickson 55983 51608 Non-doughnut 4375 0.085 490 114.251 Medium Density
Trousdale 11957 10131 Non-doughnut 1826 0.180 114 104.886 Medium Density
Macon 26240 23261 Non-doughnut 2979 0.128 307 85.472 Low Density
Smith 20389 19389 Non-doughnut 1000 0.052 314 64.933 Low Density
Cannon 14818 13958 Non-doughnut 860 0.062 266 55.707 Low Density
Hickman 25436 24561 Non-doughnut 875 0.036 612 41.562 Low Density

The population data presented in this table come from the U.S. Census Bureau’s American Community Survey (ACS). County land-area data used to calculate population density come from the U.S. Census Bureau’s 2025 Gazetteer Files.

Code:

# ============================================================
# 1. Install Required Packages if Needed and Load Them
# ============================================================

if (!requireNamespace("tidyverse", quietly = TRUE)) {
  install.packages("tidyverse")
}

if (!requireNamespace("knitr", quietly = TRUE)) {
  install.packages("knitr")
}

if (!requireNamespace("kableExtra", quietly = TRUE)) {
  install.packages("kableExtra")
}

library(tidyverse)
library(knitr)
library(kableExtra)


# ============================================================
# 2. Create the County Name Vector
# ============================================================

County <- c(
  "Cannon", "Cheatham", "Davidson", "Dickson", "Hickman", "Macon",
  "Maury", "Robertson", "Rutherford", "Smith", "Sumner", "Trousdale",
  "Williamson", "Wilson"
)


# ============================================================
# 3. Create the Current Population Vector
# ============================================================

CurrentPop <- c(
  14818, 41829, 715388, 55983, 25436, 26240, 107791,
  75539, 360646, 20389, 204424, 11957, 260351, 158805
)


# ============================================================
# 4. Create the Earlier Population Vector
# ============================================================

EarlierPop <- c(
  13958, 39087, 598184, 51608, 24561, 23261, 88738,
  67517, 292425, 19389, 174773, 10131, 208242, 129918
)


# ============================================================
# 5. Assign Each County to a Region
# ============================================================

Region <- c(
  "Non-doughnut", "Doughnut", "Davidson", "Non-doughnut",
  "Non-doughnut", "Non-doughnut", "Non-doughnut", "Doughnut",
  "Doughnut", "Non-doughnut", "Doughnut", "Non-doughnut",
  "Doughnut", "Doughnut"
)


# ============================================================
# 6. Combine the Vectors into the Population Data Frame
# ============================================================

Population <- data.frame(
  County,
  CurrentPop,
  EarlierPop,
  Region
)


# ============================================================
# 7. Sort Population by Current Population
# ============================================================

Population <- Population %>%
  arrange(desc(CurrentPop))


# ============================================================
# 8. Add the Change Variable
# ============================================================

Population <- Population %>%
  mutate(Change = CurrentPop - EarlierPop)


# ============================================================
# 9. Create Change_only
# ============================================================

Change_only <- Population %>%
  select(County, Change) %>%
  arrange(desc(Change))


# ============================================================
# 10. Create Doughnut
# ============================================================

Doughnut <- Population %>%
  filter(Region == "Davidson" | Region == "Doughnut") %>%
  arrange(desc(Change))


# ============================================================
# 11. Summarize Population Totals by Region
# ============================================================

Summary <- Population %>%
  group_by(Region) %>%
  summarize(
    CurrentPop = sum(CurrentPop),
    EarlierPop = sum(EarlierPop),
    Change = sum(Change)
  )


# ============================================================
# 12. Copy Population into Population_v2
# ============================================================

Population_v2 <- Population


# ============================================================
# 13. Calculate Percent Change
# ============================================================

Population_v2 <- Population_v2 %>%
  mutate(Percent_change = Change / EarlierPop) %>%
  arrange(desc(Percent_change))


# ============================================================
# 14. Download Tennessee County Gazetteer File
# ============================================================

TN_Counties <- read_delim(
  "https://www2.census.gov/geo/docs/maps-data/data/gazetteer/2025_Gazetteer/2025_gaz_counties_47.txt",
  delim = "|",
  show_col_types = FALSE
)


# ============================================================
# 15. Create Land_Area Data Frame
# ============================================================

Land_Area <- TN_Counties %>%
  transmute(
    County = str_remove(NAME, " County"),
    Square_Miles = round(ALAND_SQMI)
  )


# ============================================================
# 16. Join Land Area to Population_v2
# ============================================================

Population_v2 <- Population_v2 %>%
  left_join(Land_Area, by = "County")


# ============================================================
# 17. Calculate Population Density
# ============================================================

Population_v2 <- Population_v2 %>%
  mutate(Density = CurrentPop / Square_Miles) %>%
  arrange(desc(Density))


# ============================================================
# 18. Create Density Categories
# ============================================================

Population_v2 <- Population_v2 %>%
  mutate(
    Density_Category = case_when(
      Density >= 500 ~ "High Density",
      Density >= 100 & Density <= 499 ~ "Medium Density",
      Density < 100 ~ "Low Density"
    )
  )


# ============================================================
# 19. Create Updated kableExtra Table
# ============================================================
# This must come AFTER Density and Density_Category are added.

Population_v2_table <- Population_v2 %>%
  kbl(
    caption = "Population Change and Density in Nashville-Area Counties",
    digits = 3
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE
  )


# ============================================================
# 20. Display Updated Table
# ============================================================

Population_v2_table


# ============================================================
# 21. Save Population_v2 as CSV
# ============================================================

write_csv(Population_v2, "Population_v2.csv")


# ============================================================
# 22. Save Population_v2 as RDS
# ============================================================

saveRDS(Population_v2, "Population_v2.RDS")