Of the many different counties in mid-state, the highest population density belongs to Davidson County with Rutherford at less than half of that density total in second. Those two are the only counties designated at high densities while the next eight counties are at medium density. The remaining four are at low density. Rutherford has the largest square mileage total at 620 while Maury and Hickman counties are right behind at 613 and 612 respectively. This shows that Rutherford has a lot of space to work with, but a lot of people still around to take up all the space. This data all came from the U.S. Census Bureau’s American Community Survey, and is taken from the most recent data available.
The table below demonstrates these findings.
| 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 |
Code
Here is the code for these findings and results on square miles and density in the mid-state area.
# 1. Install tidyverse, knitr, and kableExtra if not already installed; then load them
if (!require(tidyverse)) {
install.packages("tidyverse")
}
if (!require(knitr)) {
install.packages("knitr")
}
if (!require(kableExtra)) {
install.packages("kableExtra")
}
library(tidyverse)
library(knitr)
library(kableExtra)
# 2. Define county names
County <- c("Cannon", "Cheatham", "Davidson", "Dickson", "Hickman", "Macon",
"Maury", "Robertson", "Rutherford", "Smith", "Sumner", "Trousdale",
"Williamson", "Wilson")
# 3. Define current population values
CurrentPop <- c(14818, 41829, 715388, 55983, 25436, 26240, 107791, 75539, 360646,
20389, 204424, 11957, 260351, 158805)
# 4. Define earlier population values
EarlierPop <- c(13958, 39087, 598184, 51608, 24561, 23261, 88738, 67517, 292425,
19389, 174773, 10131, 208242, 129918)
# 5. Define region classification for each county
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 all vectors into a single data frame
Population <- data.frame(
County,
CurrentPop,
EarlierPop,
Region
)
# 7. Sort Population by CurrentPop in descending order
Population <- Population %>% arrange(desc(CurrentPop))
# 8. Add Change variable showing population growth
Population <- Population %>% mutate(Change = CurrentPop - EarlierPop)
# 9. Display the updated Population data frame
Population
# 10. Create Change_only data frame with only County and Change
Change_only <- Population %>% select(County, Change)
# 11. Sort Change_only by Change in descending order
Change_only <- Change_only %>% arrange(desc(Change))
# 12. Display the Change_only data frame
Change_only
# 13. Create Doughnut data frame containing only Davidson or Doughnut rows
Doughnut <- Population %>% filter(Region %in% c("Davidson", "Doughnut"))
# 14. Sort Doughnut data frame by Change in descending order
Doughnut <- Doughnut %>% arrange(desc(Change))
# 15. Display the Doughnut data frame
Doughnut
# 16. Create Summary data frame that totals CurrentPop, EarlierPop, and Change by Region
Summary <- Population %>%
group_by(Region) %>%
summarize(
Total_CurrentPop = sum(CurrentPop),
Total_EarlierPop = sum(EarlierPop),
Total_Change = sum(Change)
)
# 17. Display the Summary data frame
Summary
# 18. Copy Population data into Population_v2
Population_v2 <- Population
# 19. Add Percent_change variable using mutate()
Population_v2 <- Population_v2 %>% mutate(Percent_change = Change / EarlierPop)
# 20. Sort Population_v2 by Percent_change in descending order
Population_v2 <- Population_v2 %>% arrange(desc(Percent_change))
# 21. Display the Population_v2 data frame
Population_v2
# 22. Create kableExtra-formatted tables for all data frames
Population_kable <- Population %>%
kable("html", caption = "Population Data Frame") %>%
kable_styling(full_width = FALSE)
Change_only_kable <- Change_only %>%
kable("html", caption = "Change Only Data Frame") %>%
kable_styling(full_width = FALSE)
Doughnut_kable <- Doughnut %>%
kable("html", caption = "Doughnut Region Data Frame") %>%
kable_styling(full_width = FALSE)
Summary_kable <- Summary %>%
kable("html", caption = "Summary by Region") %>%
kable_styling(full_width = FALSE)
Population_v2_kable <- Population_v2 %>%
kable("html", caption = "Population_v2 with Percent Change") %>%
kable_styling(full_width = FALSE)
# ============================================================
# Download Tennessee County Gazetteer File
# ============================================================
# Import county land-area data from the U.S. Census Bureau.
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
)
# ============================================================
# Create Land_Area Data Frame
# ============================================================
# Keep county name and land area in square miles.
# Remove " County" from county names.
# Round land area to the nearest whole square mile.
Land_Area <- TN_Counties %>%
transmute(
County = str_remove(NAME, " County"),
Square_Miles = round(ALAND_SQMI)
)
# ============================================================
# Display Results
# ============================================================
# View the completed land-area data frame.
Land_Area
# Add Square_Miles from Land_Area to Population_v2 using left_join()
Population_v2 <- Population_v2 %>%
left_join(Land_Area, by = "County")
# Add Density variable to Population_v2
Population_v2 <- Population_v2 %>%
mutate(
Density = CurrentPop / Square_Miles
)
# Create Density_Category using case_when()
Population_v2 <- Population_v2 %>%
mutate(
Density_Category = case_when(
Density >= 500 ~ "High Density",
Density >= 100 & Density <= 499 ~ "Medium Density",
Density < 100 ~ "Low Density"
)
)
Population_v2 <- Population_v2 %>%
arrange(desc(Density))
Population_v2_table <- Population_v2 %>%
kable("html", caption = "Population_v2 with Density and Density_Category") %>%
kable_styling(full_width = FALSE)
Population_v2_table