I wanted to look at COVID data for the state of Iowa and drill down to the county level to see if there are any disparities between cases per 100,000 population and deaths per 100,000 population.

It is important to note which counties don’t have a lot of cases but do have a lot of deaths, relatively speaking. Since many guidelines and practices were established at the local level, it is reasonable to expect differences in outcomes across the counties. It would be beneficial to see if there are any counties who do have a lot of cases but not a lot of deaths, relatively speaking. So I created a column that has ratio of cases to deaths. Low numbers signify counties that had/have a lot of deaths relative to their number of cases. Conversely, high numbers indicate the counties had/have fewer deaths relative to their number of cases. (I wanted to conditionally format the top 10% and bottom 10% but failed to get it to work.)

I chose to look at the first quarters of 2021 and 2022, as the winter months seemed to be most intense in terms of COVID. I thought I would be able to just sum the 1-day counts for cases and deaths for each county during the time period, but it turns out the numbers repeated for every latitude and longitude combination. In other words, the numbers were inflated. If a county had 17 different latitude-longitude pairs, then their county sums were 17 times the actual cases and deaths. Being new to R, I ultimately learned about the slice() function and finally straightened out this particular problem.

# get code from the class github to download covid data

rm(list=ls())
library(tidyverse)
library(tidycensus)

# download data

covid.state <- read_csv("https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-states.csv")
covid.state2 <- covid.state %>%
  arrange(state,date) %>%
  group_by(state) %>%
  mutate(cases.1day  = cases  - lag(cases,1),
         deaths.1day = deaths - lag(deaths,1),
         cases.7day  = zoo::rollmean(cases.1day, 7, fill=NA, align="right"),
         deaths.7day = zoo::rollmean(deaths.1day, 7, fill=NA, align="right"),
         cases.14day  = zoo::rollmean(cases.1day, 14, fill=NA, align="right"),
         deaths.14day = zoo::rollmean(deaths.1day, 14, fill=NA, align="right"))
# head(covid.state2, n=20)

covid.county <- read_csv("https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv")
covid.county2 <- covid.county %>%
  arrange(state,county,date) %>%
  group_by(county) %>%
  mutate(cases.1day  = cases  - lag(cases,1),
         deaths.1day = deaths - lag(deaths,1),
         cases.7day  = zoo::rollmean(cases.1day, 7, fill=NA, align="right"),
         deaths.7day = zoo::rollmean(deaths.1day, 7, fill=NA, align="right"),
         cases.14day  = zoo::rollmean(cases.1day, 14, fill=NA, align="right"),
         deaths.14day = zoo::rollmean(deaths.1day, 14, fill=NA, align="right"))
# head(covid.county2, n=20)

# get and save api key

apikey <- "123"
census.api.key("123", install=TRUE, overwrite = TRUE)
readRenviron("~/.Renviron")
Sys.getenv("CENSUS.API.KEY")
# get variables and codes (as per github)
View(sf1)

sf1 <- load_variables(2010, "sf1", cache = TRUE)
head(sf1)

# get population data

state.pop <- get_decennial(geography = "state", 
                           variables = "P001001", 
                           year = 2010)
# head(state.pop)



county.pop <- get_decennial(geography = "county", 
                           variables = "P001001", 
                           year = 2010)
# head(county.pop)


# merge population and covid data
# state.pop <- state.pop %>% select(fips=GEOID, pop2010=value)
names(state.pop)[names(state.pop) == "GEOID"] <- "fips"
names(state.pop)[names(state.pop) == "value"] <- "pop2010"
# head(state.pop)

# county.pop2 <- county.pop %>% select(fips=GEOID, pop2010=value)
names(county.pop)[names(county.pop) == "GEOID"] <- "fips"
names(county.pop)[names(county.pop) == "value"] <- "pop2010"
# head(county.pop)

# normalize state cases
covid.state3 <- covid.state %>% 
  left_join(state.pop, by="fips") %>%
  mutate(cases.per1k = 1000*cases / pop2010,
         deaths.per1k = 1000*deaths / pop2010,
         cases.1day.per100k = 100000*cases.1day/pop2010,
         deaths.1day.per100k = 100000*deaths.1day/pop2010,
         cases.7day.per100k = 100000*cases.7day/pop2010,
         deaths.7day.per100k = 100000*deaths.7day/pop2010,
         cases.14day.per100k = 100000*cases.14day/pop2010,
         deaths.14day.per100k = 100000*deaths.14day/pop2010)
