1. Importing the data

I used read_csv() from readr, which is part of the Tidyverse. The original file contains 3,142 rows and 35 columns. Each row represents a county or county equivalent.

counties_raw <- read_csv("acs_2015_county_data_revised.csv", show_col_types = FALSE)
tibble(rows = nrow(counties_raw), columns = ncol(counties_raw))
## # A tibble: 1 × 2
##    rows columns
##   <int>   <int>
## 1  3142      35

2. Variable types

The census ID is an identifier, so I changed it from numeric to character and padded it to five digits. This preserves leading zeros and avoids treating the ID as a measurement. State and county can remain character variables; the measurements can remain numeric. I did not convert percentage values to proportions because the questions use a 0–100 scale.

counties <- counties_raw %>%
  mutate(census_id = str_pad(as.character(census_id), width = 5, pad = "0"))
glimpse(counties)
## Rows: 3,142
## Columns: 35
## $ census_id      <chr> "01001", "01003", "01005", "01007", "01009", "01011", "01013", "01015", "01…
## $ state          <chr> "Alabama", "Alabama", "Alabama", "Alabama", "Alabama", "Alabama", "Alabama"…
## $ county         <chr> "Autauga", "Baldwin", "Barbour", "Bibb", "Blount", "Bullock", "Butler", "Ca…
## $ total_pop      <dbl> 55221, 195121, 26932, 22604, 57710, 10678, 20354, 116648, 34079, 26008, 438…
## $ men            <dbl> 26745, 95314, 14497, 12073, 28512, 5660, 9502, 56274, 16258, 12975, 21619, …
## $ women          <dbl> 28476, 99807, 12435, 10531, 29198, 5018, 10852, 60374, 17821, 13033, 22200,…
## $ hispanic       <dbl> 2.6, 4.5, 4.6, 2.2, 8.6, 4.4, 1.2, 3.5, 0.4, 1.5, 7.6, 0.4, 0.3, 3.2, 2.3, …
## $ white          <dbl> 75.8, 83.1, 46.2, 74.5, 87.9, 22.2, 53.3, 73.0, 57.3, 91.7, 80.5, 55.9, 53.…
## $ black          <dbl> 18.5, 9.5, 46.7, 21.4, 1.5, 70.7, 43.8, 20.3, 40.3, 4.8, 10.2, 42.9, 45.3, …
## $ native         <dbl> 0.4, 0.6, 0.2, 0.4, 0.3, 1.2, 0.1, 0.2, 0.2, 0.6, 0.4, 0.0, 0.0, 0.7, 0.2, …
## $ asian          <dbl> 1.0, 0.7, 0.4, 0.1, 0.1, 0.2, 0.4, 0.9, 0.8, 0.3, 0.3, 0.0, 0.4, 0.0, 0.4, …
## $ pacific        <dbl> 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 0.0, 0.0, …
## $ citizen        <dbl> 40725, 147695, 20714, 17495, 42345, 8057, 15581, 88612, 26462, 20600, 31728…
## $ income         <dbl> 51281, 50254, 32964, 38678, 45813, 31938, 32229, 41703, 34177, 36296, 41627…
## $ income_per_cap <dbl> 24974, 27317, 16824, 18431, 20532, 17580, 18390, 21374, 21071, 21811, 21399…
## $ poverty        <dbl> 12.9, 13.4, 26.7, 16.8, 16.7, 24.6, 25.4, 20.5, 21.6, 19.2, 19.1, 23.4, 24.…
## $ child_poverty  <dbl> 18.6, 19.2, 45.3, 27.9, 27.2, 38.4, 39.2, 31.6, 37.2, 30.1, 30.6, 34.4, 29.…
## $ professional   <dbl> 33.2, 33.1, 26.8, 21.5, 28.5, 18.8, 27.5, 27.3, 23.3, 29.3, 27.2, 24.9, 21.…
## $ service        <dbl> 17.0, 17.7, 16.1, 17.9, 14.1, 15.0, 16.6, 17.7, 14.5, 16.0, 14.3, 15.4, 15.…
## $ office         <dbl> 24.2, 27.1, 23.1, 17.8, 23.9, 19.7, 21.9, 24.2, 26.3, 19.5, 23.7, 19.6, 25.…
## $ construction   <dbl> 8.6, 10.8, 10.8, 19.0, 13.5, 20.1, 10.3, 10.5, 11.5, 13.7, 15.3, 18.3, 11.6…
## $ production     <dbl> 17.1, 11.2, 23.1, 23.7, 19.9, 26.4, 23.7, 20.4, 24.4, 21.5, 19.5, 21.8, 26.…
## $ drive          <dbl> 87.5, 84.7, 83.8, 83.2, 84.9, 74.9, 84.5, 85.3, 85.1, 83.9, 81.2, 85.5, 82.…
## $ carpool        <dbl> 8.8, 8.8, 10.9, 13.5, 11.2, 14.9, 12.4, 9.4, 11.9, 12.1, 14.2, 10.3, 12.8, …
## $ transit        <dbl> 0.1, 0.1, 0.4, 0.5, 0.4, 0.7, 0.0, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.6, 0.1, …
## $ walk           <dbl> 0.5, 1.0, 1.8, 0.6, 0.9, 5.0, 0.8, 1.2, 0.3, 0.6, 1.1, 1.9, 1.3, 1.8, 0.2, …
## $ other_transp   <dbl> 1.3, 1.4, 1.5, 1.5, 0.4, 1.7, 0.6, 1.2, 0.4, 0.7, 1.4, 1.4, 2.6, 0.9, 1.0, …
## $ work_at_home   <dbl> 1.8, 3.9, 1.6, 0.7, 2.3, 2.8, 1.7, 2.7, 2.1, 2.5, 1.9, 0.8, 1.1, 2.1, 3.4, …
## $ mean_commute   <dbl> 26.5, 26.4, 24.1, 28.8, 34.9, 27.5, 24.6, 24.1, 25.1, 27.4, 32.0, 30.7, 23.…
## $ employed       <dbl> 23986, 85953, 8597, 8294, 22189, 3865, 7813, 47401, 13689, 10155, 17895, 44…
## $ private_work   <dbl> 73.6, 81.5, 71.8, 76.8, 82.0, 79.5, 77.4, 74.1, 85.1, 73.1, 80.3, 77.5, 83.…
## $ public_work    <dbl> 20.9, 12.3, 20.8, 16.1, 13.5, 15.1, 16.2, 20.8, 12.1, 18.5, 15.2, 16.8, 13.…
## $ self_employed  <dbl> 5.5, 5.8, 7.3, 6.7, 4.2, 5.4, 6.2, 5.0, 2.8, 7.9, 4.1, 5.4, 3.3, 7.8, 8.4, …
## $ family_work    <dbl> 0.0, 0.4, 0.1, 0.4, 0.4, 0.0, 0.2, 0.1, 0.0, 0.5, 0.5, 0.3, 0.0, 0.0, 0.0, …
## $ unemployment   <dbl> 7.6, 7.5, 17.6, 8.3, 7.7, 18.0, 10.9, 12.3, 8.9, 7.9, 9.1, 13.6, 19.4, 9.4,…

