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),])
#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 | ||
| 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 | ||||
| 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"))
| 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 | |||
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.
#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)
#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)
#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)
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.