Hackathon: 2020 Election and State Health Policy

This analysis examines the connection between state political leaning, vaccinations, and health policy in combatting the Covid-19 pandemic.

My research found that states who favored Joe Biden in the 2020 election have higher rates of vaccinations (one dose) and more restrictive regulations intended to curb the spread of infection. Specifically, states who voted for Joe Biden are more likely to limit large gatherings and restaurant capacity, while enforcing mask mandates. Additionally they are more likely to be currently easing restrictions rather than be fully re-opened.

I use datasets from a Hackathon on state health policy, CDC vaccination records from March 31, 2021, and electoral college results from archives.gov.

First I read in my datasets and perform some cleaning operations in the code chunks below:

library(tidyverse)
library(geojsonio)
library(readxl)
library(leaflet)
library(rgdal)
library(stargazer)

# spatial polygon of states
states <- readOGR("cb_2016_us_state_500k", layer = "cb_2016_us_state_500k", encoding = "UTF-8")

#read in data, select relevant rows and columns
election <- read_excel("2020_Election.xlsx")
state_rules <- read.csv("social-distancing-actions-state-2021.csv")%>%
  select(-Footnotes)
vaccines <- read.csv("CDC_Vaccinations_3.31.21.csv") %>%
  select(1,2,3,5,6,9,10,13,14)

#merged all the datasets besides the geospatial
merged <- left_join(election,vaccines,by=c("State" = "State.Territory.Federal.Entity"))%>%
  merge(., state_rules, by.x = 1, by.y = 1, all.x = T, all.y = F)
#converting vaccines factors to numeric
merged$Doses_Delivered_per_100K <- as.numeric(merged$Doses_Delivered_per_100K)
merged$Doses_Administered_per_100k <- as.numeric(merged$Doses_Administered_per_100k)
merged$Percent_at_least_One_Dose <- as.numeric(merged$Percent_at_least_One_Dose)
merged$Percent_of_Total_Pop_Fully_Vaccinated <- as.numeric(merged$Percent_of_Total_Pop_Fully_Vaccinated)

#making democrat numeric for glms
merged$democrat <- ifelse(merged$Winner == "Democrat",1,0)
merged$republican <- ifelse(merged$Winner == "Republican",1,0)

#recode these since they're the same
merged$Large.Gatherings.Ban <- merged$Large.Gatherings.Ban %>%
  recode(.,"Limit > 50" = ">50 Prohibited",.default = levels(merged))

#re-leveling factors
merged$Large.Gatherings.Ban <- factor(merged$Large.Gatherings.Ban, 
                                      levels = c("No Limit", ">50 Prohibited",
                                                 ">25 Prohibited", ">10 Prohibited",
                                                 "All Gatherings Prohibited"))

merged$Status.of.Reopening <- factor(merged$Status.of.Reopening,
                                     levels = c("Reopened","Easing Restrictions",
                                                "Paused","New Restrictions Imposed"))

#checking levels
levels(merged$Status.of.Reopening)
levels(merged$Large.Gatherings.Ban)
levels(merged$Non.Essential.Business.Closures)
levels(merged$Statewide.Face.Mask.Requirement)
levels(merged$Restaurant.Limits)

#geospatial merge

states@data <- data.frame(states@data, merged[match(states@data$NAME, merged$State),])

Linear Modeling

#democratand percent of pop vaccinated
model1 <- glm(democrat ~ Percent_of_Total_Pop_Fully_Vaccinated,
             data = merged, family = binomial(link = 'logit'))
summary(model1)
#not statistically significant

#small correlation between democrat winning states and total pop vax
cor(merged$democrat, merged$Percent_of_Total_Pop_Fully_Vaccinated,use="complete.obs")
#this is much higher, 43%
cor(merged$democrat, merged$Percent_at_least_One_Dose,use="complete.obs")