3. Missing values

There are two missing cells: child poverty for Kalawao County, Hawaii, and household income for Loving County, Texas. I removed these two observations, leaving 3,140 counties for all subsequent questions. This removes about 0.064% of the original rows. A national mean or median would be a weak substitute for these small counties. Keeping one complete-case dataset also makes the later counts consistent. This choice does exclude their valid measurements from later questions, and it has a noticeable effect on Hawaii’s averages because Hawaii has few counties.

missing_counts <- counties %>%
  summarise(across(everything(), ~ sum(is.na(.x)))) %>%
  pivot_longer(everything(), names_to = "variable", values_to = "missing") %>%
  filter(missing > 0)
knitr::kable(missing_counts)
variable missing
income 1
child_poverty 1
counties %>% filter(if_any(everything(), is.na)) %>%
  select(census_id, county, state, income, child_poverty) %>% knitr::kable()
census_id county state income child_poverty
15005 Kalawao Hawaii 66250 NA
48301 Loving Texas NA 0
counties <- counties %>% drop_na()
tibble(rows_remaining = nrow(counties), missing_cells = sum(is.na(counties)))
## # A tibble: 1 × 2
##   rows_remaining missing_cells
##            <int>         <int>
## 1           3140             0

4. Unusual values

I used summary() to review the cleaned data. Population is strongly skewed: the largest county has 10,038,388 residents. Some commuting measures are also unusual, including a maximum walking share of 71.2% and a maximum public transit share of 61.7%. These are possible county characteristics, so I kept them rather than removing observations solely because they are extreme. All individual percentage variables are between 0 and 100, and men plus women equals total population in every retained row. The employed variable contains counts despite being described as a percentage in the dictionary; its values are consistent with counts, so I did not cap it at 100.

