This is a preregistered study, intended to draw boundaries around our effect: hold for advantage-gain frame and not for disadvantage-gain frame.
In an experimental design, participants were assigned to one of two
conditions: Advantage-gain frame (upper class gaining at working class
expense) and disadvantage-gain frame (working class gaining at upper
class expense).
They completed the following scales: (1) class-based zero-sum beliefs
(frame consistent with randomly-assigned condition); (2) class
solidarity; and (3) general zero-sum mindset.
They also read about one neutrally-framed economic progressive policy
proposal (randomly-selected out of a set of four policy descriptions)
and indicate their support for that policy.
Finally, they will indicate their political ideology, party
identification, and demographic information.
The disadvantage-gain frame condition will either not predict, or weakly predict, class solidarity and support for policy.
But first, let’s exclude participants who failed a very simple attention check.
df_cbzs %>%
group_by(att_1) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
att_1 | N | Perc |
---|---|---|
0 | 8 | 2.00 |
1 | 392 | 97.76 |
NA | 1 | 0.25 |
Alright, that leaves us with 392. Cool.
df_cbzs_elg %>%
group_by(race) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
race | N | Perc |
---|---|---|
American Indian or Alaska Native | 2 | 0.51 |
Asian | 24 | 6.12 |
Black or African American | 48 | 12.24 |
Hispanic, Latino, or Spanish origin | 15 | 3.83 |
Middle Eastern or North African | 1 | 0.26 |
Native Hawaiian or Other Pacific Islander | 1 | 0.26 |
Other (please specify) | 3 | 0.77 |
White | 276 | 70.41 |
multiracial | 22 | 5.61 |
df_cbzs_elg %>%
mutate(gender = ifelse(is.na(gender) | gender == "","other",gender)) %>%
group_by(gender) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
gender | N | Perc |
---|---|---|
man | 174 | 44.39 |
other | 6 | 1.53 |
woman | 212 | 54.08 |
df_cbzs_elg %>%
summarise(age_mean = round(mean(age,na.rm = T),2),
age_sd = round(sd(age,na.rm = T),2)) %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
age_mean | age_sd |
---|---|
39.54 | 13.01 |
df_cbzs_elg %>%
group_by(edu) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
edu | N | Perc |
---|---|---|
noHS | 2 | 0.51 |
GED | 100 | 25.51 |
2yearColl | 46 | 11.73 |
4yearColl | 162 | 41.33 |
MA | 59 | 15.05 |
PHD | 22 | 5.61 |
NA | 1 | 0.26 |
df_cbzs_elg %>%
group_by(ses) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
ses | N | Perc |
---|---|---|
Lower Class | 43 | 10.97 |
Lower Middle Class | 119 | 30.36 |
Middle Class | 177 | 45.15 |
Upper Middle Class | 51 | 13.01 |
Upper Class | 2 | 0.51 |
To what extent do you see yourself as part of the working class? (1 = Not at all part of the working class to 5 = Entirely part of the working class)
df_cbzs_elg %>%
ggplot(aes(x = wrkclass)) +
geom_bar() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.y = element_text(color = "black"),
axis.text.x = element_text(color = "black",
face = "bold"),
axis.title.x = element_blank(),
axis.title.y = element_blank())
df_cbzs_elg %>%
ggplot(aes(x = income)) +
geom_bar() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.y = element_text(color = "black"),
axis.text.x = element_text(color = "black",
face = "bold"),
axis.title.x = element_blank(),
axis.title.y = element_blank()) +
coord_flip()
Participants were asked about the extent to which they subscribe to the following ideologies on a scale of 1-7 (select NA if unfamiliar): Conservatism, Liberalism, Democratic Socialism, Libertarianism, Progressivism.
means <- df_cbzs_elg %>%
dplyr::select(PID,ideo_con:ideo_prog) %>%
pivot_longer(-PID,
names_to = "ideo",
values_to = "score") %>%
filter(!is.na(score)) %>%
group_by(ideo) %>%
summarise(score = mean(score)) %>%
ungroup()
df_cbzs_elg %>%
dplyr::select(PID,ideo_con:ideo_prog) %>%
pivot_longer(-PID,
names_to = "ideo",
values_to = "score") %>%
filter(!is.na(score)) %>%
ggplot() +
geom_density(aes(x = score), fill = "lightblue") +
scale_x_continuous(limits = c(1,7),
breaks = seq(1,7,1)) +
geom_vline(data = means,mapping = aes(xintercept = score),
color = "black",
linetype = "dashed",
size = 1.1) +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.y = element_text(color = "black"),
axis.text.x = element_text(color = "black",
face = "bold")) +
facet_wrap(~ideo,nrow = 2)
df_cbzs_elg %>%
group_by(party_id) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
party_id | N | Perc |
---|---|---|
Democrat | 191 | 48.72 |
Independent | 111 | 28.32 |
Republican | 90 | 22.96 |
df_cbzs_elg %>%
group_by(vote_2020) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
arrange(desc(N)) %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
vote_2020 | N | Perc |
---|---|---|
Joe Biden | 212 | 54.08 |
Donald Trump | 95 | 24.23 |
I did not vote | 60 | 15.31 |
Third-party candidate | 25 | 6.38 |
df_cbzs_elg %>%
group_by(vote_2024) %>%
summarise(N = n()) %>%
ungroup() %>%
mutate(Perc = round(100*(N/sum(N)),2)) %>%
ungroup() %>%
arrange(desc(N)) %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
vote_2024 | N | Perc |
---|---|---|
Joe Biden | 192 | 48.98 |
Donald Trump | 99 | 25.26 |
I will not vote | 51 | 13.01 |
Robert F. Kennedy Jr. | 25 | 6.38 |
Other | 21 | 5.36 |
Cornel West | 2 | 0.51 |
Jill Stein | 2 | 0.51 |
means <- df_cbzs_elg %>%
group_by(cond) %>%
summarise(score = mean(zs_class,na.rm = T)) %>%
ungroup()
df_cbzs_elg %>%
ggplot(aes(x = zs_class)) +
geom_density(fill = "lightblue",
color = "black") +
scale_x_continuous(breaks = seq(1,7,1),
limits = c(1,7)) +
ylab("density") +
geom_vline(data = means,mapping = aes(xintercept = score),
color = "black",
linetype = "dashed",
size = 1.1) +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.y = element_text(color = "black"),
axis.text.x = element_text(color = "black",
face = "bold"),
axis.title.x = element_text(color = "black",
face = "bold")) +
facet_wrap(~cond,
nrow = 2)
df_cbzs_elg %>%
ggplot(aes(x = zsm)) +
geom_density(fill = "lightblue",
color = "black") +
scale_x_continuous(breaks = seq(1,7,1),
limits = c(1,7)) +
ylab("density") +
geom_vline(xintercept = mean(df_cbzs_elg$zsm,na.rm = T),
color = "grey15",
size = 1,
linetype = "dashed") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.y = element_text(color = "black"),
axis.text.x = element_text(color = "black",
face = "bold"),
axis.title.x = element_text(color = "black",
face = "bold"))
df_cbzs_elg %>%
ggplot(aes(x = soli)) +
geom_density(fill = "lightblue",
color = "black") +
scale_x_continuous(breaks = seq(1,7,1),
limits = c(1,7)) +
ylab("density") +
geom_vline(xintercept = mean(df_cbzs_elg$soli,na.rm = T),
color = "grey15",
size = 1,
linetype = "dashed") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.y = element_text(color = "black"),
axis.text.x = element_text(color = "black",
face = "bold"),
axis.title.x = element_text(color = "black",
face = "bold"))
Participants saw one of four policy descriptions:
Minimum wage: Congress has not increased the federal
minimum wage, currently set at 7.25 dollars, since 2009. Some
Congresspeople are proposing a policy that would gradually raise the
federal minimum wage to 15 dollars an hour by 2025. After 2025, the
minimum wage would be adjusted each year to keep pace with growth in the
median wage, a measure of wages for typical workers.
Student debt: Some Congresspeople are proposing a
policy that would help to address the student loan debt crisis by
forgiving up to 50,000 dollars in loans per borrower. Approximately 42
million Americans, or about 1 in 6 American adults, owe a cumulative 1.6
trillion dollars in student loans. Student loans are now the
second-largest slice of household debt after mortgages, bigger than
credit card debt.
Housing: Some Congresspeople are proposing a housing
affordability policy that would help ensure that every American has a
place to live. The policy would allow for smaller, lower cost homes like
duplexes, townhouses, and garden apartments to be built and developed,
allowing new nonprofit homes and reducing overall housing prices.
Climate: Some Congresspeople are proposing a Green New
Deal bill which would phase out the use of fossil fuels, with the
government providing clean energy jobs for people who can’t find
employment in the private sector. All jobs would pay at least 15 dollars
an hour, and include healthcare benefits and collective bargaining
rights.
To what extent do you oppose or support this policy? (1 = Strongly Oppose to 7 = Strongly Support)
means <- df_cbzs_elg %>%
dplyr::select(PID,support,policy) %>%
filter(!is.na(support)) %>%
group_by(policy) %>%
summarise(score = mean(support)) %>%
ungroup()
df_cbzs_elg %>%
dplyr::select(PID,support,policy) %>%
filter(!is.na(support)) %>%
ggplot(aes(x = support)) +
geom_histogram(fill = "lightblue",
color = "black",
binwidth = 1) +
scale_x_continuous(limits = c(0,8),
breaks = seq(1,7,1)) +
geom_vline(data = means,mapping = aes(xintercept = score),
color = "black",
linetype = "dashed",
size = 1.1) +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.y = element_text(color = "black"),
axis.text.x = element_text(color = "black",
face = "bold")) +
facet_wrap(~policy,nrow = 2)
df_cbzs_elg <- df_cbzs_elg %>%
mutate(income_num = as.numeric(income),
edu_num = as.numeric(edu),
ses_num = as.numeric(ses))
df_cbzs_elg %>%
filter(cond == "adgain") %>%
dplyr::select(zs_class:support,ideo_con,white,man,wrkclass,income_num:ses_num) %>%
corPlot(upper = TRUE,stars = TRUE,xsrt = 270)
df_cbzs_elg <- df_cbzs_elg %>%
mutate(income_num = as.numeric(income),
edu_num = as.numeric(edu),
ses_num = as.numeric(ses))
df_cbzs_elg %>%
filter(cond == "disadgain") %>%
dplyr::select(zs_class:support,ideo_con,white,man,wrkclass,income_num:ses_num) %>%
corPlot(upper = TRUE,stars = TRUE,xsrt = 270)
One note: I love that they’re both equally correlated with general zero-sum mindset. And yeah, the disadvantage-gain frame is not correlated with anything. V cool.
Support for policy as the outcome variable; Class Zero-Sum Beliefs as the primary predictor; Condition as the moderator; General zero-sum mindset as a control variable.
m1 <- lm(support ~ zs_class*cond + zsm,data = df_cbzs_elg)
apa_lm <- apa_print(m1)
apa_table(
apa_lm$table,
placement = "H"
)
Predictor | \(b\) | 95% CI | \(t\) | \(\mathit{df}\) | \(p\) |
---|---|---|---|---|---|
Intercept | 3.00 | [2.20, 3.79] | 7.40 | 387 | < .001 |
Zs class | 0.57 | [0.40, 0.73] | 6.70 | 387 | < .001 |
Conddisadgain | 2.24 | [1.32, 3.16] | 4.79 | 387 | < .001 |
Zsm | 0.00 | [-0.17, 0.17] | -0.05 | 387 | .961 |
Zs class \(\times\) Conddisadgain | -0.49 | [-0.72, -0.27] | -4.28 | 387 | < .001 |
df_cbzs_elg %>%
ggplot(aes(x = zs_class,y = support,color = cond)) +
scale_color_manual(values = c("darkblue",
"darkred")) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "lm") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.x = element_text(color = "black",
face = "bold",
size = 12),
axis.title.x = element_text(color = "black",
face = "bold",
size = 12),
axis.text.y = element_text(color = "black",
face = "bold",
size = 12),
axis.title.y = element_text(color = "black",
face = "bold",
size = 12))
that’s a pretty plot.
Class solidarity as the outcome variable; Class Zero-Sum Beliefs as the primary predictor; Condition as the moderator; General zero-sum mindset as a control variable.
m1 <- lm(soli ~ zs_class*cond + zsm,data = df_cbzs_elg)
apa_lm <- apa_print(m1)
apa_table(
apa_lm$table,
placement = "H"
)
Predictor | \(b\) | 95% CI | \(t\) | \(\mathit{df}\) | \(p\) |
---|---|---|---|---|---|
Intercept | 5.19 | [4.83, 5.56] | 27.89 | 387 | < .001 |
Zs class | 0.21 | [0.14, 0.29] | 5.47 | 387 | < .001 |
Conddisadgain | 1.06 | [0.63, 1.48] | 4.90 | 387 | < .001 |
Zsm | -0.06 | [-0.14, 0.02] | -1.45 | 387 | .148 |
Zs class \(\times\) Conddisadgain | -0.26 | [-0.37, -0.16] | -5.00 | 387 | < .001 |
df_cbzs_elg %>%
ggplot(aes(x = zs_class,y = soli,color = cond)) +
scale_color_manual(values = c("darkblue",
"darkred")) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "lm") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.ticks = element_blank(),
axis.line = element_line(color = "grey66"),
axis.text.x = element_text(color = "black",
face = "bold",
size = 12),
axis.title.x = element_text(color = "black",
face = "bold",
size = 12),
axis.text.y = element_text(color = "black",
face = "bold",
size = 12),
axis.title.y = element_text(color = "black",
face = "bold",
size = 12))
wow.
Can I also take a moment to acknowledge the main effect of condition?
That’s wild. All we changed is the framing of the measure, and look at
that effect. That’s very encouraging ahead of our experimental
designs.
Support for policy as the outcome variable; Class Zero-Sum Beliefs as the primary predictor; Class solidarity as the mediator; General zero-sum mindset as a control variable. Condition as the moderator of the a-path and direct link.
df_cbzs_elg <- df_cbzs_elg %>%
mutate(cond_num = ifelse(cond == "adgain",1,0))
fit <- PROCESS(df_cbzs_elg, y="support", x="zs_class",
meds="soli",
mods="cond",
mod.path=c("x-m", "x-y"),
ci="boot", nsim=100, seed=1)
****************** PART 1. Regression Model Summary ******************
PROCESS Model Code : 8 (Hayes, 2018; www.guilford.com/p/hayes3) PROCESS Model Type : Moderated Mediation - Outcome (Y) : support - Predictor (X) : zs_class - Mediators (M) : soli - Moderators (W) : cond - Covariates (C) : - - HLM Clusters : -
All numeric predictors have been grand-mean centered. (For details, please see the help page of PROCESS.)
Formula of Mediator: - soli ~ zs_classcond Formula of Outcome: - support ~ zs_classcond + soli
CAUTION: Fixed effect (coef.) of a predictor involved in an interaction denotes its “simple effect/slope” at the other predictor = 0. Only when all predictors in an interaction are mean-centered can the fixed effect denote the “main effect”!
Model Summary
───────────────────────────────────────────────────────────── (1)
support (2) soli (3) support
─────────────────────────────────────────────────────────────
(Intercept) 5.543 *** 5.835 *** 5.252 (0.086) (0.065)
(0.126)
zs_class 0.267 0.192 *** 0.377 (0.049)
(0.036) (0.073)
conddisadgain 0.044 0.363
(0.093) (0.179)
zs_class:conddisadgain -0.265 * -0.231 *
(0.053) (0.106)
soli 0.980 (0.098)
───────────────────────────────────────────────────────────── R^2 0.070
0.077 0.301
Adj. R^2 0.068 0.070 0.294
Num. obs. 392 392 392
───────────────────────────────────────────────────────────── Note.
p < .05, p < .01, *** p < .001.
************ PART 2. Mediation/Moderation Effect Estimate ************
Package Use : ‘mediation’ (v4.5.0), ‘interactions’ (v1.1.5) Effect Type : Moderated Mediation (Model 8) Sample Size : 392 Random Seed : set.seed(1) Simulations : 100 (Bootstrap)
Interaction Effect on “support” (Y)
─────────────────────────────────────── F df1 df2 p
─────────────────────────────────────── zs_class * cond 4.79 1 387 .029
*
───────────────────────────────────────
Simple Slopes: “zs_class” (X) ==> “support” (Y) (Conditional Direct Effects [c’] of X on Y) ───────────────────────────────────────────────────────── “cond” Effect S.E. t p [95% CI] ───────────────────────────────────────────────────────── adgain 0.377 (0.073) 5.183 <.001 *** [ 0.234, 0.521] disadgain 0.146 (0.075) 1.960 .051 . [-0.000, 0.293] ─────────────────────────────────────────────────────────
Interaction Effect on “soli” (M)
──────────────────────────────────────── F df1 df2 p
──────────────────────────────────────── zs_class * cond 25.17 1 388
<.001 *** ────────────────────────────────────────
Simple Slopes: “zs_class” (X) ==> “soli” (M) (Conditional Effects [a] of X on M) ────────────────────────────────────────────────────────── “cond” Effect S.E. t p [95% CI] ────────────────────────────────────────────────────────── adgain 0.192 (0.036) 5.301 <.001 *** [ 0.121, 0.264] disadgain -0.073 (0.038) -1.891 .059 . [-0.148, 0.003] ──────────────────────────────────────────────────────────
Running 100 * 2 simulations… Indirect Path: “zs_class” (X) ==>
“soli” (M) ==> “support” (Y) (Conditional Indirect Effects [ab] of X
through M on Y)
─────────────────────────────────────────────────────────── “cond”
Effect S.E. z p [Boot 95% CI]
─────────────────────────────────────────────────────────── adgain 0.189
(0.043) 4.354 <.001 *** [0.115, 0.266]
disadgain -0.071 (0.035) -2.043 .041 * [-0.142, -0.007]
─────────────────────────────────────────────────────────── Percentile
Bootstrap Confidence Interval (SE and CI are estimated based on 100
Bootstrap samples.)
Note. The results based on bootstrapping or other random processes are unlikely identical to other statistical software (e.g., SPSS). To make results reproducible, you need to set a seed (any number). Please see the help page for details: help(PROCESS) Ignore this note if you have already set a seed. :)
fit$results[1] %>%
kbl() %>%
kable_styling(bootstrap_options = "hover",
full_width = F,
position = "left")
|