save(covid.state3, file="covid.state3.rda")
# dim(covid.state3)

# normalize county cases
covid.county3 <- covid.county2 %>% 
  left_join(county.pop, by="fips") %>%
  mutate(cases.per1k = 1000*cases / pop2010,
         deaths.per1k = 1000*deaths / pop2010,
         cases.1day.per100k = 100000*cases.1day/pop2010,
         deaths.1day.per100k = 100000*deaths.1day/pop2010,
         cases.7day.per100k = 100000*cases.7day/pop2010,
         deaths.7day.per100k = 100000*deaths.7day/pop2010,
         cases.14day.per100k = 100000*cases.14day/pop2010,
         deaths.14day.per100k = 100000*deaths.14day/pop2010)
save(covid.county3, file="covid.county3.rda")
# dim(covid.county3)
load(file = 'covid.state3.rda')
load(file = 'covid.county3.rda')

# get longitude and latitudes for the U.S.
us.counties.covid <- map_data("county") %>%
  mutate(region = str_to_title(region),
         subregion = str_to_title(subregion)) %>%
  left_join(covid.county3 %>%
              filter(date == max(date)),
            by = c("region" = "state", "subregion" = "county"))
us.counties.covid.21q1 <- map_data("county") %>%
  mutate(region = str_to_title(region),
         subregion = str_to_title(subregion)) %>%
  left_join(covid.county3 %>%
              filter(between(date, as.Date('2020-12-31'), as.Date('2021-03-31'))),
            by = c("region" = "state", "subregion" = "county"))
us.counties.covid.22q1 <- map_data("county") %>%
  mutate(region = str_to_title(region),
         subregion = str_to_title(subregion)) %>%
  left_join(covid.county3 %>%
              filter(between(date, as.Date('2021-12-31'), as.Date('2022-03-31'))),
            by = c("region" = "state", "subregion" = "county"))

# subset for the state of Iowa
iowa.counties.covid <- us.counties.covid %>%
  dplyr::select(date, region, subregion, pop2010, cases, cases.1day, deaths, deaths.1day) %>%
  filter(region == "Iowa")
iowa.counties.covid.21q1 <- us.counties.covid.21q1 %>%
  dplyr::select(date, region, subregion, pop2010, cases, cases.1day, deaths, deaths.1day) %>%
  filter(region == "Iowa")
iowa.counties.covid.22q1 <- us.counties.covid.22q1 %>%
  dplyr::select(date, region, subregion, pop2010, cases, cases.1day, deaths, deaths.1day) %>%
  filter(region == "Iowa")
cases.iowa.counties.21q1 <- iowa.counties.covid.21q1 %>%
  drop_na() %>%
  group_by(subregion) %>%
  slice(c(1, n())) %>%
  mutate(cases.q1 = (cases - lag(cases, default = first(cases))),
         deaths.q1 = (deaths - lag(deaths, default = first(deaths))),
         cases.per100k = 100000*cases.q1 / pop2010,
         deaths.per100k = 100000*deaths.q1 / pop2010,
         deaths.div.cases = deaths.q1 / cases.q1,
         deaths.div.cases.per100k = deaths.per100k / cases.per100k,
         cases.div.deaths = cases.q1 / deaths.q1,
         cases.div.deaths.per100k = cases.per100k / deaths.per100k,
         plot.cases = NA,
         plot.deaths = NA) %>%
  slice(n()) %>%
  ungroup() %>%
  as.data.frame()
  
cases.iowa.counties.22q1 <- iowa.counties.covid.22q1 %>%
  drop_na() %>%
  group_by(subregion) %>%
  slice(c(1, n())) %>%
  mutate(cases.q1 = (cases - lag(cases, default = first(cases))),
         deaths.q1 = (deaths - lag(deaths, default = first(deaths))),
         cases.per100k = 100000*cases.q1 / pop2010,
         deaths.per100k = 100000*deaths.q1 / pop2010,
         # plot.cases = NA,
         # plot.deaths = NA,
         deaths.div.cases = deaths.q1 / cases.q1,
         deaths.div.cases.per100k = deaths.per100k / cases.per100k,
         cases.div.deaths = cases.q1 / deaths.q1,
         cases.div.deaths.per100k = cases.per100k / deaths.per100k) %>%
  slice(n()) %>%
  ungroup() %>%
  as.data.frame()