summary(counties)
##      census_id          state            county       total_pop       
##  Length   :3140   Length   :3140   Length   :3140   Min.   :     267  
##  N.unique :3140   N.unique :  51   N.unique :1849   1st Qu.:   11036  
##  N.blank  :   0   N.blank  :   0   N.blank  :   0   Median :   25793  
##  Min.nchar:   5   Min.nchar:   4   Min.nchar:   3   Mean   :  100801  
##  Max.nchar:   5   Max.nchar:  20   Max.nchar:  33   3rd Qu.:   67620  
##                                                     Max.   :10038388  
##       men              women            hispanic          white      
##  Min.   :    136   Min.   :    131   Min.   : 0.000   Min.   : 0.90  
##  1st Qu.:   5551   1st Qu.:   5488   1st Qu.: 1.900   1st Qu.:65.67  
##  Median :  12838   Median :  12916   Median : 3.700   Median :84.65  
##  Mean   :  49597   Mean   :  51204   Mean   : 8.819   Mean   :77.31  
##  3rd Qu.:  33328   3rd Qu.:  34123   3rd Qu.: 9.000   3rd Qu.:93.33  
##  Max.   :4945351   Max.   :5093037   Max.   :98.700   Max.   :99.80  
##      black            native           asian           pacific        
##  Min.   : 0.000   Min.   : 0.000   Min.   : 0.000   Min.   : 0.00000  
##  1st Qu.: 0.600   1st Qu.: 0.100   1st Qu.: 0.200   1st Qu.: 0.00000  
##  Median : 2.100   Median : 0.300   Median : 0.500   Median : 0.00000  
##  Mean   : 8.885   Mean   : 1.763   Mean   : 1.253   Mean   : 0.07357  
##  3rd Qu.:10.200   3rd Qu.: 0.600   3rd Qu.: 1.200   3rd Qu.: 0.00000  
##  Max.   :85.900   Max.   :92.100   Max.   :41.600   Max.   :11.10000  
##     citizen            income       income_per_cap     poverty    
##  Min.   :    199   Min.   : 19328   Min.   : 8292   Min.   : 1.4  
##  1st Qu.:   8276   1st Qu.: 38826   1st Qu.:20470   1st Qu.:12.0  
##  Median :  19454   Median : 45094   Median :23574   Median :16.0  
##  Mean   :  70849   Mean   : 46824   Mean   :24331   Mean   :16.7  
##  3rd Qu.:  50795   3rd Qu.: 52248   3rd Qu.:27138   3rd Qu.:20.3  
##  Max.   :6046749   Max.   :123453   Max.   :65600   Max.   :53.3  
##  child_poverty    professional      service          office     
##  Min.   : 0.00   Min.   :13.50   Min.   : 5.00   Min.   : 4.10  
##  1st Qu.:16.10   1st Qu.:26.70   1st Qu.:15.90   1st Qu.:20.20  
##  Median :22.50   Median :30.00   Median :18.00   Median :22.40  
##  Mean   :23.29   Mean   :31.05   Mean   :18.25   Mean   :22.13  
##  3rd Qu.:29.50   3rd Qu.:34.42   3rd Qu.:20.20   3rd Qu.:24.30  
##  Max.   :72.30   Max.   :74.00   Max.   :36.60   Max.   :35.40  
##   construction     production        drive         carpool     
##  Min.   : 1.70   Min.   : 0.00   Min.   : 5.2   Min.   : 0.00  
##  1st Qu.: 9.80   1st Qu.:11.50   1st Qu.:76.6   1st Qu.: 8.50  
##  Median :12.20   Median :15.40   Median :80.6   Median : 9.90  
##  Mean   :12.75   Mean   :15.82   Mean   :79.1   Mean   :10.33  
##  3rd Qu.:15.00   3rd Qu.:19.40   3rd Qu.:83.6   3rd Qu.:11.90  
##  Max.   :40.30   Max.   :55.60   Max.   :94.6   Max.   :29.90  
##     transit             walk         other_transp    work_at_home   
##  Min.   : 0.0000   Min.   : 0.000   Min.   : 0.00   Min.   : 0.000  
##  1st Qu.: 0.1000   1st Qu.: 1.400   1st Qu.: 0.90   1st Qu.: 2.800  
##  Median : 0.4000   Median : 2.400   Median : 1.30   Median : 4.000  
##  Mean   : 0.9681   Mean   : 3.294   Mean   : 1.61   Mean   : 4.694  
##  3rd Qu.: 0.8000   3rd Qu.: 4.000   3rd Qu.: 1.90   3rd Qu.: 5.700  
##  Max.   :61.7000   Max.   :71.200   Max.   :39.10   Max.   :37.200  
##   mean_commute      employed        private_work    public_work   
##  Min.   : 4.90   Min.   :    166   Min.   :29.50   Min.   : 5.80  
##  1st Qu.:19.30   1st Qu.:   4532   1st Qu.:70.90   1st Qu.:13.07  
##  Median :22.90   Median :  10657   Median :75.85   Median :16.10  
##  Mean   :23.15   Mean   :  46416   Mean   :74.45   Mean   :17.33  
##  3rd Qu.:26.60   3rd Qu.:  29272   3rd Qu.:79.80   3rd Qu.:20.10  
##  Max.   :44.00   Max.   :4635465   Max.   :88.30   Max.   :66.20  
##  self_employed     family_work      unemployment   
##  Min.   : 0.000   Min.   :0.0000   Min.   : 0.000  
##  1st Qu.: 5.400   1st Qu.:0.1000   1st Qu.: 5.500  
##  Median : 6.900   Median :0.2000   Median : 7.500  
##  Mean   : 7.922   Mean   :0.2917   Mean   : 7.815  
##  3rd Qu.: 9.400   3rd Qu.:0.3000   3rd Qu.: 9.700  
##  Max.   :36.600   Max.   :9.8000   Max.   :29.400
percent_vars <- c("hispanic", "white", "black", "native", "asian", "pacific",
  "poverty", "child_poverty", "professional", "service", "office",
  "construction", "production", "drive", "carpool", "transit", "walk",
  "other_transp", "work_at_home", "private_work", "public_work",
  "self_employed", "family_work", "unemployment")
