The table below shows population, population change, land area, and population density for counties in the Nashville metropolitan area. Davidson County has the highest population density at approximately 1,419 residents per square mile, which is more than twice Rutherford County’s density of approximately 582 residents per square mile. Although several surrounding counties have experienced faster population growth rates than Davidson County, their lower population densities suggest that they still have more available land relative to their populations.
The population data shown in this report came from the U.S. Census Bureau’s American Community Survey, while the land-area data came from the U.S. Census Bureau’s 2025 Gazetteer Files.
| County | CurrentPop | EarlierPop | Region | Change | Percent_change | Square_Miles | Density | Density_Category |
|---|---|---|---|---|---|---|---|---|
| Davidson | 715388 | 598184 | Davidson | 117204 | 0.1959330 | 504 | 1419.42063 | High Density |
| Rutherford | 360646 | 292425 | Doughnut | 68221 | 0.2332940 | 620 | 581.68710 | High Density |
| Williamson | 260351 | 208242 | Doughnut | 52109 | 0.2502329 | 583 | 446.57118 | Medium Density |
| Sumner | 204424 | 174773 | Doughnut | 29651 | 0.1696544 | 529 | 386.43478 | Medium Density |
| Wilson | 158805 | 129918 | Doughnut | 28887 | 0.2223479 | 571 | 278.11734 | Medium Density |
| Maury | 107791 | 88738 | Non-doughnut | 19053 | 0.2147107 | 613 | 175.84176 | Medium Density |
| Robertson | 75539 | 67517 | Doughnut | 8022 | 0.1188145 | 476 | 158.69538 | Medium Density |
| Cheatham | 41829 | 39087 | Doughnut | 2742 | 0.0701512 | 302 | 138.50662 | Medium Density |
| Dickson | 55983 | 51608 | Non-doughnut | 4375 | 0.0847737 | 490 | 114.25102 | Medium Density |
| Trousdale | 11957 | 10131 | Non-doughnut | 1826 | 0.1802389 | 114 | 104.88596 | Medium Density |
| Macon | 26240 | 23261 | Non-doughnut | 2979 | 0.1280684 | 307 | 85.47231 | Low Density |
| Smith | 20389 | 19389 | Non-doughnut | 1000 | 0.0515756 | 314 | 64.93312 | Low Density |
| Cannon | 14818 | 13958 | Non-doughnut | 860 | 0.0616134 | 266 | 55.70677 | Low Density |
| Hickman | 25436 | 24561 | Non-doughnut | 875 | 0.0356256 | 612 | 41.56209 | Low Density |
# ============================================================
# Step 1: Install and load required packages
# ============================================================
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)
# ============================================================
# Step 2: Create the County variable
# ============================================================
County <- c(
"Cannon",
"Cheatham",
"Davidson",
"Dickson",
"Hickman",
"Macon",
"Maury",
"Robertson",
"Rutherford",
"Smith",
"Sumner",
"Trousdale",
"Williamson",
"Wilson"
)
# ============================================================
# Step 3: Create the CurrentPop variable
# ============================================================
CurrentPop <- c(
14818,
41829,
715388,
55983,
25436,
26240,
107791,
75539,
360646,
20389,
204424,
11957,
260351,
158805
)
# ============================================================
# Step 4: Create the EarlierPop variable
# ============================================================
EarlierPop <- c(
13958,
39087,
598184,
51608,
24561,
23261,
88738,
67517,
292425,
19389,
174773,
10131,
208242,
129918
)
# ============================================================
# Step 5: Create the Region variable
# ============================================================
Region <- c(
"Non-doughnut",
"Doughnut",
"Davidson",
"Non-doughnut",
"Non-doughnut",
"Non-doughnut",
"Non-doughnut",
"Doughnut",
"Doughnut",
"Non-doughnut",
"Doughnut",
"Non-doughnut",
"Doughnut",
"Doughnut"
)
# ============================================================
# Step 6: Create the Population data frame
# ============================================================
Population <- data.frame(
County,
CurrentPop,
EarlierPop,
Region
)
# ============================================================
# Step 7: Sort Population by CurrentPop in descending order
# ============================================================
Population <- Population %>%
arrange(desc(CurrentPop))
# ============================================================
# Step 8: Add a Change variable
# ============================================================
Population <- Population %>%
mutate(Change = CurrentPop - EarlierPop)
# ============================================================
# Step 9: Create Change_only
# ============================================================
Change_only <- Population %>%
select(County, Change) %>%
arrange(desc(Change))
# ============================================================
# Step 10: Create Doughnut
# ============================================================
Doughnut <- Population %>%
filter(Region == "Davidson" | Region == "Doughnut") %>%
arrange(desc(Change))
# ============================================================
# Step 11: Create Summary
# ============================================================
Summary <- Population %>%
group_by(Region) %>%
summarize(
CurrentPop = sum(CurrentPop),
EarlierPop = sum(EarlierPop),
Change = sum(Change)
)
# ============================================================
# Step 12: Create Population_v2
# ============================================================
Population_v2 <- Population
# ============================================================
# Step 13: Add Percent_change
# ============================================================
Population_v2 <- Population_v2 %>%
mutate(Percent_change = Change / EarlierPop)
# ============================================================
# Step 14: Sort Population_v2 by Percent_change
# ============================================================
Population_v2 <- Population_v2 %>%
arrange(desc(Percent_change))
# ============================================================
# Step 15: Create formatted kableExtra tables
# ============================================================
Population_table <- Population %>%
kable(
caption = "Population Data",
format = "html"
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
)
Change_only_table <- Change_only %>%
kable(
caption = "Population Change by County",
format = "html"
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
)
Doughnut_table <- Doughnut %>%
kable(
caption = "Davidson and Doughnut Counties",
format = "html"
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
)
Summary_table <- Summary %>%
kable(
caption = "Regional Population Totals",
format = "html"
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
)
Population_v2_table <- Population_v2 %>%
kable(
caption = "Population Data with Percent Change",
format = "html",
digits = c(0, 0, 0, 0, 0, 6)
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE
)
# ============================================================
# Step 16: Display the final Population_v2 table
# ============================================================
Population_v2_table