model2 <- glm(democrat ~ Percent_at_least_One_Dose,
              data = merged, family = binomial(link = 'logit'))
summary(model2)


#Now lets look at state restrictions!

#All these vars are significant and imply 2-4x more likelihood of voting Dem in 2020
#than states with no large gatherings banned
model3 <- glm(democrat ~ Large.Gatherings.Ban,
              data = merged, family = binomial(link = 'logit'))
summary(model3)

model3b <- lm(Percent_at_least_One_Dose ~ Large.Gatherings.Ban,
              data = merged)
summary(model3b)

#states who are currently easing restrictions are 3x more likely to have voted for Biden
#than states who are fully reopened
model4<- glm(democrat ~ Status.of.Reopening,
             data = merged, family = binomial(link='logit'))
summary(model4)

#no relationship between vaccination and state reopening
model4b <- lm(Percent_at_least_One_Dose ~ Status.of.Reopening,
              data=merged)
summary(model4b)

#states with a mask mandate are 2.8x more likely than states with no mask mandate to
#have voted for Joe Biden
model5 <- glm(democrat ~ Statewide.Face.Mask.Requirement, 
              data = merged, family = binomial(link='logit'))
summary(model5)

#no relationship between vaccination rates and face mask requirements
model5b <- lm(Percent_at_least_One_Dose ~ Statewide.Face.Mask.Requirement,
              data=merged)
summary(model5b)

#states whose restaurants currently have service limits are 2.6x more likely than state with
#fully opened restaurants to have voted for Joe Biden
model6 <- glm(democrat ~ Restaurant.Limits, 
              data = merged, family = binomial(link='logit'))
summary(model6)

#states whose restaurants have restrictions have 7% more of their pop vaccinated, on avg,
#than states whose restaurants are fully open
model6b <- lm(Percent_at_least_One_Dose ~ Restaurant.Limits,
              data=merged)
summary(model6b)

The following models were developed to assess whether there was a realtionship between 2020 election results and state health policy in response to the Covid-19 pandemic. Model 2 shows a statistically significant relationship between states that voted for Joe Biden and the percent of residents receiving one vaccination. Fully vaccinated residents was not statistically significant.

I also ran a correlation between states who voted Democrat and these two vaccination statistics from the CDC and found that percent with one shot had an R^2 of 0.43 whereas percent with both shots was only 0.20. Therefore I used Percent_at_least_One_Dose in my future models.

#these will only show in an RMD, knitted to html
stargazer(model1,model2, type = 'html', align=TRUE, single.row=TRUE,report="vc*",se=NULL,digits=2, dep.var.caption = "",title = "Democrat and Percent Vaccinated", 
          column.labels=c("Fully Vaccinated","Partially Vaccinated"))
Democrat and Percent Vaccinated
democrat
Fully Vaccinated Partially Vaccinated
(1) (2)
Percent_of_Total_Pop_Fully_Vaccinated 0.03
Percent_at_least_One_Dose 0.08***
Constant -0.79 -2.18***
Observations 50 50
Log Likelihood -33.68 -29.54
Akaike Inf. Crit. 71.35 63.07
Note: p<0.1; p<0.05; p<0.01


The following models use a logistic regression analysis, evaluating the likelihood of voting democrat, or for Joe Biden, by each state based on current state health policy.

Model 1 examines regulations for large gatherings. These levels were statistically significant and show an escalating likelihood of voting democrat as state regulations get stricter. For example, states that ban large gatherings >10 people were 4x more likely than states with no gathering restrictions to vote for Joe Biden in 2020. Only one state has banned all gatherings; it is statisticaly insignificant.

Model 2 shows that states who are currently easing restrictions were 3x more likely than states who have no restrictions to vote Democrat in 2020.

Model 3 reveals that states with a mask mandate were 3x more likely to vote Democrat than states with no mask mandate.

Finally, Model 4 found that states with restrictions on restaurants were 2.66x more likely than states with no restrictions to have voted Democrat.