counties %>% summarise(
  invalid_percent_rows = sum(if_any(all_of(percent_vars), ~ .x < 0 | .x > 100)),
  inconsistent_population_rows = sum(men + women != total_pop),
  employed_above_population = sum(employed > total_pop),
  duplicate_ids = sum(duplicated(census_id)))
## # A tibble: 1 × 4
##   invalid_percent_rows inconsistent_population_rows employed_above_population
##                  <int>                        <int>                     <int>
## 1                    0                            0                         0
##   duplicate_ids
##           <int>
## 1             0

No additional rows were removed or values replaced after these checks. The race totals are checked separately in Question 9.

5. Counties with more women than men

counties %>% filter(women > men) %>% summarise(counties = n())
## # A tibble: 1 × 1
##   counties
##      <int>
## 1     1984

1,984 counties have more women than men. Counties with equal numbers do not meet the strict inequality.

6. Unemployment below 10%

counties %>% filter(unemployment < 10) %>% summarise(counties = n())
## # A tibble: 1 × 1
##   counties
##      <int>
## 1     2419

2,419 counties have unemployment below 10%. A value of 10 means 10%, so the cutoff is 10 rather than 0.10.

7. Highest mean commute

I used the requested top_n() function, then sorted the results from longest to shortest commute. top_n() includes ties at its cutoff; this selection returns exactly ten counties.

