Some helpful code for Report 2.
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"))
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
)
# 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"))
)
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,)
# 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 |
R^{2} | 0.004 | 0.041 |
Adjusted R^{2} | 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_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.