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.

Population Data with Percent Change
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

Code:

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