These results prove that the political majority of a state has a large impact on how the state is governed. Democrat-leaning states are more likely to take proactive and restrictive measures to curb the Covid-19 pandemic than states whose populace favored Donald Trump in the 2020 national election.

Note that this excludes the partisanship of the governor and state congress. However, this shows a relatonship between the ideology of a states’ residents re: federal elections and the response of state lawmakers to the pandemic.

stargazer(model3,model4,model5,model6, type = 'html', align=TRUE, single.row=TRUE, report="vc*",se=NULL,digits=2, dep.var.caption = "",title = "Democrat and State Health Policy", 
          column.labels=c("Large Gatherings", "Reopening","Mask Mandate",
                          "Restaurant"))
Democrat and State Health Policy
democrat
Large Gatherings Reopening Mask Mandate Restaurant
(1) (2) (3) (4)
Large.Gatherings.Ban> 50 Prohibited 2.25**
Large.Gatherings.Ban> 25 Prohibited 2.94**
Large.Gatherings.Ban> 10 Prohibited 4.41***
Large.Gatherings.BanAll Gatherings Prohibited 18.41
Status.of.ReopeningEasing Restrictions 3.05***
Status.of.ReopeningPaused 19.41
Status.of.ReopeningNew Restrictions Imposed 19.41
Statewide.Face.Mask.RequirementYes 2.89***
Restaurant.LimitsOpen with Service Limits 2.66***
Constant -1.85*** -1.85*** -2.01*** -1.10**
Observations 51 51 51 51
Log Likelihood -21.34 -22.81 -26.75 -26.37
Akaike Inf. Crit. 52.69 53.62 57.51 56.74
Note: p<0.1; p<0.05; p<0.01


To double-check my previous analysis, I ran the same state health policy variables in relation to a state’s progress on vaccination. We already know there is a small positive relationship between vaccination rates and states who voted for Joe Biden. It’s possible that health policy could be dictated by vaccination rates.

However, these models showed a much weaker relationship. Only one model contained a variable with statistical signifigance at p<0.05. States with restaurant regulations showed a 7.85% higher vaccination rate than states without any restaurant restrictions. Clearly there is little health rationale for easing restrictions in terms of vaccinations.

stargazer(model3b,model4b,model5b,model6b, type = 'html', align=TRUE, single.row=TRUE, report="vc*",se=NULL,digits=2, dep.var.caption = "",title = "Vaccination and State Health Policy", 
          column.labels=c("Large Gatherings", "Reopening","Mask Mandate",
                          "Restaurant"))
Vaccination and State Health Policy
Percent_at_least_One_Dose
Large Gatherings Reopening Mask Mandate Restaurant
(1) (2) (3) (4)
Large.Gatherings.Ban> 50 Prohibited -1.56
Large.Gatherings.Ban> 25 Prohibited 9.64
Large.Gatherings.Ban> 10 Prohibited 7.83*
Large.Gatherings.BanAll Gatherings Prohibited 19.14
Status.of.ReopeningEasing Restrictions 6.52*
Status.of.ReopeningPaused -6.86
Status.of.ReopeningNew Restrictions Imposed 19.64
Statewide.Face.Mask.RequirementYes 6.56*
Restaurant.LimitsOpen with Service Limits 7.85**
Constant 23.86*** 23.36*** 22.41*** 23.29***
Observations 50 50 50 50
R2 0.15 0.13 0.06 0.10
Adjusted R2 0.07 0.07 0.04 0.08
Residual Std. Error 12.05 (df = 45) 12.07 (df = 46) 12.24 (df = 48) 12.01 (df = 48)
F Statistic 1.97 (df = 4; 45) 2.22* (df = 3; 46) 3.22* (df = 1; 48) 5.27** (df = 1; 48)
Note: p<0.1; p<0.05; p<0.01

Data Visulization