result <- counties %>% top_n(10, wt = mean_commute) %>%
  arrange(desc(mean_commute), census_id) %>%
  select(census_id, county, state, mean_commute)
knitr::kable(result, digits = 4)
census_id county state mean_commute
42103 Pike Pennsylvania 44.0
36005 Bronx New York 43.0
24017 Charles Maryland 42.8
51187 Warren Virginia 42.7
36081 Queens New York 42.6
36085 Richmond New York 42.6
51193 Westmoreland Virginia 42.5
08093 Park Colorado 42.4
36047 Kings New York 41.7
54015 Clay West Virginia 41.4

Pike County, Pennsylvania, has the longest mean commute at 44.0 minutes. These are county averages, not individual commute times.

8. Lowest percentages of women

counties <- counties %>% mutate(women_pct = 100 * women / total_pop)
result <- counties %>% arrange(women_pct, census_id) %>%
  slice_head(n = 10) %>% select(census_id, county, state, women_pct)
knitr::kable(result, digits = 4)
census_id county state women_pct
42053 Forest Pennsylvania 26.7775
08011 Bent Colorado 31.3656
51183 Sussex Virginia 31.4734
13309 Wheeler Georgia 32.1016
06035 Lassen California 33.1659
48095 Concho Texas 33.2844
13053 Chattahoochee Georgia 33.3557
02013 Aleutians East Borough Alaska 33.4746
22125 West Feliciana Louisiana 33.6490
32027 Pershing Nevada 33.7251

Forest County, Pennsylvania, has the lowest share of women, about 26.78%. I calculated the percentage using the county’s total population and sorted the unrounded results.

9. Race and ethnicity percentage totals

I added the six variables specified in the question. Each source percentage has one decimal place, so rounding the sum to one decimal avoids floating-point artifacts when comparing it with 100.

counties <- counties %>% mutate(
  race_sum = round(hispanic + white + black + native + asian + pacific, 1))

9a. Ten lowest county totals

result <- counties %>% arrange(race_sum, census_id) %>%
  slice_head(n = 10) %>% select(census_id, county, state, race_sum)
knitr::kable(result, digits = 4)
census_id county state race_sum
15001 Hawaii Hawaii 76.4
15009 Maui Hawaii 79.2
40097 Mayes Oklahoma 79.7
15003 Honolulu Hawaii 81.5
40123 Pontotoc Oklahoma 82.8
47061 Grundy Tennessee 83.0
02282 Yakutat City and Borough Alaska 83.4
40069 Johnston Oklahoma 84.0
15007 Kauai Hawaii 84.1
40003 Alfalfa Oklahoma 85.1

These six categories do not necessarily describe the entire population. In particular, the file does not provide separate columns for multiracial residents or every other race category. I kept low totals rather than rescaling them to 100%. A low total alone is not evidence of a data-entry error.

9b. Lowest average total by state

state_race <- counties %>% group_by(state) %>%
  summarise(mean_race_sum = mean(race_sum), .groups = "drop")
result <- state_race %>% arrange(mean_race_sum, state) %>% slice_head(n = 1)
knitr::kable(result, digits = 4)
state mean_race_sum
Hawaii 80.3

Hawaii has the lowest average at 80.30% across its retained counties. This is an unweighted county average; it is not a statewide population percentage.

9c. County totals above 100%

result <- counties %>% filter(race_sum > 100) %>%
  arrange(state, county) %>% select(census_id, county, state, race_sum)
knitr::kable(result, digits = 4)
census_id county state race_sum
31073 Gosper Nebraska 100.1
31091 Hooker Nebraska 100.1
31125 Nance Nebraska 100.1
48017 Bailey Texas 100.1
48137 Edwards Texas 100.1

Five counties have a total above 100%, and each totals 100.1%. Because the component values are rounded to one decimal, this small excess can arise from rounding. I kept the supplied values instead of forcing the totals to equal 100%.