# sparkline(0)

table.21q1 <- cases.iowa.counties.21q1 %>%
  dplyr::select(subregion, pop2010, cases.q1, cases.per100k, deaths.q1, deaths.per100k, cases.div.deaths) %>%
  kbl(col.names = c("County",
                    "Population",
                    "Cases for 1st quarter",
                    "Cases per 100k",
                    "Deaths for 1st quarter",
                    "Deaths per 100k",
                    "Cases by Deaths"),
      align = c("r","r","r","r","r","r","r"),
      digits = 0,
      caption = "Iowa County COVID data for Quarter 1, 2021") %>%
#  add_header_above(c(" ", " ", " ", " ", " ", " ", " ", "per 100k" = 3, " ", " ", " ", "per 100k" = 3, " ", "per 100k", = 3,)) %>%
  kable_styling(font_size = 18, fixed_thead = TRUE) %>%
  scroll_box(width = "100%", height = "700px") %>%
#  kable_material(lightable_options = c("striped", "hover"))
  kable_paper(lightable_options = "hover", full_width = FALSE)
#  kable_classic(full_width = FALSE, html_font = "helvetica")
table.21q1
Iowa County COVID data for Quarter 1, 2021
County Population Cases for 1st quarter Cases per 100k Deaths for 1st quarter Deaths per 100k Cases by Deaths
Adair 7682 231 3007 15 195 15
Adams 4029 54 1340 2 50 27
Allamakee 14330 306 2135 24 167 13
Appanoose 12887 282 2188 11 85 26
Audubon 6119 107 1749 2 33 54
Benton 26076 495 1898 17 65 29
Black Hawk 131090 2506 1912 83 63 30
Boone 26306 613 2330 16 61 38
Bremer 24276 498 2051 13 54 38
Buchanan 20958 402 1918 15 72 27
Buena Vista 20260 472 2330 13 64 36
Butler 14867 334 2247 11 74 30
Calhoun 9670 151 1562 2 21 76
Carroll 20816 350 1681 19 91 18
Cass 13956 287 2056 16 115 18
Cedar 18499 393 2124 5 27 79
Cerro Gordo 44151 785 1778 23 52 34
Cherokee 12072 312 2584 15 124 21
Chickasaw 12439 174 1399 4 32 44
Clarke 9286 288 3101 17 183 17
Clay 16667 477 2862 13 78 37
Clayton 18129 239 1318 9 50 27
Clinton 49116 1067 2172 32 65 33
Crawford 17096 465 2720 15 88 31
Dallas 66135 2745 4151 29 44 95
Davis 8753 149 1702 4 46 37
Decatur 8457 154 1821 6 71 26
Delaware 17764 317 1785 10 56 32
Des Moines 40325 820 2033 30 74 27
Dickinson 16667 555 3330 22 132 25
Dubuque 93653 2136 2281 65 69 33
Emmet 10302 217 2106 16 155 14
Fayette 20880 416 1992 20 96 21
Floyd 16303 244 1497 7 43 35
Franklin 10680 210 1966 4 37 52
Fremont 7441 122 1640 5 67 24
Greene 9336 105 1125 3 32 35
Grundy 12453 249 2000 14 112 18
Guthrie 10954 202 1844 5 46 40
Hamilton 15673 275 1755 22 140 12
Hancock 11341 229 2019 9 79 25
Hardin 17534 305 1739 14 80 22
Harrison 14928 266 1782 18 121 15
Henry 20145 355 1762 10 50 36
Howard 9566 311 3251 5 52 62
Humboldt 9815 192 1956 8 82 24
Ida 7089 181 2553 4 56 45
Iowa 16355 301 1840 2 12 150
Jackson 19848 371 1869 13 65 29
Jasper 36842 1166 3165 16 43 73
Jefferson 16843 271 1609 15 89 18
Johnson 130882 2414 1844 32 24 75
Jones 20638 311 1507 7 34 44
Keokuk 10511 145 1380 5 48 29
Kossuth 15543 521 3352 26 167 20
Lee 35862 778 2169 31 86 25
Linn 211226 3304 1564 80 38 41
Louisa 11387 177 1554 24 211 7
Lucas 8898 171 1922 15 169 11
Lyon 11581 248 2141 16 138 16
Madison 15679 533 3399 11 70 48
Mahaska 22381 455 2033 15 67 30
Marion 33309 796 2390 27 81 29
Marshall 40648 720 1771 17 42 42
Mills 15059 271 1800 5 33 54
Mitchell 10776 203 1884 11 102 18
Monona 9243 250 2705 14 151 18
Monroe 7970 247 3099 11 138 22
Montgomery 10740 220 2048 21 196 10
Muscatine 42745 875 2047 21 49 42
Osceola 6462 105 1625 8 124 13
Page 15932 500 3138 6 38 83
Palo Alto 9421 264 2802 14 149 19
Plymouth 24986 500 2001 28 112 18
Pocahontas 7310 106 1450 7 96 15
Polk 430640 13068 3035 171 40 76
Pottawattamie 93158 2051 2202 59 63 35
Poweshiek 18914 308 1628 8 42 38
Ringgold 5131 164 3196 15 292 11
Sac 10350 200 1932 5 48 40
Scott 165224 3953 2393 74 45 53
Shelby 12167 290 2383 10 82 29
Sioux 33704 615 1825 25 74 25
Story 89542 2066 2307 15 17 138
Tama 17767 295 1660 13 73 23
Taylor 6317 99 1567 3 47 33
Union 12534 196 1564 13 104 15
Van Buren 7570 92 1215 7 92 13
Wapello 35625 1086 3048 26 73 42
Warren 46225 1578 3414 46 100 34
Washington 21704 565 2603 21 97 27
Wayne 6403 134 2093 2 31 67
Webster 38013 594 1563 25 66 24
Winnebago 10866 240 2209 3 28 80
Winneshiek 21056 514 2441 14 66 37
Woodbury 102172 2260 2212 50 49 45
Worth 7598 158 2079 5 66 32
Wright 13229 239 1807 17 129 14
table.22q1 <- cases.iowa.counties.22q1 %>%
  dplyr::select(subregion, pop2010, cases.q1, cases.per100k, deaths.q1, deaths.per100k, cases.div.deaths) %>%
  kbl(col.names = c("County",
                    "Population",
                    "Cases for 1st quarter",
                    "Cases per 100k",
                    "Deaths for 1st quarter",
                    "Deaths per 100k",
                    "Cases by Deaths"),
      align = c("r","r","r","r","r","r","r"),
      digits = 0,
      caption = "Iowa County COVID data for Quarter 1, 2022") %>%
