We are using Change Research’s set of survey respondents to explore whether COVID has changed their political alignment or opinions of political figures.

Our two sources of data: 1. Change Research respondents since the third week of 2020 up to last week. 2. JHU CSSE’s timeseries of COVID-19 cases by county for the same time period.

Our potential dependent variables will be explored in more detail later on.

Import Survey Data

We must first extract the survey respondent data. We select some political preferences and demographics per respondent, as well as the population and vote history of the respondent’s county.

This query is not run when the document is rendered because I didn’t want to muck around with ODBC in RStudio.

select
    pd.week,
    pd.state_abbrev,
    pd.county_descr,
    pd.fips_code,
    pd.biden,
    pd.trump,
    pd.clinton_biden,
    pd.trump_trump,
    pd.clinton_trump,
    pd.trump_biden,
    ftb.biden_ft,
    ftt.trump_ft,
    pd.prevtrump,
    pd.prevclinton,
    pd.ethnicity,
    pd.four_yr_degree,
    pd.age,
    pd.male,
    pd.county_clinton,
    pd.county_trump,
    pd.county_trump_margin,
    pd.county_pop
from
(select
    sr.id,
    FROM_UNIXTIME(sr.date_created,'%Y-%U') as week,
    z.state_abbrev,
    cn.county_descr,
    cn.fips_code,
    if(c.text like '%Biden%', 1, 0) as biden,
    if(c.text like '%Trump%', 1, 0) as trump,
    if(sr.president_vote_2016 like '%Clinton%' and c.text like '%Biden%', 1, 0) as clinton_biden,
    if(sr.president_vote_2016 like '%Trump%' and c.text like '%Trump%', 1, 0) as trump_trump,
    if(sr.president_vote_2016 like '%Clinton%' and c.text like '%Trump%', 1, 0) as clinton_trump,
    if(sr.president_vote_2016 like '%Trump%' and c.text like '%Biden%', 1, 0) as trump_biden,
    if(sr.president_vote_2016 like '%Clinton%', 1, 0) as prevclinton,
    if(sr.president_vote_2016 like '%Trump%' , 1, 0) as prevtrump,
    sr.ethnicity,
    2020 - sr.year_born as age,
    sr.education in ('Bachelor\'s degree, or four-year college degree', 'Graduate degree') as four_yr_degree,
    if(sr.gender like 'Male', 1, 0) as male,
    cn.votes_2016_clinton / cn.votes_2016_all as county_clinton,
    cn.votes_2016_trump / cn.votes_2016_all as county_trump,
    (cn.votes_2016_trump - cn.votes_2016_clinton) / cn.votes_2016_all as county_trump_margin,
    pop_2017_18plus as county_pop
from survey_data.survey_responders sr
    join survey_data.surveys s
        on sr.survey_id = s.id
    join survey_data.survey_responses r
        on sr.id = r.survey_responder_id
    join survey_data.survey_questions q
        on q.id = r.survey_question_id
        and q.heading in (
        'If the election for President were held today, who would you vote for?',
        'If the 2020 general election for President were held today and the candidates were the following, who would you vote for?',
        'If the election for President were held today and the candidates were the following, who would you vote for?',
        'If the November election for President were held today, who would you vote for?'
        )
    join survey_data.survey_choices c
        on c.id = r.survey_choice_id
        and c.survey_question_id = q.id
    join (select ZCTA, state_abbrev, association_id from zip_map where association_type = 'county' group by ZCTA) z
        on z.ZCTA = sr.zip_code
    join counties cn
        on z.state_abbrev = cn.state_abbrev
        and z.association_id = cn.county_code
where sr.date_created > UNIX_TIMESTAMP(20191231)) as pd
join (select
                  sr.id,
                  c.text as biden_ft
from survey_data.survey_responders sr
    join survey_data.surveys s
        on sr.survey_id = s.id
    join survey_data.survey_responses r
        on sr.id = r.survey_responder_id
    join survey_data.survey_questions q
        on q.id = r.survey_question_id
        and q.heading in (
        'On a scale of 1-10, how do you feel about Joe Biden? 1 means you strongly oppose him and 10 means you strongly support him.'
        )
    join survey_data.survey_choices c
        on c.id = r.survey_choice_id
        and c.survey_question_id = q.id
where sr.date_created > UNIX_TIMESTAMP(20191231)
) ftb on pd.id = ftb.id
join (select
             sr.id,
             c.text as trump_ft
from survey_data.survey_responders sr
    join survey_data.surveys s
        on sr.survey_id = s.id
    join survey_data.survey_responses r
        on sr.id = r.survey_responder_id
    join survey_data.survey_questions q
        on q.id = r.survey_question_id
        and q.heading in (
        'On a scale of 1-10, how do you feel about President Donald Trump? 1 means you strongly oppose him and 10 means you strongly support him.'
        )
    join survey_data.survey_choices c
        on c.id = r.survey_choice_id
        and c.survey_question_id = q.id
where sr.date_created > UNIX_TIMESTAMP(20191231)
) ftt on pd.id = ftt.id

