As seen in the data below, Williamson and Rutherford counties (Go Blue Raiders!) grew faster than Davidson County, which encompasses the city of Nashville, over the last five years. However, Census data show that Davidson County added the most people overall. When looking at growth per 100 residents among counties in the Nashville metropolitan area, Davidson County ranked fifth behind Williamson, Rutherford, Wilson, and Maury counties.

Davidson County added 117,204 residents during this period, followed by Rutherford County with 68,221 and Williamson County with 52,109. While Davidson County added the most people, it did not grow the fastest.

The table below provides details for each county and is sorted by population growth per 100 residents. Williamson County led the region with a growth rate of 25%, while Hickman County experienced the slowest growth, increasing by only 3.5%. All data shown were obtained from the U.S. Census Bureau’s American Community Survey.

Population 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
Population Data
County CurrentPop EarlierPop Region Change
Davidson 715388 598184 Davidson 117204
Rutherford 360646 292425 Doughnut 68221
Williamson 260351 208242 Doughnut 52109
Sumner 204424 174773 Doughnut 29651
Wilson 158805 129918 Doughnut 28887
Maury 107791 88738 Non-doughnut 19053
Robertson 75539 67517 Doughnut 8022
Dickson 55983 51608 Non-doughnut 4375
Cheatham 41829 39087 Doughnut 2742
Macon 26240 23261 Non-doughnut 2979
Hickman 25436 24561 Non-doughnut 875
Smith 20389 19389 Non-doughnut 1000
Cannon 14818 13958 Non-doughnut 860
Trousdale 11957 10131 Non-doughnut 1826

Code:

# ==================================================
# STEP 1: Install and Load Required Packages
# Installs and loads tidyverse, knitr, and kableExtra.
# ==================================================

required_packages <- c("tidyverse", "knitr", "kableExtra")

for(pkg in required_packages) {
  if (!require(pkg, character.only = TRUE)) {
    install.packages(pkg)
    library(pkg, character.only = TRUE)
  }
}
# ==================================================
# STEP 2: Create County Name Vector
# Stores the names of all counties included in the analysis.
# ==================================================
County <- c("Cannon", "Cheatham", "Davidson", "Dickson", "Hickman", "Macon",
            "Maury", "Robertson", "Rutherford", "Smith", "Sumner", "Trousdale",
            "Williamson", "Wilson")

# ==================================================
# STEP 3: Create Current Population Vector
# Stores the most recent population values for each county.
# ==================================================
CurrentPop <- c(14818, 41829, 715388, 55983, 25436, 26240, 107791, 75539,
                360646, 20389, 204424, 11957, 260351, 158805)

# ==================================================
# STEP 4: Create Earlier Population Vector
# Stores population values from the earlier census period.
# ==================================================
EarlierPop <- c(13958, 39087, 598184, 51608, 24561, 23261, 88738, 67517,
                292425, 19389, 174773, 10131, 208242, 129918)

# ==================================================
# STEP 5: Create Regional Classification Vector
# Categorizes each county by geographic region.
# ==================================================
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: Combine Vectors into a Data Frame
# Creates a structured dataset containing all variables.
# ==================================================
Population <- data.frame(
  County,
  CurrentPop,
  EarlierPop,
  Region
)

# ==================================================
# STEP 7: Sort Data by Current Population
# Arranges counties from highest to lowest current population.
# ==================================================
Population <- Population %>%
  arrange(desc(CurrentPop))

# ==================================================
# STEP 8: Add Population Change Variable
# Creates a new variable showing population growth.
# ==================================================
Population <- Population %>%
  mutate(Change = CurrentPop - EarlierPop)

# ==================================================
# STEP 9: Display the Updated Population Data Frame
# Prints the sorted dataset with the Change variable.
# ==================================================
Population

# ==================================================
# STEP 10: Create Change_only Data Frame
# Selects only County and Change variables and
# sorts by Change in descending order.
# ==================================================
Change_only <- Population %>%
  select(County, Change) %>%
  arrange(desc(Change))

# ==================================================
# STEP 11: Display the Change_only Data Frame
# Prints counties ranked by population change.
# ==================================================
Change_only

# ==================================================
# STEP 12: Create Doughnut Data Frame
# Filters for Davidson and Doughnut counties and
# sorts them by Change in descending order.
# ==================================================
Doughnut <- Population %>%
  filter(Region %in% c("Davidson", "Doughnut")) %>%
  arrange(desc(Change))

# ==================================================
# STEP 13: Display the Doughnut Data Frame
# Prints the filtered and sorted Doughnut dataset.
# ==================================================
Doughnut

# ==================================================
# STEP 14: Create Summary Data Frame
# Groups counties by Region and totals population
# variables for each region.
# ==================================================
Summary <- Population %>%
  group_by(Region) %>%
  summarize(
    CurrentPop = sum(CurrentPop),
    EarlierPop = sum(EarlierPop),
    Change = sum(Change)
  )

# ==================================================
# STEP 15: Display the Summary Data Frame
# Prints regional population totals and change.
# ==================================================
Summary

# ==================================================
# STEP 16: Create Population_v2 Data Frame
# Copies the Population data frame into a new data frame.
# ==================================================
Population_v2 <- Population

# ==================================================
# STEP 17: Add Percent_change Variable
# Calculates percentage population change.
# ==================================================
Population_v2 <- Population_v2 %>%
  mutate(Percent_change = Change / EarlierPop)

# ==================================================
# STEP 18: Sort Population_v2 by Percent Change
# Arranges counties from highest to lowest percent change.
# ==================================================
Population_v2 <- Population_v2 %>%
  arrange(desc(Percent_change))

# ==================================================
# STEP 19: Display the Population_v2 Data Frame
# Prints the data frame with Percent_change included.
# ==================================================
Population_v2
# ==================================================
# STEP 20: Create Formatted Population Table
# Creates a kableExtra-formatted table for Population.
# ==================================================
Population_table <- Population %>%
  kbl(caption = "Population Data") %>%
  kable_styling(full_width = FALSE)

# ==================================================
# STEP 21: Display Population Table
# ==================================================
Population_table

# ==================================================
# STEP 22: Create Formatted Change_only Table
# Creates a kableExtra-formatted table for Change_only.
# ==================================================
Change_only_table <- Change_only %>%
  kbl(caption = "County Population Change") %>%
  kable_styling(full_width = FALSE)

# ==================================================
# STEP 23: Display Change_only Table
# ==================================================
Change_only_table

# ==================================================
# STEP 24: Create Formatted Doughnut Table
# Creates a kableExtra-formatted table for Doughnut.
# ==================================================
Doughnut_table <- Doughnut %>%
  kbl(caption = "Davidson and Doughnut Counties") %>%
  kable_styling(full_width = FALSE)

# ==================================================
# STEP 25: Display Doughnut Table
# ==================================================
Doughnut_table

# ==================================================
# STEP 26: Create Formatted Summary Table
# Creates a kableExtra-formatted table for Summary.
# ==================================================
Summary_table <- Summary %>%
  kbl(caption = "Regional Population Summary") %>%
  kable_styling(full_width = FALSE)

# ==================================================
# STEP 27: Display Summary Table
# ==================================================
Summary_table

# ==================================================
# STEP 28: Create Formatted Population_v2 Table
# Creates a kableExtra-formatted table for Population_v2.
# ==================================================
Population_v2_table <- Population_v2 %>%
  kbl(caption = "Population Percent Change") %>%
  kable_styling(full_width = FALSE)

# ==================================================
# STEP 29: Display Population_v2 Table
# ==================================================
Population_v2_table