Q1. Report the relationship between three issues scales (Guaranteed Jobs and Incomes-VCF0809, Government Health Insurance Scale-VCF0806, Government Services-Spending Scale-VCF0839). Which is the most strongly re- lated to presidential vote choice?
library(plyr)
library(tidyverse)
library(magrittr)
library(purrrlyr)
library(broom)
d1 <- "https://github.com/thomasjwood/ps7160/raw/master/anes_cdf_20211118.rds" %>%
url %>%
gzcon %>%
readRDS %>%
tbl_df
t1 <- d1 %>%
select(
VCF0704a, VCF0809, VCF0806, VCF0839
) %>%
filter(
VCF0704a %>%
str_detect("1. |2. ")
) %>%
modify_at(
1,
function(i)
i %>%
str_sub(, 1) %>%
as.numeric %>%
subtract(1)
) %>%
pivot_longer(
-VCF0704a,
names_to = "scale",
values_to = "ans",
values_drop_na = T
) %>%
mutate(
ans = ans %>%
str_sub(, 1) %>%
as.numeric,
scale = scale %>%
mapvalues(
c("VCF0809", "VCF0806", "VCF0839"),
c("Guaranteed jobs and income",
"Govt health insurance scale",
"Govt spending services scale")
)
) %>%
filter(
ans %>%
is_in(1:7)
)
library(DAMisc)
t1 %>%
group_by(
scale
) %>%
nest %>%
mutate(
pre = data %>%
map(
\(i)
glm(
VCF0704a ~ ans, data = i, family = binomial()
) %>%
pre %>%
extract2(., "pre")
) %>%
unlist
)
## # A tibble: 3 × 3
## # Groups: scale [3]
## scale data pre
## <chr> <list> <dbl>
## 1 Guaranteed jobs and income <tibble [21,655 × 2]> 0.391
## 2 Govt health insurance scale <tibble [19,498 × 2]> 0.415
## 3 Govt spending services scale <tibble [17,757 × 2]> 0.438
The pre
function reports the proportional reduction in
error–how much more predictive a GLM model is, following the inclusion
of a predictor variable, compared to a GLM with only an intercept.
Bigger values indicate larger improvements in predictiveness.
Accordingly, the VCF0839
–government spending and services
scale–is the most strongly related.
Q.2 Working still with these issue scales, does the relationship with presidential vote change over time?
t2 <- d1 %>%
select(
VCF0704a, VCF0004, VCF0809, VCF0806, VCF0839
) %>%
filter(
VCF0704a %>%
str_detect("1. |2. ")
) %>%
modify_at(
1,
function(i)
i %>%
str_sub(, 1) %>%
as.numeric %>%
subtract(1)
) %>%
pivot_longer(
-c(VCF0704a, VCF0004),
names_to = "scale",
values_to = "ans",
values_drop_na = T
) %>%
mutate(
ans = ans %>%
str_sub(, 1) %>%
as.numeric,
scale = scale %>%
mapvalues(
c("VCF0809", "VCF0806", "VCF0839"),
c("Guaranteed jobs and income",
"Govt health insurance scale",
"Govt spending services scale")
)
) %>%
filter(
ans %>%
is_in(1:7)
)
Now we’ll just do the version of the PRE test we did above, now just doing the test separately by year
t2 %>%
group_by(
scale, VCF0004
) %>%
nest %>%
pmap(
function(VCF0004, scale, data)
tibble(
VCF0004 = VCF0004,
scale = scale,
pre = glm(
VCF0704a ~ ans, data = data, family = binomial()
) %>%
pre %>%
extract2(., "pre")
)
) %>%
list_rbind %>%
ggplot(
aes(VCF0004, pre)
) +
geom_line() +
facet_wrap(~scale) +
theme_minimal() +
labs(
x = "",
y = "Poportional reduction in error"
)
Gawsh! Look at how Govt health insurance jumps in 2012? With whose theory of mass attitudes does this comport?
Q.3 Working still with these issue scales, does the relationship with presidential vote interact with respondent education?
Now we only need to trade out years for education!
t3 <- d1 %>%
select(
VCF0704a, VCF0110, VCF0809, VCF0806, VCF0839
) %>%
filter(
VCF0704a %>%
str_detect("1. |2. ")
) %>%
modify_at(
1,
function(i)
i %>%
str_sub(, 1) %>%
as.numeric %>%
subtract(1)
) %>%
pivot_longer(
-c(VCF0704a, VCF0110),
names_to = "scale",
values_to = "ans",
values_drop_na = T
) %>%
mutate(
ans = ans %>%
str_sub(, 1) %>%
as.numeric,
scale = scale %>%
mapvalues(
c("VCF0809", "VCF0806", "VCF0839"),
c("Guaranteed jobs and income",
"Govt health insurance scale",
"Govt spending services scale")
)
) %>%
filter(
ans %>%
is_in(1:7) &
VCF0110 %>%
str_detect("0. DK") %>%
not
)
t3 %>%
group_by(
scale, VCF0110
) %>%
nest %>%
pmap(
function(VCF0110, scale, data)
tibble(
VCF0110 = VCF0110,
scale = scale,
pre = glm(
VCF0704a ~ ans, data = data, family = binomial()
) %>%
pre %>%
extract2(., "pre")
)
) %>%
list_rbind %>%
ggplot(
aes(scale, pre, fill = VCF0110)
) +
geom_col(
color = "black",
size = .6,
width = .75,
position = "dodge"
) +
scale_x_discrete(
breaks = t3$scale %>%
factor %>%
levels,
labels = t3$scale %>%
factor %>%
levels %>%
str_wrap(15)
) +
scale_fill_grey(
guide = guide_legend(nrow = 2),
labels = t3$VCF0110 %>%
levels %>%
extract(-1) %>%
str_sub(4)
) +
theme_minimal() +
theme(
panel.grid = element_blank(),
legend.position = "bottom"
) +
labs(
fill = "",
x = "",
y = "Poportional reduction in error"
)
Q.4 Consider the Lewis-Beck et al. criteria for issue voting:
- The public reports they have thought about some issue
- The public adopts a non-neutral position
- THe public can discriminate between the parties’ respective positions on an issue
Among the ANES CDF’s 7 point issue scales, report an issue where a higher proportion of the public met the issue voting criteria in 2016, compared to prior years.
Ok, so I need to cheat a lot on this, and do some stuff compactly which we’ll only demo later this semester.
t4 <- list(
c("govhealth", "VCF0806", "VCF0508", "VCF0509"),
c("guarntjob", "VCF0809", "VCF0513", "VCF0514"),
c("govserv","VCF0839", "VCF0541" , "VCF0542")
) %>%
map(
function(i)
d1 %>%
select(
VCF0006a, VCF0004, i[-1]
) %>%
gather(actor, ans, -c(1:2), na.rm = T) %>%
mutate(
ans = ans %>%
str_sub(, 1) %>%
as.numeric,
actor = actor %>%
plyr::mapvalues(
i[-1],
c("respondent", "dem_party", "rep_party")
),
scale = i[1]
) %>%
spread(actor, ans)
) %>%
list_rbind
t5 <- t4 %>%
group_by(
VCF0004, scale
) %>%
nest %>%
pmap_dfr(
function(VCF0004, scale, data)
tibble(
VCF0004 = VCF0004,
scale = scale,
perc = data %>%
filter(
dem_party %>%
is_in(1:7) &
rep_party %>%
is_in(1:7) &
respondent %>%
is_in(1:7)
) %>%
mutate(
issue_voter = ifelse(
respondent != 4 &
dem_party != rep_party,
"prospective issue voter",
"non-prospective issue voter"
)
) %>%
group_by(
issue_voter
) %>%
tally %>%
mutate(
prop = n %>%
divide_by(
n %>%
sum
)
) %>%
select(-n) %>%
filter(
issue_voter == "prospective issue voter"
) %>%
use_series(prop)
)
) %>%
ungroup
t5 %>%
ggplot(
aes(VCF0004, perc)
) +
geom_point() +
geom_smooth(
method = "lm"
) +
facet_wrap(~scale) +
theme_minimal() +
labs(
x = "",
y = "Voters qualifying under American Voter's\nissue voting criteria"
)
That answers was way way more technical than I wanted to be–but we’ll get to this stuff later in the semester!