A CSV is saved from DataGrip; we import it here.

survey <- read.csv("respondents.csv")

dim(survey)
## [1] 130829     22

Importing and Manipulating COVID Data

We download the latest data from the JHU CSSE’s GitHub. We make a long table, calculate the delta in cases, and summarize by county and week.

cwo <-
  read.csv(
    "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_US.csv"
  )
cwn <- cbind(
  FIPS = cwo$FIPS, 
  cwo[, grep("X(0-9)*", names(cwo))[-1]] - cwo[, grep("X(0-9)*", names(cwo))[-1] - 1]
  )
clo <- pivot_longer(cwo, starts_with("X"), names_to = "date", values_to = "total_cases")
cln <- pivot_longer(cwn, starts_with("X"), names_to = "date", values_to = "new_cases")
cl <- merge(clo, cln)
cl$date <- as.Date(cl$date, format = "X%m.%d.%y")
cl <- cl[!is.na(cl$FIPS), ]
cl$new_cases[cl$new_cases < 0] <- 0

cl[["week"]] <- format(cl$date, "%Y-%U")
covid <-
  cl %>% 
  group_by(FIPS, week) %>% 
  summarize(cases = sum(new_cases), .groups = "keep")

dim(covid)
## [1] 143190      3

Join Survey and COVID Data

We merge (by default, a left join) on FIPS code as an integer and week, giving us one row per respondent with weekly COVID-19 case counts for each respondent’s county. We then cacluate the proportional case count by population. Note that this value is scaled by 1000 for interpretability, i.e. to cases per 1000 population.

dta <-
  merge(survey,
        covid,
        by.x = c("fips_code", "week"),
        by.y = c("FIPS", "week"))

dta <- dta[!dta$week %in% c("2020-02", strftime(Sys.Date(), format = "%Y-%U")),]

dta[["weekn"]] <- as.numeric(substr(dta$week, 6, 7))

dta[["propcases"]] <- dta$cases / (dta$county_pop / 1000)

write.csv(dta, file = "respondents_covid.csv")