9d. States with a total exactly equal to 100%

I interpret this as asking whether the average county total for a state equals 100%, consistent with the state comparison in 9b. Adding county percentages directly across a state would not produce a meaningful statewide percentage.

state_race %>% filter(near(mean_race_sum, 100)) %>%
  summarise(states = n())
## # A tibble: 1 × 1
##   states
##    <int>
## 1      0
# Alternative reading: states containing at least one county totaling 100%.
counties %>% filter(near(race_sum, 100)) %>%
  summarise(states_with_a_100_percent_county = n_distinct(state))
## # A tibble: 1 × 1
##   states_with_a_100_percent_county
##                              <int>
## 1                               16

Zero states have an average county total equal to 100%. If the question instead means states containing at least one county whose total is 100%, the answer is 16 states. The comparisons use a small numerical tolerance without rounding state averages to whole percentages.

10. Carpooling

10a. Creating the county rank

counties <- counties %>% mutate(carpool_rank = min_rank(desc(carpool)))

min_rank(desc(carpool)) gives rank 1 to the highest carpool percentage. Tied counties receive the same rank, with gaps after ties. For example, the lowest carpool percentage is shared, so the bottom rank need not equal the number of rows.

10b. Ten highest ranked counties

result <- counties %>% arrange(carpool_rank, census_id) %>%
  slice_head(n = 10) %>%
  select(census_id, county, state, carpool, carpool_rank)
knitr::kable(result, digits = 4)
census_id county state carpool carpool_rank
13061 Clay Georgia 29.9 1
18087 LaGrange Indiana 27.0 2
13165 Jenkins Georgia 25.3 3
05133 Sevier Arkansas 24.4 4
20175 Seward Kansas 23.4 5
48079 Cochran Texas 22.8 6
48247 Jim Hogg Texas 22.6 7
48393 Roberts Texas 22.4 8
39075 Holmes Ohio 21.8 9
21197 Powell Kentucky 21.6 10

10c. Ten lowest ranked counties

result <- counties %>% arrange(desc(carpool_rank), census_id) %>%
  slice_head(n = 10) %>%
  select(census_id, county, state, carpool, carpool_rank)
knitr::kable(result, digits = 4)
census_id county state carpool carpool_rank
48261 Kenedy Texas 0.0 3139
48269 King Texas 0.0 3139
48235 Irion Texas 0.9 3138
31183 Wheeler Nebraska 1.3 3137
36061 New York New York 1.9 3136
13309 Wheeler Georgia 2.3 3134
38029 Emmons North Dakota 2.3 3134
30019 Daniels Montana 2.6 3132
31057 Dundy Nebraska 2.6 3132
46069 Hyde South Dakota 2.8 3130

For both lists, census ID breaks ordering ties so that each table contains exactly ten rows. This does not change the assigned ranks. The highest carpool percentage is 29.9%, while the lowest is 0%.

10d. Best state by average county rank

state_carpool <- counties %>% group_by(state) %>%
  summarise(mean_carpool_rank = mean(carpool_rank),
            mean_carpool = mean(carpool), .groups = "drop") %>%
  arrange(mean_carpool_rank, state)
result <- state_carpool %>% slice_head(n = 1)
knitr::kable(result, digits = 4)
state mean_carpool_rank mean_carpool
Hawaii 651.25 12.75

Hawaii has the best average county rank, 651.25. A smaller average rank indicates better placement. This result uses four retained Hawaii counties after the missing-value removal.

10e. Top five states

result <- state_carpool %>% slice_head(n = 5)
knitr::kable(result, digits = 4)
state mean_carpool_rank mean_carpool
Hawaii 651.250 12.7500
Arizona 970.400 11.5600
Utah 1018.931 11.8655
Arkansas 1054.307 11.9013
Alaska 1086.379 12.1345

Using average county rank, the top five states are Hawaii, Arizona, Utah, Arkansas, and Alaska. I used the same definition as in 10d. The mean carpool percentages are included for context, but the ordering is based on average rank. Each county has equal weight, so these results do not represent the share of all commuters in each state who carpool.