Report 2 Guide (draft)

Some helpful code for Report 2.

Team 346 pol346.com (Princeton Univeristy Department of Politics)princeton.edu/politics
2020-05-04

Table of Contents


Introduction

Imagine if we were interested in how attitudes about civil unrest in the 1970s influenced political views. To investigate, we could use the American National Election Study Timeseries to model and plot how something like the relationship between the 1972 Unrest Scale relates to feelings toward the Republican presidential candidate.


# tidyverse packages
library(tidyverse)
library(janitor)

# file path management (requires use of R Projects)
library(here)

# data translation
library(foreign)
library(haven)

# plotting
library(ggridges)
library(sjPlot)

# with sjPlot, for changing labels
library(sjlabelled)

# tables
library(stargazer)

# here() manages local path to data (requires use of R Projects)
a1 <- read_dta(here("anes_timeseries_cdf_dta/anes_timeseries_cdf_stata13.dta")) 

Recode data


a2 <- a1 %>% 
  mutate(
    # this is time series version of ANES with multiple years
    year       = VCF0004,

    # example demographic vars
    age        = VCF0102,
    male       = (VCF0104 == 1) %>% as.factor(),
    race       = VCF0105a,
    race_white = (race == 1) %>% as.factor(),
    race_black = (race == 2) %>% as.factor(),
    race_other = (race != 1 & race != 2) %>% as.factor(),
    race_wb    = case_when(
                   race == 1 ~ "White",
                   race == 2 ~ "Black",
                   TRUE      ~ NA_character_) %>% as.factor(),
    race       = race %>% as.factor(),

    # main explanatory and outcome vars
    unrest_scale   = VCF0528,
    therm_rep_pres = VCF0426
  )

Relabel data


# sjlabelled package allows us to set labels for x, y and their values

# review label attributes
attr(a2$unrest_scale, "labels")

0. NA party placement; DK/NA/haven't thought much 
                                                0 
    1. Solve problems of poverty and unemployment 
                                                1 
                       7. Use all available force 
                                                7 
                            8. DK party placement 
                                                8 

# use sjlabelled package functions to view attributes

# get_label (no s) tells us about variable label
get_label(a2$unrest_scale)  

[1] "Democratic Party- Urban Unrest Scale"

# get_labels (with s) tells us variable values
get_labels(a2$unrest_scale) 

[1] "0. NA party placement; DK/NA/haven't thought much"
[2] "1. Solve problems of poverty and unemployment"    
[3] "7. Use all available force"                       
[4] "8. DK party placement"                            

# number of label levels
get_labels(a2$unrest_scale) %>% length() 

[1] 4

# use sjlabelled package
a2 <- a2 %>% 
  mutate(
    # re-label data with set_labels (WITH *s*)
    unrest_scale = set_labels(unrest_scale,  
                              labels = c("Solve\nPoverty" = 1, " " = 2, " " = 3, 
                                         " " = 4, " " = 5, " " = 6, 
                                         "Use\nForce" = 7)), # \n is for new line
    
    # re-label variable with set_label (NO *s*)
    unrest_scale = set_label(unrest_scale,  label = c("Urban Unrest Scale"))

  )

Model data

Typically we might control for something like 5-7 variables. In this example, we just use three to illustrate.


# subset this version of ANES for the year 1972
a3 <- a2 %>% filter(year == 1972)

# Thermometers Republican Candidate vs Unrest Scale 
reduced_model <- lm(formula = therm_rep_pres ~ unrest_scale,
          data    = a3,) 

full_model    <- lm(formula = therm_rep_pres ~ unrest_scale + male + race_wb + age,
          data    = a3,) 

Publish data in table


# stargazer can take multiple models
stargazer(reduced_model, full_model, header = FALSE, type = "html")
Dependent variable:
therm_rep_pres
(1) (2)
unrest_scale 1.150* 1.080
(0.670) (0.662)
male -0.899
(1.940)
race_wbWhite 16.100***
(3.310)
age 0.784
(0.586)
Constant 61.300*** 45.000***
(2.280) (4.040)
Observations 734 719
R2 0.004 0.041
Adjusted R2 0.003 0.035
Residual Std. Error 26.400 (df = 732) 25.900 (df = 714)
F Statistic 2.960* (df = 1; 732) 7.540*** (df = 4; 714)
Note: p<0.1; p<0.05; p<0.01

Plot models


# plot_model from sjPlot package
plot_model(
  model  = full_model,    
  type   = "pred",           # plot predicted value
  terms  = c("unrest_scale") # plot unrest_scale as predictor (x-axis)
) +
  theme_minimal() +
  ggtitle("Thermometer GOP Candidate vs Unrest Scale") +
  labs(y = "Predicted Therm-GOP Pres Cand")

We can also look at how race moderates the main relationship. The slope of the relationship between the GOP Candidate Feeling Thermometer and the Urban Unrest Scale is the same for both groups (white and black) but whites, on average, feel more warmly towards the GOP candidate and blacks, on average, feel more cooly toward towards the GOP candidate (an intercept shift).


plot_model(
  model  = full_model,    
  type   = "pred",                      # plot predicted value
  terms  = c("unrest_scale", "race_wb") # plot unrest_scale as predictor
                                        # plot race_wb as moderator
) +
  theme_minimal() +
  ggtitle("Thermometer GOP Candidate vs Unrest Scale") +
  labs(y     = "Predicted Therm-GOP Pres Cand",
       color = 'Race') # change legend title


This supplement was put together by Omar Wasow.