dim(dta)
## [1] 130829     25
summary(dta)
##    fips_code         week           state_abbrev       county_descr      
##  Min.   : 1001   Length:130829      Length:130829      Length:130829     
##  1st Qu.:13121   Class :character   Class :character   Class :character  
##  Median :35001   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :29212                                                           
##  3rd Qu.:42043                                                           
##  Max.   :56041                                                           
##                                                                          
##      biden            trump        clinton_biden     trump_trump    
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.0000   Median :0.0000   Median :0.0000  
##  Mean   :0.4496   Mean   :0.4704   Mean   :0.3711   Mean   :0.4133  
##  3rd Qu.:1.0000   3rd Qu.:1.0000   3rd Qu.:1.0000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.0000  
##                                                                     
##  clinton_trump     trump_biden         biden_ft         trump_ft     
##  Min.   :0.0000   Min.   :0.00000   Min.   : 1.000   Min.   : 1.000  
##  1st Qu.:0.0000   1st Qu.:0.00000   1st Qu.: 1.000   1st Qu.: 1.000  
##  Median :0.0000   Median :0.00000   Median : 3.000   Median : 5.000  
##  Mean   :0.0122   Mean   :0.01605   Mean   : 4.617   Mean   : 5.217  
##  3rd Qu.:0.0000   3rd Qu.:0.00000   3rd Qu.: 8.000   3rd Qu.:10.000  
##  Max.   :1.0000   Max.   :1.00000   Max.   :10.000   Max.   :10.000  
##                                                                      
##    prevtrump       prevclinton      ethnicity         four_yr_degree  
##  Min.   :0.0000   Min.   :0.0000   Length:130829      Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.0000   Class :character   1st Qu.:0.0000  
##  Median :0.0000   Median :0.0000   Mode  :character   Median :1.0000  
##  Mean   :0.4503   Mean   :0.3982                      Mean   :0.5038  
##  3rd Qu.:1.0000   3rd Qu.:1.0000                      3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :1.0000                      Max.   :1.0000  
##                                                       NA's   :194     
##       age              male        county_clinton    county_trump   
##  Min.   :  0.00   Min.   :0.0000   Min.   :0.0576   Min.   :0.0409  
##  1st Qu.: 43.00   1st Qu.:0.0000   1st Qu.:0.3773   1st Qu.:0.3927  
##  Median : 56.00   Median :0.0000   Median :0.4655   Median :0.4766  
##  Mean   : 54.03   Mean   :0.4467   Mean   :0.4664   Mean   :0.4785  
##  3rd Qu.: 66.00   3rd Qu.:1.0000   3rd Qu.:0.5423   3rd Qu.:0.5712  
##  Max.   :120.00   Max.   :1.0000   Max.   :0.9086   Max.   :0.9035  
##  NA's   :357                       NA's   :1750     NA's   :1750    
##  county_trump_margin   county_pop          cases           weekn      
##  Min.   :-0.8678     Min.   :    475   Min.   :    0   Min.   :18.00  
##  1st Qu.:-0.1643     1st Qu.: 103613   1st Qu.:   73   1st Qu.:29.00  
##  Median : 0.0143     Median : 314966   Median :  264   Median :36.00  
##  Mean   : 0.0121     Mean   : 681921   Mean   : 1143   Mean   :33.71  
##  3rd Qu.: 0.1933     3rd Qu.: 735904   3rd Qu.:  803   3rd Qu.:39.00  
##  Max.   : 0.8459     Max.   :7832142   Max.   :20828   Max.   :42.00  
##  NA's   :1750                                                         
##    propcases      
##  Min.   : 0.0000  
##  1st Qu.: 0.4526  
##  Median : 0.9298  
##  Mean   : 1.3456  
##  3rd Qu.: 1.6991  
##  Max.   :42.6230  
## 

Note that our data begins in the 18th week of the year, or about mid-April.

Probability of Voting for Each Candidate

We have a set of binary variables to consider as dependent here: 1. Biden 2020 intended vote 2. Trump 2020 intended vote 3. Clinton to Trump switcher 4. Trump to Biden switcher

Since they are binary values between 0 and 1, a logistic regression will yield more helpful coefficients. In a logit model, the predicted y is interpreted as the log-odds of the dependent variable taking on a value of 1 (true), i.e. as a probability.

The second two options for dependent variable more clearly get at our original question of “does COVID affect voter preferences?” but unfortunately suffer from case bias. The overwhelming number of our respondents are NOT switchers. Sampling in equal proportion to achieve balance or matching pairs is a future goal of this project. For now, we proceed to analyze the probability of voting for each candidate as a result of COVID case counts per 1000 population in the respondent’s county.

prop.table(table(dta$clinton_trump))
## 
##          0          1 
## 0.98780087 0.01219913
prop.table(table(dta$trump_biden))
## 
##          0          1 
## 0.98394851 0.01605149

Trump

prop.table(table(dta$trump))
## 
##         0         1 
## 0.5295997 0.4704003
t.m1 <- glm(
  trump ~ propcases,
  data = dta,
  family = binomial(link = "logit")
)
t.m2 <- glm(
  trump ~ propcases + weekn,
  data = dta,
  family = binomial(link = "logit")
)
t.m3 <- glm(
  trump ~ propcases + weekn + male + age + four_yr_degree + ethnicity,
  data = dta,
  family = binomial(link = "logit")
)
t.m4 <- glm(
  trump ~ propcases + weekn + male + age + four_yr_degree + ethnicity + county_trump_margin,
  data = dta,
  family = binomial(link = "logit")
)
t.m5 <- glm(
  trump ~ propcases + weekn + prevtrump + male + age + four_yr_degree + ethnicity + county_trump_margin,
  data = dta,
  family = binomial(link = "logit")
)
t.m6 <- glm(
  trump ~ propcases + weekn + prevtrump + male + age + four_yr_degree + ethnicity,
  data = dta,
  family = binomial(link = "logit")
)