#  add_header_above(c(" ", " ", " ", " ", " ", " ", " ", "per 100k" = 3, " ", " ", " ", "per 100k" = 3, " ", "per 100k", = 3,)) %>%
  kable_styling(font_size = 18, fixed_thead = TRUE) %>%
  scroll_box(width = "100%", height = "700px") %>%
#  kable_material(lightable_options = c("striped", "hover"))
  kable_paper(lightable_options = "hover", full_width = FALSE)
#  kable_classic(full_width = FALSE, html_font = "helvetica")
table.22q1
Iowa County COVID data for Quarter 1, 2022
County Population Cases for 1st quarter Cases per 100k Deaths for 1st quarter Deaths per 100k Cases by Deaths
Adair 7682 253 3293 7 91 36
Adams 4029 177 4393 2 50 88
Allamakee 14330 541 3775 2 14 270
Appanoose 12887 613 4757 9 70 68
Audubon 6119 253 4135 2 33 126
Benton 26076 1380 5292 14 54 99
Black Hawk 131090 8335 6358 70 53 119
Boone 26306 1128 4288 10 38 113
Bremer 24276 1112 4581 8 33 139
Buchanan 20958 1050 5010 13 62 81
Buena Vista 20260 1260 6219 8 39 158
Butler 14867 641 4312 5 34 128
Calhoun 9670 491 5078 4 41 123
Carroll 20816 1012 4862 8 38 126
Cass 13956 466 3339 5 36 93
Cedar 18499 1140 6162 8 43 142
Cerro Gordo 44151 2216 5019 30 68 74
Cherokee 12072 636 5268 11 91 58
Chickasaw 12439 599 4815 8 64 75
Clarke 9286 477 5137 6 65 80
Clay 16667 968 5808 5 30 194
Clayton 18129 673 3712 8 44 84
Clinton 49116 2492 5074 22 45 113
Crawford 17096 791 4627 5 29 158
Dallas 66135 6048 9145 22 33 275
Davis 8753 236 2696 6 69 39
Decatur 8457 355 4198 9 106 39
Delaware 17764 706 3974 7 39 101
Des Moines 40325 1638 4062 26 64 63
Dickinson 16667 742 4452 12 72 62
Dubuque 93653 5251 5607 31 33 169
Emmet 10302 408 3960 4 39 102
Fayette 20880 929 4449 15 72 62
Floyd 16303 758 4649 8 49 95
Franklin 10680 512 4794 8 75 64
Fremont 7441 309 4153 8 108 39
Greene 9336 361 3867 3 32 120
Grundy 12453 551 4425 5 40 110
Guthrie 10954 513 4683 5 46 103
Hamilton 15673 701 4473 12 77 58
Hancock 11341 446 3933 5 44 89
Hardin 17534 956 5452 7 40 137
Harrison 14928 744 4984 11 74 68
Henry 20145 1059 5257 16 79 66
Howard 9566 379 3962 11 115 34
Humboldt 9815 500 5094 5 51 100
Ida 7089 365 5149 6 85 61
Iowa 16355 1067 6524 14 86 76
Jackson 19848 895 4509 16 81 56
Jasper 36842 1783 4840 17 46 105
Jefferson 16843 912 5415 7 42 130
Johnson 130882 11576 8845 34 26 340
Jones 20638 1006 4875 5 24 201
Keokuk 10511 412 3920 6 57 69
Kossuth 15543 542 3487 8 51 68
Lee 35862 1453 4052 33 92 44
Linn 211226 14788 7001 131 62 113
Louisa 11387 484 4250 8 70 60
Lucas 8898 382 4293 3 34 127
Lyon 11581 496 4283 6 52 83
Madison 15679 588 3750 14 89 42
Mahaska 22381 855 3820 18 80 48
Marion 33309 1442 4329 19 57 76
Marshall 40648 2248 5530 16 39 140
Mills 15059 846 5618 12 80 70
Mitchell 10776 482 4473 3 28 161
Monona 9243 378 4090 8 87 47
Monroe 7970 333 4178 6 75 56
Montgomery 10740 495 4609 5 47 99
Muscatine 42745 2307 5397 12 28 192
Osceola 6462 269 4163 4 62 67
Page 15932 442 2774 7 44 63
Palo Alto 9421 399 4235 6 64 66
Plymouth 24986 1121 4487 10 40 112
Pocahontas 7310 302 4131 2 27 151
Polk 430640 35443 8230 228 53 155
Pottawattamie 93158 6559 7041 65 70 101
Poweshiek 18914 901 4764 14 74 64
Ringgold 5131 262 5106 2 39 131
Sac 10350 534 5159 5 48 107
Scott 165224 10118 6124 79 48 128
Shelby 12167 534 4389 7 58 76
Sioux 33704 1463 4341 8 24 183
Story 89542 4953 5531 23 26 215
Tama 17767 789 4441 10 56 79
Taylor 6317 246 3894 1 16 246
Union 12534 509 4061 5 40 102
Van Buren 7570 304 4016 3 40 101
Wapello 35625 1855 5207 41 115 45
Warren 46225 3100 6706 23 50 135
Washington 21704 1302 5999 9 41 145
Wayne 6403 290 4529 7 109 41
Webster 38013 2228 5861 34 89 66
Winnebago 10866 516 4749 5 46 103
Winneshiek 21056 792 3761 4 19 198
Woodbury 102172 6951 6803 53 52 131
Worth 7598 425 5594 6 79 71
Wright 13229 686 5186 9 68 76