Lastly I wanted to visualize some of these models. The first map shows the 2020 electoral college results. Map 2 shows statewide mask mandates in the United States. Map 3 shows the restrictions on large gatherings by state. Visually, it appears that Republican-leaning states in the south and Great Plains have milder restrictions than the coastal Democrat states in the Northeast and West.

Map 1: Electoral College Results 2020

#popup
election_popup <- paste("<strong>Party: </strong>", 
                     states@data$Winner, 
                     "<br>State:", 
                     states@data$NAME)

# Choosing a color scheme
factpal <- colorFactor(c("#0000FF", "#FF0000"),
                       states@data$Winner)

# Election Results
leaflet(states) %>% 
  fitBounds(-124, 34, -62, 40) %>%
  addProviderTiles("CartoDB.Positron") %>%
  addPolygons(stroke = TRUE, 
              smoothFactor = 0.2, 
              fillOpacity = .8,
              color = ~factpal(Winner),
              weight = 1, 
              popup = election_popup) %>%
  addLegend("bottomright", 
            colors = c("#0000FF", "#FF0000"),
            labels = c("Democrat", "Republican"),  
            title = "2020 Election",
            opacity = 1) 

Map 2: State Mask Mandates

#popup
mask_popup <- paste("<strong>Mask Required: </strong>", 
                        states@data$Statewide.Face.Mask.Requirement, 
                        "<br>State:", 
                        states@data$NAME)

# Choosing a color scheme
factpal2 <- colorFactor(c("#f03b20", "#31a354"),
                       states@data$Statewide.Face.Mask.Requirement)

# Election Results
leaflet(states) %>% 
  fitBounds(-124, 34, -62, 40) %>%
  addProviderTiles("CartoDB.Positron") %>%
  addPolygons(stroke = TRUE, 
              smoothFactor = 0.2, 
              fillOpacity = .8,
              color = ~factpal2(Statewide.Face.Mask.Requirement),
              weight = 1, 
              popup = mask_popup) %>%
  addLegend("bottomright", 
            colors = c("#f03b20", "#31a354"),
            labels = c("Mask Not Required", "Mask Required"),  
            title = "State Mask Mandate",
            opacity = 1)

Map 3: State Large Gathering Restrictions

#popup
gatherings_popup <- paste("<strong>Large Gatherings: </strong>", 
                    states@data$Large.Gatherings.Ban, 
                    "<br>State:", 
                    states@data$NAME)

# Choosing a color scheme
factpal3 <- colorFactor(c("#2b83ba","#abdda4","#ffffbf","#fdae61","#d7191c"),
                        states@data$Large.Gatherings.Ban)

# Election Results
leaflet(states) %>% 
  fitBounds(-124, 34, -62, 40) %>%
  addProviderTiles("CartoDB.Positron") %>%
  addPolygons(stroke = TRUE, 
              smoothFactor = 0.2, 
              fillOpacity = .8,
              color = ~factpal3(Large.Gatherings.Ban),
              weight = 1, 
              popup = gatherings_popup) %>%
  addLegend("bottomright", 
            colors = c("#2b83ba","#abdda4","#ffffbf","#fdae61","#d7191c"),
            labels = c("No Limit",">50 Prohibited", ">25 Prohibited",
                       ">10 Prohibited","All Gatherings Prohibited"),  
            title = "Large Gatherings Ban",
            opacity = 1) 

Conclusion

Ultimately these results were concerning. This analysis shows that state politics have factored heavily into the pandemic response. The Covid-19 pandemic is not political, however. It is a virus that spreads through the air, surfaces, and large indoor gatherings. In an ideal world, there would be no relationship between the 2020 federal election results and current state health policy. Even more concerning was that states with slower vaccination rates are more likely to re-open businesses at unsafe levels.

One limitation of this analysis was I didn’t examine cases, deaths, and hospitalizations at the state level, which could account for health policy decisions.