huxreg(t.m1,
       t.m2,
       t.m3,
       t.m4,
       t.m5,
       t.m6,
       statistics = c("nobs", "logLik", "AIC"))
(1)(2)(3)(4)(5)(6)
(Intercept)-0.088 ***-0.133 ***-0.387 *  -0.375 *  -1.463 ***-1.521 ***
(0.008)   (0.030)   (0.152)   (0.155)   (0.249)   (0.248)   
propcases-0.023 ***-0.024 ***-0.003    0.002    -0.016 *  -0.018 ** 
(0.004)   (0.004)   (0.004)   (0.004)   (0.007)   (0.007)   
weekn        0.001    0.003 ** 0.003 ** 0.012 ***0.012 ***
        (0.001)   (0.001)   (0.001)   (0.002)   (0.002)   
male                0.573 ***0.569 ***0.455 ***0.454 ***
                (0.012)   (0.012)   (0.019)   (0.019)   
age                0.009 ***0.009 ***-0.009 ***-0.009 ***
                (0.000)   (0.000)   (0.001)   (0.001)   
four_yr_degree                -0.701 ***-0.664 ***-0.573 ***-0.588 ***
                (0.012)   (0.012)   (0.019)   (0.019)   
ethnicityAmerican Indian or Alaska Native                0.139    0.118    -0.133    -0.083    
                (0.161)   (0.166)   (0.267)   (0.263)   
ethnicityAsian / Pacific Islander                -0.568 ***-0.531 ***-0.440    -0.406    
                (0.154)   (0.158)   (0.253)   (0.252)   
ethnicityBlack or African American                -2.072 ***-2.097 ***-1.267 ***-1.194 ***
                (0.151)   (0.154)   (0.246)   (0.245)   
ethnicityHispanic or Latino/a                -0.408 ** -0.362 *  -0.322    -0.283    
                (0.148)   (0.151)   (0.243)   (0.242)   
ethnicityOther                0.121    0.082    -0.040    0.038    
                (0.149)   (0.153)   (0.246)   (0.244)   
ethnicityWhite / Caucasian                -0.131    -0.189    -0.516 *  -0.430    
                (0.146)   (0.150)   (0.241)   (0.240)   
county_trump_margin                        0.701 ***0.329 ***        
                        (0.023)   (0.038)           
prevtrump                                4.558 ***4.565 ***
                                (0.021)   (0.020)   
nobs130829        130829        130291        128550        128550        130291        
logLik-90436.179    -90434.936    -84429.484    -82849.221    -38851.885    -39433.878    
AIC180876.358    180875.872    168882.967    165724.442    77731.770    78893.756    
*** p < 0.001; ** p < 0.01; * p < 0.05.

Biden

prop.table(table(dta$biden))
## 
##         0         1 
## 0.5503826 0.4496174
b.m1 <- glm(
  biden ~ propcases,
  data = dta,
  family = binomial(link = "logit")
)
b.m2 <- glm(
  biden ~ propcases + weekn,
  data = dta,
  family = binomial(link = "logit")
)
b.m3 <- glm(
  biden ~ propcases + weekn + male + age + four_yr_degree + ethnicity,
  data = dta,
  family = binomial(link = "logit")
)
b.m4 <- glm(
  biden ~ propcases + weekn + male + age + four_yr_degree + ethnicity + county_trump_margin,
  data = dta,
  family = binomial(link = "logit")
)
b.m5 <- glm(
  biden ~ propcases + weekn + prevtrump + male + age + four_yr_degree + ethnicity + county_trump_margin,
  data = dta,
  family = binomial(link = "logit")
)
b.m6 <- glm(
  biden ~ propcases + weekn + prevtrump + male + age + four_yr_degree + ethnicity,
  data = dta,
  family = binomial(link = "logit")
)

