Summary This report analyzes population dynamics across 14 Middle Tennessee counties, detailing recent total population figures, net change, and percentage growth rate. Key findings include: Regional Dominance: Davidson County remains the most populous county in the region with 715,388 residents. Growth Leaders: Rutherford County registered the highest absolute increase in residents (up 68,221), while Williamson County leads the region in proportional growth with an approximate 25.0% increase over earlier levels. Regional Distribution: Counties classified within the “Doughnut” region account for the largest share of overall population expansion, underscoring significant suburban growth surrounding Davidson County.
| County | CurrentPop | EarlierPop | Region | Change | Percent_change |
|---|---|---|---|---|---|
| Williamson | 260351 | 208242 | Doughnut | 52109 | 0.2502329 |
| Rutherford | 360646 | 292425 | Doughnut | 68221 | 0.2332940 |
| Wilson | 158805 | 129918 | Doughnut | 28887 | 0.2223479 |
| Maury | 107791 | 88738 | Non-doughnut | 19053 | 0.2147107 |
| Davidson | 715388 | 598184 | Davidson | 117204 | 0.1959330 |
| Trousdale | 11957 | 10131 | Non-doughnut | 1826 | 0.1802389 |
| Sumner | 204424 | 174773 | Doughnut | 29651 | 0.1696544 |
| Macon | 26240 | 23261 | Non-doughnut | 2979 | 0.1280684 |
| Robertson | 75539 | 67517 | Doughnut | 8022 | 0.1188145 |
| Dickson | 55983 | 51608 | Non-doughnut | 4375 | 0.0847737 |
| Cheatham | 41829 | 39087 | Doughnut | 2742 | 0.0701512 |
| Cannon | 14818 | 13958 | Non-doughnut | 860 | 0.0616134 |
| Smith | 20389 | 19389 | Non-doughnut | 1000 | 0.0515756 |
| Hickman | 25436 | 24561 | Non-doughnut | 875 | 0.0356256 |
Here is the R code that produced the analysis. The analysis relied on data from the U.S. Census Bureau’s American Community Survey.
# -----------------------------------------------------------------------------
# 1. SETUP & PACKAGE LOADING
# -----------------------------------------------------------------------------
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 VECTOR DATA
# -----------------------------------------------------------------------------
County <- c("Cannon", "Cheatham", "Davidson", "Dickson", "Hickman", "Macon",
"Maury", "Robertson", "Rutherford", "Smith", "Sumner", "Trousdale",
"Williamson", "Wilson")
CurrentPop <- c(14818, 41829, 715388, 55983, 25436, 26240, 107791, 75539, 360646,
20389, 204424, 11957, 260351, 158805)
EarlierPop <- c(13958, 39087, 598184, 51608, 24561, 23261, 88738, 67517, 292425,
19389, 174773, 10131, 208242, 129918)
Region <- c("Non-doughnut", "Doughnut", "Davidson", "Non-doughnut", "Non-doughnut",
"Non-doughnut", "Non-doughnut", "Doughnut", "Doughnut", "Non-doughnut",
"Doughnut", "Non-doughnut", "Doughnut", "Doughnut")
# -----------------------------------------------------------------------------
# 3. COMBINE VECTORS INTO A DATA FRAME
# -----------------------------------------------------------------------------
Population <- data.frame(County, CurrentPop, EarlierPop, Region)
# -----------------------------------------------------------------------------
# 4. DISPLAY INITIAL DATA FRAME
# -----------------------------------------------------------------------------
Population
# -----------------------------------------------------------------------------
# 5. SORT DATA FRAME
# -----------------------------------------------------------------------------
Population <- Population %>% arrange(desc(CurrentPop))
# -----------------------------------------------------------------------------
# 6. DISPLAY SORTED DATA FRAME
# -----------------------------------------------------------------------------
Population
# -----------------------------------------------------------------------------
# 7. ADD POPULATION CHANGE VARIABLE
# -----------------------------------------------------------------------------
Population <- Population %>% mutate(Change = CurrentPop - EarlierPop)
# -----------------------------------------------------------------------------
# 8. DISPLAY UPDATED DATA FRAME
# -----------------------------------------------------------------------------
Population
# -----------------------------------------------------------------------------
# 9. CREATE & SORT CHANGE_ONLY DATA FRAME
# -----------------------------------------------------------------------------
Change_only <- Population %>% select(County, Change) %>% arrange(desc(Change))
# -----------------------------------------------------------------------------
# 10. DISPLAY CHANGE_ONLY DATA FRAME
# -----------------------------------------------------------------------------
Change_only
# -----------------------------------------------------------------------------
# 11. CREATE, FILTER, & SORT DOUGHNUT DATA FRAME
# -----------------------------------------------------------------------------
Doughnut <- Population %>%
filter(Region %in% c("Davidson", "Doughnut")) %>%
arrange(desc(Change))
# -----------------------------------------------------------------------------
# 12. DISPLAY DOUGHNUT DATA FRAME
# -----------------------------------------------------------------------------
Doughnut
# -----------------------------------------------------------------------------
# 13. AGGREGATE POPULATION METRICS BY REGION
# -----------------------------------------------------------------------------
Summary <- Population %>%
group_by(Region) %>%
summarize(
CurrentPop = sum(CurrentPop),
EarlierPop = sum(EarlierPop),
Change = sum(Change)
)
# -----------------------------------------------------------------------------
# 14. DISPLAY SUMMARY DATA FRAME
# -----------------------------------------------------------------------------
Summary
# -----------------------------------------------------------------------------
# 15. CALCULATE PERCENT CHANGE
# -----------------------------------------------------------------------------
Population_v2 <- Population %>%
mutate(Percent_change = Change / EarlierPop) %>%
arrange(desc(Percent_change))
# -----------------------------------------------------------------------------
# 16. DISPLAY POPULATION_V2 DATA FRAME
# -----------------------------------------------------------------------------
Population_v2
# -----------------------------------------------------------------------------
# 17. FORMAT TABLES WITH KABLEEXTRA
# -----------------------------------------------------------------------------
tbl_Population <- kable(Population, caption = "Population Data") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
tbl_Change_only <- kable(Change_only, caption = "Population Change Only") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
tbl_Doughnut <- kable(Doughnut, caption = "Doughnut Region Data") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
tbl_Summary <- kable(Summary, caption = "Regional Population Summary") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
tbl_Population_v2 <- kable(Population_v2, caption = "Population Data with Percent Change") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
# -----------------------------------------------------------------------------
# 18. DISPLAY KABLEEXTRA TABLES
# -----------------------------------------------------------------------------
tbl_Population
tbl_Change_only
tbl_Doughnut
tbl_Summary
tbl_Population_v2