huxreg(b.m1,
       b.m2,
       b.m3,
       b.m4,
       b.m5,
       b.m6,
       statistics = c("nobs", "logLik", "AIC"))
(1)(2)(3)(4)(5)(6)
(Intercept)-0.241 ***-0.363 ***-0.957 ***-0.941 ***-1.052 ***-1.082 ***
(0.008)   (0.030)   (0.158)   (0.161)   (0.222)   (0.218)   
propcases0.029 ***0.028 ***0.008 *  0.005    0.029 ***0.028 ***
(0.004)   (0.004)   (0.004)   (0.004)   (0.006)   (0.006)   
weekn        0.004 ***0.003 ** 0.003 ***0.004 *  0.003 *  
        (0.001)   (0.001)   (0.001)   (0.001)   (0.001)   
male                -0.625 ***-0.622 ***-0.547 ***-0.545 ***
                (0.012)   (0.012)   (0.018)   (0.018)   
age                0.001 ***0.001 ***0.026 ***0.026 ***
                (0.000)   (0.000)   (0.001)   (0.001)   
four_yr_degree                0.738 ***0.703 ***0.587 ***0.603 ***
                (0.012)   (0.012)   (0.018)   (0.018)   
ethnicityAmerican Indian or Alaska Native                -0.029    -0.038    0.243    0.282    
                (0.168)   (0.173)   (0.239)   (0.232)   
ethnicityAsian / Pacific Islander                0.748 ***0.671 ***0.756 ***0.830 ***
                (0.160)   (0.163)   (0.224)   (0.220)   
ethnicityBlack or African American                2.059 ***2.031 ***1.413 ***1.468 ***
                (0.156)   (0.159)   (0.217)   (0.213)   
ethnicityHispanic or Latino/a                0.614 ***0.522 ***0.650 ** 0.735 ***
                (0.154)   (0.157)   (0.216)   (0.212)   
ethnicityOther                -0.136    -0.137    -0.058    -0.028    
                (0.156)   (0.159)   (0.218)   (0.214)   
ethnicityWhite / Caucasian                0.389 *  0.401 ** 0.851 ***0.882 ***
                (0.153)   (0.156)   (0.214)   (0.210)   
county_trump_margin                        -0.685 ***-0.342 ***        
                        (0.023)   (0.035)           
prevtrump                                -4.772 ***-4.779 ***
                                (0.026)   (0.025)   
nobs130829        130829        130291        128550        128550        130291        
logLik-89989.244    -89980.364    -84019.515    -82525.660    -42532.583    -43161.759    
AIC179982.489    179966.728    168063.031    165077.319    85093.167    86349.519    
*** p < 0.001; ** p < 0.01; * p < 0.05.

Isolating the Effects of COVID on Preference

nocovid <- b.m5$model
nocovid$propcases <- 0

locovid <- b.m5$model
locovid$propcases <- summary(dta$propcases)[2] # 25th percentile

hicovid <- b.m5$model
hicovid$propcases <- summary(dta$propcases)[5] # 75th percentile

maxcovid <- b.m5$model
maxcovid$propcases <- max(dta$propcases)

mikecovid <- b.m5$model
mikecovid$propcases <- 3

b.vec <-
  c(sum(predict(
    b.m5, newdata = nocovid, type = "response"
  )),
  sum(predict(
    b.m5, newdata = locovid, type = "response"
  )),
  sum(predict(b.m5, type = "response")),
  sum(dta$biden),
  sum(predict(
    b.m5, newdata = hicovid, type = "response"
  )),
  sum(predict(
    b.m5, newdata = maxcovid, type = "response"
  )),
  sum(predict(
    b.m5, newdata = mikecovid, type = "response"
  )))



# these matrices are idential to above except for the first column
# and the first column is ignored by predict()
nocovid <- t.m5$model
nocovid$propcases <- 0

locovid <- t.m5$model
locovid$propcases <- summary(dta$propcases)[2] # 25th percentile

hicovid <- t.m5$model
hicovid$propcases <- summary(dta$propcases)[5] # 75th percentile

maxcovid <- t.m5$model
maxcovid$propcases <- max(dta$propcases)

mikecovid <- t.m5$model
mikecovid$propcases <- 3


t.vec <-
  c(sum(predict(
    t.m5, newdata = nocovid, type = "response"
  )),
  sum(predict(
    t.m5, newdata = locovid, type = "response"
  )),
  sum(predict(t.m5, type = "response")),
  sum(dta$trump),
  sum(predict(
    t.m5, newdata = hicovid, type = "response"
  )),
  sum(predict(
    t.m5, newdata = maxcovid, type = "response"
  )),
  sum(predict(
    t.m5, newdata = mikecovid, type = "response"
  )))

out <- data.frame(
  scenario = c("Zero", "Low", "As-is","Among Respondents",  "High", "Max", "Arbitrary (3)"),
  biden = b.vec,
  trump = t.vec
)
out$diff <- out$biden - out$trump


kable(out)
scenario biden trump diff
Zero 57514.13 60534.87 -3020.732
Low 57681.80 60456.61 -2774.812
As-is 58009.00 60304.00 -2295.000
Among Respondents 58823.00 61542.00 -2719.000
High 58140.26 60241.50 -2101.231
Max 71207.05 53265.40 17941.645
Arbitrary (3) 58613.71 60017.58 -1403.872
out.pct <- round(rbind(
  "Zero" = prop.table(c(b.vec[1], t.vec[1])),
  "Low" = prop.table(c(b.vec[2], t.vec[2])),
  "As-is" = prop.table(c(b.vec[3], t.vec[3])),
  "Among Respondents" = prop.table(c(b.vec[4], t.vec[4])),
  "High" = prop.table(c(b.vec[5], t.vec[5])),
  "Max" = prop.table(c(b.vec[6], t.vec[6])),
  "Arbitrary (3)" = prop.table(c(b.vec[7], t.vec[7]))
) * 100, 2)

out.pct <- as.data.frame(out.pct)
names(out.pct) <- c("Biden", "Trump")
kable(out.pct)
Biden Trump
Zero 48.72 51.28
Low 48.83 51.17
As-is 49.03 50.97
Among Respondents 48.87 51.13
High 49.11 50.89
Max 57.21 42.79
Arbitrary (3) 49.41 50.59

Feeling Thermometers (1-10)

A logistic regression is not well-suited for values between 1 and 10. We will proceed with an OLS model.

Trump

t.ft1 <- lm(trump_ft ~ propcases, data = dta)
t.ft2 <- lm(trump_ft ~ propcases + weekn, data = dta)
t.ft3 <-
  lm(trump_ft ~ propcases + weekn + male + age + four_yr_degree + ethnicity,
     data = dta)
t.ft4 <-
  lm(
    trump_ft ~ propcases + weekn + male + age + four_yr_degree + ethnicity + county_trump_margin,
    data = dta
  )
t.ft5 <-
  lm(
    trump_ft ~ propcases + weekn + prevtrump + male + age + four_yr_degree + ethnicity + county_trump_margin,
    data = dta
  )

huxreg(t.ft1,
       t.ft2,
       t.ft3,
       t.ft4,
       t.ft5,
       statistics = c("nobs", "r.squared", "logLik", "AIC"))
(1)(2)(3)(4)(5)
(Intercept)5.277 ***5.044 ***4.718 ***4.716 ***2.698 ***
(0.015)   (0.061)   (0.287)   (0.291)   (0.174)   
propcases-0.044 ***-0.048 ***-0.009    -0.001    -0.014 ** 
(0.008)   (0.008)   (0.008)   (0.008)   (0.005)   
weekn        0.007 ***0.009 ***0.008 ***0.012 ***
        (0.002)   (0.002)   (0.002)   (0.001)   
male                1.137 ***1.122 ***0.356 ***
                (0.022)   (0.022)   (0.013)   
age                0.018 ***0.018 ***-0.006 ***
                (0.001)   (0.001)   (0.000)   
four_yr_degree                -1.495 ***-1.416 ***-0.550 ***
                (0.022)   (0.022)   (0.013)   
ethnicityAmerican Indian or Alaska Native                0.380    0.390    0.062    
                (0.305)   (0.311)   (0.186)   
ethnicityAsian / Pacific Islander                -1.051 ***-0.931 ** -0.229    
                (0.292)   (0.295)   (0.177)   
ethnicityBlack or African American                -3.173 ***-3.145 ***-0.774 ***
                (0.282)   (0.285)   (0.171)   
ethnicityHispanic or Latino/a                -0.786 ** -0.647 *  -0.154    
                (0.280)   (0.284)   (0.170)   
ethnicityOther                0.409    0.364    0.182    
                (0.283)   (0.286)   (0.171)   
ethnicityWhite / Caucasian                -0.368    -0.432    -0.430 *  
                (0.278)   (0.281)   (0.168)   
county_trump_margin                        1.341 ***0.256 ***
                        (0.043)   (0.026)   
prevtrump                                6.601 ***
                                (0.014)   
nobs130829        130829        130291        128550        128550        
r.squared0.000    0.000    0.088    0.094    0.675    
logLik-370477.136    -370469.363    -362974.470    -357676.084    -291704.953    
AIC740960.271    740946.726    725974.940    715380.168    583439.907    
*** p < 0.001; ** p < 0.01; * p < 0.05.

Biden

b.ft1 <- lm(biden_ft ~ propcases, data = dta)
b.ft2 <- lm(biden_ft ~ propcases + weekn, data = dta)
b.ft3 <-
  lm(biden_ft ~ propcases + weekn + male + age + four_yr_degree + ethnicity,
     data = dta)
b.ft4 <-
  lm(
    biden_ft ~ propcases + weekn + male + age + four_yr_degree + ethnicity + county_trump_margin,
    data = dta
  )
b.ft5 <-
  lm(
    biden_ft ~ propcases + weekn + prevtrump + male + age + four_yr_degree + ethnicity + county_trump_margin,
    data = dta
  )

huxreg(b.ft1,
       b.ft2,
       b.ft3,
       b.ft4,
       b.ft5,
       statistics = c("nobs", "r.squared", "logLik", "AIC"))
(1)(2)(3)(4)(5)
(Intercept)4.536 ***3.916 ***2.319 ***2.310 ***3.985 ***
(0.014)   (0.055)   (0.260)   (0.263)   (0.178)   
propcases0.060 ***0.052 ***0.005    0.000    0.012 *  
(0.007)   (0.007)   (0.007)   (0.007)   (0.005)   
weekn        0.019 ***0.016 ***0.017 ***0.014 ***
        (0.002)   (0.002)   (0.002)   (0.001)   
male                -1.153 ***-1.141 ***-0.506 ***
                (0.020)   (0.020)   (0.014)   
age                0.019 ***0.019 ***0.039 ***
                (0.001)   (0.001)   (0.000)   
four_yr_degree                1.231 ***1.164 ***0.446 ***
                (0.020)   (0.020)   (0.014)   
ethnicityAmerican Indian or Alaska Native                -0.090    -0.077    0.195    
                (0.275)   (0.281)   (0.191)   
ethnicityAsian / Pacific Islander                1.242 ***1.123 ***0.540 ** 
                (0.264)   (0.267)   (0.181)   
ethnicityBlack or African American                3.377 ***3.335 ***1.366 ***
                (0.254)   (0.258)   (0.175)   
ethnicityHispanic or Latino/a                1.060 ***0.925 ***0.516 ** 
                (0.253)   (0.256)   (0.174)   
ethnicityOther                -0.369    -0.350    -0.200    
                (0.256)   (0.259)   (0.176)   
ethnicityWhite / Caucasian                0.444    0.484    0.482 ** 
                (0.251)   (0.254)   (0.172)   
county_trump_margin                        -1.102 ***-0.201 ***
                        (0.039)   (0.027)   
prevtrump                                -5.479 ***
                                (0.014)   
nobs130829        130829        130291        128550        128550        
r.squared0.001    0.002    0.095    0.101    0.586    
logLik-357750.724    -357683.638    -349771.506    -344804.496    -294873.024    
AIC715507.449    715375.276    699569.012    689636.993    589776.048    
*** p < 0.001; ** p < 0.01; * p < 0.05.