This study is an expansion of an earlier pilot study by the authors, of which the results were used to generate the secondary hypotheses and exploratory analysis plan, in addition to the defined planned contrasts. All primary hypotheses remain identical to that of the pilot study, with the inclusion of hypotheses for the Democratic portion of the sample, as the pilot study sampled solely Republicans. All participants will be newly sampled from Prolific so as to avoid repeated exposure to the treatment.

Descriptive Analyses

I will perform a set of descriptive analyses intended to measure the exploratory relationship between each of our identified measures and condition assignment. I create one table comparing Democrats in the control condition to Democrats in the treatment condition on the basis of the mean and standard deviations for the following variables: partisan self-concept, self-reported ideology, the difference in feeling thermometer ratings between pre- and post-treatment for both parties, the difference between these affective differences, moral disengagement toward Republicans, individual levels of SPV, and meta-perceptions of Republicans’ SPV.

# 4.1: make groups
gD_control <- 2
gD_treat <- 4
D_control <- descriptive_stats %>% filter(exp_group_numeric == gD_control)
D_treat <- descriptive_stats %>% filter(exp_group_numeric == gD_treat)
# 4.2: form column structure
dem_rows <- lapply(names(items), function(label) {
  cols    <- items[[label]]
  mean_col <- cols[1]; sd_col <- cols[2]
# 4.3: how to pull means and SDs for each column         
  valD_control <- if (!is.na(D_control[[mean_col]])) {
    if (mean_col == "count") sprintf("%d", D_control[[mean_col]]) else sprintf("%.2f (%.2f)", D_control[[mean_col]], D_control[[sd_col]])
  } else NA_character_
  star <- if (label %in% names(stars_D)) stars_D[[label]] else ""
  valD_treat <- if (!is.na(D_treat[[mean_col]])) {
    if (mean_col == "count") sprintf("%d", D_treat[[mean_col]])
    else sprintf("%.2f (%.2f)%s", D_treat[[mean_col]], D_treat[[sd_col]], star)
  } else NA_character_
# 4.4: bind into table         
  tibble::tibble(Variable = label, Group_D_control = valD_control, Group_D_treat = valD_treat)
}) %>% dplyr::bind_rows()
# 4.5: make the labels for table and fill in      
nD_control <- D_control %>% pull(count) %>% unique()
nD_treat <- D_treat %>% pull(count) %>% unique()
colnames(dem_rows)[2:3] <- c(
  paste0("Control x Democrat"),
  paste0("Treatment x Democrat"))
Variable Control x Democrat Treatment x Democrat
Partisan Self-Concept 3.09 (1.02) 3.13 (1.02)
Self-Reported Ideology 2.24 (1.17) 2.00 (1.00)*
Difference in Affective Ratings:
Republican Party -0.18 (5.98) -2.20 (6.06)***
Difference in Affective Ratings:
Democratic Party -0.08 (5.61) 0.44 (7.93)
Difference in Affective Ratings Between Parties -0.10 (8.11) -2.93 (8.55)***
Moral Disengagement: Opposing Party 3.35 (0.98) 3.46 (1.07)
Individual SPV 21.91 (18.20) 25.79 (20.67)*
Meta-Perceptions of Republican SPV 41.77 (25.58) 47.50 (27.94)*
N 251 278

I will create a second table comparing Republicans in the control condition to Republicans in the treatment condition across the same set of variables.

# 3.1: make groups
gR_control <- 2
gR_treat <- 4
R_control <- descriptive_stats %>% filter(exp_group_numeric == gR_control)
R_treat <- descriptive_stats %>% filter(exp_group_numeric == gR_treat)
# 3.2: form column structure
rep_rows <- lapply(names(items), function(label) {
  cols    <- items[[label]]
  mean_col <- cols[1]; sd_col <- cols[2]
# 3.3: how to pull means and SRs for each column         
  valR_control <- if (!is.na(R_control[[mean_col]])) {
    if (mean_col == "count") sprintf("%d", R_control[[mean_col]]) else sprintf("%.2f (%.2f)", R_control[[mean_col]], R_control[[sd_col]])
  } else NA_character_
  star <- if (label %in% names(stars_R)) stars_R[[label]] else ""
  valR_treat <- if (!is.na(R_treat[[mean_col]])) {
    if (mean_col == "count") sprintf("%d", R_treat[[mean_col]])
    else sprintf("%.2f (%.2f)%s", R_treat[[mean_col]], R_treat[[sd_col]], star)
  } else NA_character_
# 3.4: bind into table         
  tibble::tibble(Variable = label, Group_R_control = valR_control, Group_R_treat = valR_treat)
}) %>% dplyr::bind_rows()
# 3.5: make the labels for table and fill in      
nR_control <- R_control %>% pull(count) %>% unique()
nR_treat <- R_treat %>% pull(count) %>% unique()
colnames(rep_rows)[2:3] <- c(
  paste0("Control x Republican"),
  paste0("Treatment x Republican"))
Variable Control x Republican Treatment x Republican
Partisan Self-Concept 3.09 (1.02) 3.13 (1.02)
Self-Reported Ideology 2.24 (1.17) 2.00 (1.00)
Difference in Affective Ratings:
Republican Party -0.18 (5.98) -2.20 (6.06)
Difference in Affective Ratings:
Democratic Party -0.08 (5.61) 0.44 (7.93)
Difference in Affective Ratings Between Parties -0.10 (8.11) -2.93 (8.55)
Moral Disengagement: Opposing Party 3.35 (0.98) 3.46 (1.07)
Individual SPV 21.91 (18.20) 25.79 (20.67)
Meta-Perceptions of Republican SPV 41.77 (25.58) 47.50 (27.94)
N 251 278

I also created a combined version of this table with four columns by condition assignment and (non-randomized) partisan ID, which was not specified in the pre-analysis plan, but essentially places these two tables next to each other. Therefore, this is not a significant deviation.

# 5.1: make groups
groups <- list(
  list(num = 1, col = "Control x Republican"),
  list(num = 3, col = "Treatment x Republican"),
  list(num = 2, col = "Control x Democrat"),
  list(num = 4, col = "Treatment x Democrat"))
# 5.2: form column structure   
combined_rows <- lapply(names(items), function(label) {
  cols     <- items[[label]]
  mean_col <- cols[1]; sd_col <- cols[2]
# 5.3: how to pull means and SDs for each column  
  vals <- lapply(groups, function(g) {
    grp <- descriptive_stats %>% filter(exp_group_numeric == g$num)
    if (!is.na(grp[[mean_col]])) {
      if (mean_col == "count") sprintf("%d", grp[[mean_col]]) 
      else sprintf("%.2f (%.2f)", grp[[mean_col]], grp[[sd_col]])
    } else NA_character_
  })
# 5.4: bind into table
  row <- tibble::tibble(Variable = label)
  for (i in seq_along(groups)) row[[groups[[i]]$col]] <- vals[[i]]
  row
}) %>% dplyr::bind_rows()
Variable Control x Republican Treatment x Republican Control x Democrat Treatment x Democrat
Partisan Self-Concept 3.14 (1.05) 3.08 (1.11) 3.09 (1.02) 3.13 (1.02)
Self-Reported Ideology 5.53 (1.08) 5.57 (1.20) 2.24 (1.17) 2.00 (1.00)
Difference in Affective Ratings:
Republican Party -0.25 (5.95) -1.90 (9.29) -0.18 (5.98) -2.20 (6.06)
Difference in Affective Ratings:
Democratic Party -0.18 (6.28) -0.67 (9.72) -0.08 (5.61) 0.44 (7.93)
Difference in Affective Ratings Between Parties -0.08 (9.35) -1.20 (13.19) -0.10 (8.11) -2.93 (8.55)
Moral Disengagement: Opposing Party 2.80 (1.23) 2.79 (1.18) 3.35 (0.98) 3.46 (1.07)
Individual SPV 20.50 (21.25) 18.53 (21.26) 21.91 (18.20) 25.79 (20.67)
Meta-Perceptions of Republican SPV 29.95 (19.20) 32.17 (24.24) 41.77 (25.58) 47.50 (27.94)
N 146 114 251 278

I deviate from the pre-analysis plan by creating an additional table that reports the mean and standard errors for each condition. This was selected for inclusion in the final manuscript to be consistent with later analyses, given that our conditional average treatment effect (CATE) estimates report robust standard errors.

Republicans

# 3.1: make groups
gR_control <- 1
gR_treat   <- 3
R_control <- descriptive_stats %>% filter(exp_group_numeric == gR_control)
R_treat <- descriptive_stats %>% filter(exp_group_numeric == gR_treat)
# 3.2: form column structure
rep_rows_se <- lapply(names(items), function(label) {
cols    <- items[[label]]
mean_col <- cols[1]; se_col <- cols[2]
# 3.3: how to pull means and SRs for each column
valR_control_se <- if (!is.na(R_control[[mean_col]])) {
if (mean_col == "count") sprintf("%d", R_control[[mean_col]]) else sprintf("%.2f (%.2f)", R_control[[mean_col]], R_control[[se_col]])
} else NA_character_
star <- if (label %in% names(stars_R)) stars_R[[label]] else ""
valR_treat_se <- if (!is.na(R_treat[[mean_col]])) {
if (mean_col == "count") sprintf("%d", R_treat[[mean_col]])
else sprintf("%.2f (%.2f)%s", R_treat[[mean_col]], R_treat[[se_col]], star)
} else NA_character_
# 3.4: bind into table
tibble::tibble(Variable = label, Group_R_control = valR_control_se, Group_R_treat = valR_treat_se)
}) %>% dplyr::bind_rows()
# 3.5: make the labels for table and fill in
nR_control_se <- R_control %>% pull(count) %>% unique()
nR_treat_se <- R_treat %>% pull(count) %>% unique()
colnames(rep_rows_se)[2:3] <- c(
paste0("Control x Republican"),
paste0("Treatment x Republican"))
Variable Control x Republican Treatment x Republican
Partisan Self-Concept 3.14 (1.05) 3.08 (1.11)
Self-Reported Ideology 5.53 (1.08) 5.57 (1.20)
Difference in Affective Ratings:
Republican Party -0.25 (5.95) -1.90 (9.29)
Difference in Affective Ratings:
Democratic Party -0.18 (6.28) -0.67 (9.72)
Difference in Affective Ratings Between Parties -0.08 (9.35) -1.20 (13.19)
Moral Disengagement: Opposing Party 2.80 (1.23) 2.79 (1.18)
Individual SPV 20.50 (21.25) 18.53 (21.26)
Meta-Perceptions of Republican SPV 29.95 (19.20) 32.17 (24.24)
N 146 114

Democrats

# 4.1: make groups
gD_control <- 2
gD_treat <- 4
D_control <- descriptive_stats %>% filter(exp_group_numeric == gD_control)
D_treat <- descriptive_stats %>% filter(exp_group_numeric == gD_treat)
# 4.2: form column structure
dem_rows_se <- lapply(names(items), function(label) {
        cols    <- items[[label]]
        mean_col <- cols[1]; se_col <- cols[2]
# 4.3: how to pull means and SDs for each column
        valD_control_se <- if (!is.na(D_control[[mean_col]])) {
        if (mean_col == "count") sprintf("%d", D_control[[mean_col]]) else sprintf("%.2f (%.2f)", D_control[[mean_col]], D_control[[se_col]])
        } else NA_character_
        star <- if (label %in% names(stars_D)) stars_D[[label]] else ""
        valD_treat_se <- if (!is.na(D_treat[[mean_col]])) {
        if (mean_col == "count") sprintf("%d", D_treat[[mean_col]])
        else sprintf("%.2f (%.2f)%s", D_treat[[mean_col]], D_treat[[se_col]], star)
        } else NA_character_
# 4.4: bind into table
tibble::tibble(Variable = label, Group_D_control = valD_control_se, Group_D_treat = valD_treat_se)
}) %>% dplyr::bind_rows()
# 4.5: make the labels for table and fill in
nD_control_se <- D_control %>% pull(count) %>% unique()
nD_treat_se <- D_treat %>% pull(count) %>% unique()
colnames(dem_rows_se)[2:3] <- c(
paste0("Control x Democrat"),
paste0("Treatment x Democrat"))
Variable Control x Democrat Treatment x Democrat
Partisan Self-Concept 3.09 (1.02) 3.13 (1.02)
Self-Reported Ideology 2.24 (1.17) 2.00 (1.00)*
Difference in Affective Ratings:
Republican Party -0.18 (5.98) -2.20 (6.06)***
Difference in Affective Ratings:
Democratic Party -0.08 (5.61) 0.44 (7.93)
Difference in Affective Ratings Between Parties -0.10 (8.11) -2.93 (8.55)***
Moral Disengagement: Opposing Party 3.35 (0.98) 3.46 (1.07)
Individual SPV 21.91 (18.20) 25.79 (20.67)*
Meta-Perceptions of Republican SPV 41.77 (25.58) 47.50 (27.94)*
N 251 278

Combined

groups_se <- list(
list(num = 1, col = "Control x Republican"),
list(num = 3, col = "Treatment x Republican"),
list(num = 2, col = "Control x Democrat"),
list(num = 4, col = "Treatment x Democrat"))
# 5.2: form column structure
combined_rows_se <- lapply(names(items), function(label) {
cols     <- items[[label]]
mean_col <- cols[1]; se_col <- cols[2]
# 5.3: how to pull means and SDs for each column
vals_se <- lapply(groups, function(g) {
grp <- descriptive_stats %>% filter(exp_group_numeric == g$num)
if (!is.na(grp[[mean_col]])) {
if (mean_col == "count") sprintf("%d", grp[[mean_col]])
else sprintf("%.2f (%.2f)", grp[[mean_col]], grp[[se_col]])
} else NA_character_
})
# 5.4: bind into table
row <- tibble::tibble(Variable = label)
for (i in seq_along(groups)) row[[groups[[i]]$col]] <- vals_se[[i]]
row
}) %>% dplyr::bind_rows()
Variable Control x Republican Treatment x Republican Control x Democrat Treatment x Democrat
Partisan Self-Concept 3.14 (1.05) 3.08 (1.11) 3.09 (1.02) 3.13 (1.02)
Self-Reported Ideology 5.53 (1.08) 5.57 (1.20) 2.24 (1.17) 2.00 (1.00)
Difference in Affective Ratings:
Republican Party -0.25 (5.95) -1.90 (9.29) -0.18 (5.98) -2.20 (6.06)
Difference in Affective Ratings:
Democratic Party -0.18 (6.28) -0.67 (9.72) -0.08 (5.61) 0.44 (7.93)
Difference in Affective Ratings Between Parties -0.08 (9.35) -1.20 (13.19) -0.10 (8.11) -2.93 (8.55)
Moral Disengagement: Opposing Party 2.80 (1.23) 2.79 (1.18) 3.35 (0.98) 3.46 (1.07)
Individual SPV 20.50 (21.25) 18.53 (21.26) 21.91 (18.20) 25.79 (20.67)
Meta-Perceptions of Republican SPV 29.95 (19.20) 32.17 (24.24) 41.77 (25.58) 47.50 (27.94)
N 146 114 251 278

Correlations

Next, I will create a correlation matrix to test the relationship between individual SPV, meta-perceptions of Republicans’ SPV, and the difference between pre- and post-treatment affective ratings based on whether the party is one’s own party (ingroup) or the opposing party (outgroup).

# A: SPV v. in-party meta-SPV
cor.test(data_clean$SPV_individual, data_clean$SPV_meta_R)
## 
##  Pearson's product-moment correlation
## 
## data:  data_clean$SPV_individual and data_clean$SPV_meta_R
## t = 13.19, df = 776, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.3687373 0.4836738
## sample estimates:
##       cor 
## 0.4279341
# B: SPV v. ft_diff_out
cor.test(data_clean$SPV_individual, data_clean$ft_diff_out)
## 
##  Pearson's product-moment correlation
## 
## data:  data_clean$SPV_individual and data_clean$ft_diff_out
## t = 1.4789, df = 773, p-value = 0.1396
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.01737027  0.12308203
## sample estimates:
##        cor 
## 0.05311858
# C: SPV v. ft_diff_in
cor.test(data_clean$SPV_individual, data_clean$ft_diff_in)
## 
##  Pearson's product-moment correlation
## 
## data:  data_clean$SPV_individual and data_clean$ft_diff_in
## t = 1.7228, df = 775, p-value = 0.08533
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.00860548  0.13152680
## sample estimates:
##        cor 
## 0.06176504
# D: in-party meta-SPV v. ft_diff_in
cor.test(data_clean$SPV_meta_R, data_clean$ft_diff_in)
## 
##  Pearson's product-moment correlation
## 
## data:  data_clean$SPV_meta_R and data_clean$ft_diff_in
## t = 1.4783, df = 781, p-value = 0.1397
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.01730342  0.12243347
## sample estimates:
##        cor 
## 0.05282361
# E: out-party meta-SPV v. ft_diff_out
cor.test(data_clean$SPV_meta_R, data_clean$ft_diff_out)
## 
##  Pearson's product-moment correlation
## 
## data:  data_clean$SPV_meta_R and data_clean$ft_diff_out
## t = 0.70495, df = 778, p-value = 0.4811
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.04501197  0.09529419
## sample estimates:
##        cor 
## 0.02526553

I will also run two correlations designed to test whether the four SPV questions that are more concretely scenario-based correlate to the two SPV questions that are broader and vaguer in their depicted scenarios, allowing us to determine whether there may be any confounding effects of question wording.

cor.test(data_clean$SPV_indiv_scenario, data_clean$SPV_indiv_broad)
## 
##  Pearson's product-moment correlation
## 
## data:  data_clean$SPV_indiv_scenario and data_clean$SPV_indiv_broad
## t = 27.639, df = 777, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.6668296 0.7378436
## sample estimates:
##       cor 
## 0.7040927
cor.test(data_clean$SPV_meta_scenario, data_clean$SPV_meta_broad)
## 
##  Pearson's product-moment correlation
## 
## data:  data_clean$SPV_meta_scenario and data_clean$SPV_meta_broad
## t = 25.556, df = 779, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.6352486 0.7117409
## sample estimates:
##       cor 
## 0.6753066

I deviate from the analysis plan by constructing correlation matrices for all pre-treatment and post-treatment variables separately. All correlations reported above are still included.

pretreat_matrix <- data_clean %>%
  dplyr::select (condition_dummy, 
                 party_numeric, ideology_selfreport, maga, PID_strength, social_closeness, ft_rep_pre, ft_dem_pre)
pretreat_results <- round(cor(pretreat_matrix, use = "pairwise.complete.obs"), 2)
pretreat_stars <- cor_with_stars(pretreat_matrix)
condition_dummy party_numeric ideology_selfreport maga PID_strength social_closeness ft_rep_pre ft_dem_pre
condition_dummy -0.07* -0.11** -0.08* 0.00 -0.01 -0.10** 0.05
party_numeric -0.07* 0.85*** 0.53*** -0.06 0.33*** 0.79*** -0.65***
ideology_selfreport -0.11** 0.85*** 0.50*** 0.01 0.36*** 0.77*** -0.56***
maga -0.08* 0.53*** 0.50*** 0.14*** 0.10** 0.47*** -0.46***
PID_strength 0.00 -0.06 0.01 0.14*** -0.16*** 0.10** 0.29***
social_closeness -0.01 0.33*** 0.36*** 0.10** -0.16*** 0.51*** -0.05
ft_rep_pre -0.10** 0.79*** 0.77*** 0.47*** 0.10** 0.51*** -0.42***
ft_dem_pre 0.05 -0.65*** -0.56*** -0.46*** 0.29*** -0.05 -0.42***
postreat_matrix <- data_clean %>%
  dplyr::select (condition_dummy,
                 ft_rep_post, ft_dem_post, ft_diff_in, ft_diff_out,
                 moral_disengagement_outgroup, SPV_individual, SPV_meta_R, SPV_indiv_scenario, SPV_indiv_broad, SPV_meta_scenario, SPV_meta_broad)
postreat_results <- round(cor(postreat_matrix, use = "pairwise.complete.obs"), 2)
postreat_stars <- cor_with_stars(postreat_matrix)
condition_dummy ft_rep_post ft_dem_post ft_diff_in ft_diff_out moral_disengagement_outgroup SPV_individual SPV_meta_R SPV_indiv_scenario SPV_indiv_broad SPV_meta_scenario SPV_meta_broad
condition_dummy -0.13*** 0.05 -0.01 -0.12** 0.05 0.06 0.11** 0.06 0.04 0.11** 0.09*
ft_rep_post -0.13*** -0.44*** -0.07 0.07 -0.36*** -0.12*** -0.31*** -0.11** -0.11** -0.21*** -0.41***
ft_dem_post 0.05 -0.44*** 0.16*** -0.04 -0.01 0.01 0.12*** 0.02 0.01 0.06 0.20***
ft_diff_in -0.01 -0.07 0.16*** -0.00 0.11** 0.06 0.05 0.06 0.04 0.04 0.06
ft_diff_out -0.12** 0.07 -0.04 -0.00 -0.05 0.05 0.03 0.06 0.04 0.04 0.02
moral_disengagement_outgroup 0.05 -0.36*** -0.01 0.11** -0.05 0.30*** 0.24*** 0.29*** 0.27*** 0.18*** 0.27***
SPV_individual 0.06 -0.12*** 0.01 0.06 0.05 0.30*** 0.43*** 0.96*** 0.87*** 0.41*** 0.36***
SPV_meta_R 0.11** -0.31*** 0.12*** 0.05 0.03 0.24*** 0.43*** 0.41*** 0.38*** 0.95*** 0.86***
SPV_indiv_scenario 0.06 -0.11** 0.02 0.06 0.06 0.29*** 0.96*** 0.41*** 0.70*** 0.41*** 0.31***
SPV_indiv_broad 0.04 -0.11** 0.01 0.04 0.04 0.27*** 0.87*** 0.38*** 0.70*** 0.32*** 0.40***
SPV_meta_scenario 0.11** -0.21*** 0.06 0.04 0.04 0.18*** 0.41*** 0.95*** 0.41*** 0.32*** 0.68***
SPV_meta_broad 0.09* -0.41*** 0.20*** 0.06 0.02 0.27*** 0.36*** 0.86*** 0.31*** 0.40*** 0.68***

Furthermore, I will also run a correlation analysis between each of the eight emotions named in the PANAS-M—Anger, Shame, Guilt, Disgust, Fear, Anxiety, Sadness, and Happiness—and our pre-treatment measures of partisan self-concept, social closeness, affective ratings toward the Republican Party, and affective ratings toward the Democratic Party. I selected only pre-treatment measures since participants will only complete the PANAS-M scale following random assignment to the treatment or control group.

Here, I diverge from the pre-analysis plan to prevent any effects of post-treatment conditioning. That is, I only report correlations between the treatment and post-treatment variables such that the pre-treatment variables are not interpreted as corollaries for the significance of a treatment effect on any post-treatment variables.

emotion_matrix <- data_clean %>%
  dplyr::select (condition_dummy,
                 angry_dummy,
                 shame_dummy,
                 guilt_dummy,
                 disgust_dummy,
                 fear_dummy,
                 anxiety_dummy,
                 sadness_dummy,
                 happiness_dummy)
emotion_results <- round(cor(emotion_matrix, use = "pairwise.complete.obs"), 2)
emotion_stars <- cor_with_stars(emotion_matrix)
condition_dummy angry_dummy shame_dummy guilt_dummy disgust_dummy fear_dummy anxiety_dummy sadness_dummy happiness_dummy
condition_dummy 0.52*** 0.16*** -0.04 0.63*** 0.19*** 0.02 0.21*** -0.36***
angry_dummy 0.52*** 0.20*** 0.05 0.68*** 0.36*** 0.25*** 0.29*** -0.32***
shame_dummy 0.16*** 0.20*** 0.33*** 0.25*** 0.23*** 0.16*** 0.29*** -0.17***
guilt_dummy -0.04 0.05 0.33*** 0.06 0.22*** 0.22*** 0.18*** -0.11**
disgust_dummy 0.63*** 0.68*** 0.25*** 0.06 0.32*** 0.18*** 0.35*** -0.42***
fear_dummy 0.19*** 0.36*** 0.23*** 0.22*** 0.32*** 0.44*** 0.35*** -0.20***
anxiety_dummy 0.02 0.25*** 0.16*** 0.22*** 0.18*** 0.44*** 0.31*** -0.24***
sadness_dummy 0.21*** 0.29*** 0.29*** 0.18*** 0.35*** 0.35*** 0.31*** -0.28***
happiness_dummy -0.36*** -0.32*** -0.17*** -0.11** -0.42*** -0.20*** -0.24*** -0.28***

Conditional Average Treatment Effect (CATE)

Broadly speaking, all analyses will test the effect of shared partisan identity across the pre-identified set of hypothesis-specific outcome variables through a set of Ordinary Least Squares (OLS) linear regression models with heteroskedasticity-robust standard errors applied. This method will determine whether the contrast between Democratic and Republican participants varies in overall magnitude between the treatment and control groups.

library(readxl)
library(tidyverse)
library(psych)
library(interactions)
library(broom)
library(emmeans)
library(stargazer)
library(effsize)
library(modelsummary)
library(lsr)
library(rempsyc)
library(estimatr)
library(ggsignif)

To test Hypotheses 1a through 3b, I will conduct an Ordinary Least Squares (OLS) linear regression model with heteroskedasticity-robust standard errors applied. For Hypotheses 1a and 1b, I will regress the composite variable for meta-perceptions of the average Republican’s support for political violence onto a dichotomous variable denoting condition assignment, with the numeric version of the ANES 7-point party identification scale and the interaction between condition assignment and the numeric version of the ANES 7-point party identification scale as the two covariate terms.

H1<- lm_robust(SPV_meta_R ~ condition_dummy * party_numeric,
                       data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 45.096 2.185 20.639 0.000 40.807 49.386 781 SPV_meta_R
condition_dummy 6.309 3.255 1.938 0.053 -0.080 12.698 781 SPV_meta_R
party_numeric -2.298 0.482 -4.769 0.000 -3.244 -1.352 781 SPV_meta_R
condition_dummy:party_numeric -0.480 0.774 -0.621 0.535 -2.000 1.039 781 SPV_meta_R

To test Hypotheses 2a and 2b, I will regress the composite variable for moral disengagement toward the outgroup party onto a dichotomous variable denoting condition assignment, with the numeric version of the ANES 7-point party identification scale and the interaction between condition assignment and the numeric version of the ANES 7-point party identification scale as the two covariate terms.

H2<- lm_robust(moral_disengagement_outgroup ~ condition_dummy * party_numeric,
                       data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 3.521 0.088 40.227 0.000 3.349 3.693 785 moral_disengagement_outgroup
condition_dummy 0.108 0.129 0.838 0.402 -0.145 0.360 785 moral_disengagement_outgroup
party_numeric -0.113 0.025 -4.520 0.000 -0.162 -0.064 785 moral_disengagement_outgroup
condition_dummy:party_numeric -0.008 0.037 -0.217 0.828 -0.081 0.065 785 moral_disengagement_outgroup

To test Hypotheses 3a and 3b, I will regress the composite variable for individual support for political violence toward the outgroup party onto a dichotomous variable denoting condition assignment, with the numeric version of the ANES 7-point party identification scale and the interaction between condition assignment and the numeric version of the ANES 7-point party identification scale as the two covariate terms.

H3<- lm_robust(SPV_individual ~ condition_dummy * party_numeric,
                     data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 22.109 1.660 13.319 0.000 18.850 25.367 775 SPV_individual
condition_dummy 4.957 2.470 2.006 0.045 0.107 9.806 775 SPV_individual
party_numeric -0.216 0.455 -0.474 0.636 -1.109 0.678 775 SPV_individual
condition_dummy:party_numeric -0.912 0.684 -1.333 0.183 -2.256 0.431 775 SPV_individual

Secondary hypothesis tests will examine the significance of the treatment effect on post-treatment affective ratings by an Ordinary Least Squares (OLS) linear regression model with heteroskedasticity-robust standard errors applied. I will test whether there is an overall decrease in affective ratings toward the Republican Party among participants presented with the violence-endorsing message (H4a) by regressing post-treatment ratings toward the Republican Party onto a dichotomous variable representing the two experimental conditions, interacted with the numeric version of the ANES 7-point party identification scale.

H4a<- lm_robust(ft_rep_post ~ condition_dummy * party_numeric,
                        data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 2.740 1.763 1.554 0.121 -0.721 6.200 783 ft_rep_post
condition_dummy -4.922 2.369 -2.078 0.038 -9.573 -0.272 783 ft_rep_post
party_numeric 11.427 0.387 29.534 0.000 10.668 12.187 783 ft_rep_post
condition_dummy:party_numeric 0.118 0.556 0.212 0.832 -0.973 1.209 783 ft_rep_post

For Hypothesis 4b, I add the interaction between the dichotomous treatment variable and pre-treatment ratings toward the Republican Party as an additional covariate of interest.

H4b <- lm_robust(ft_rep_post ~ condition_dummy * party_numeric + condition_dummy * ft_rep_pre,
                                 data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -0.249 0.447 -0.557 0.578 -1.127 0.629 780 ft_rep_post
condition_dummy -2.175 0.673 -3.230 0.001 -3.497 -0.853 780 ft_rep_post
party_numeric 0.831 0.315 2.639 0.008 0.213 1.449 780 ft_rep_post
ft_rep_pre 0.934 0.023 41.335 0.000 0.889 0.978 780 ft_rep_post
condition_dummy:party_numeric 0.308 0.449 0.687 0.492 -0.572 1.189 780 ft_rep_post
condition_dummy:ft_rep_pre -0.023 0.033 -0.703 0.483 -0.088 0.042 780 ft_rep_post

For Hypotheses 5a through 5c, I will conduct a baseline OLS linear regression model with heteroskedasticity-robust standard errors, regressing post-treatment affective ratings toward the Republican Party onto a three-way interaction between the dichotomous treatment variable, the numeric version of the ANES 7-point party identification scale, and a numeric variable representing the three groups of partisan self-concept.

H5 <- lm_robust(ft_rep_post ~ condition_dummy * party_numeric * PID_bin,
                            data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -2.831 5.429 -0.522 0.602 -13.488 7.825 775 ft_rep_post
condition_dummy -10.179 7.768 -1.310 0.190 -25.428 5.071 775 ft_rep_post
party_numeric 9.448 1.478 6.392 0.000 6.547 12.349 775 ft_rep_post
PID_bin 4.044 3.119 1.296 0.195 -2.079 10.167 775 ft_rep_post
condition_dummy:party_numeric 1.048 2.063 0.508 0.611 -3.002 5.099 775 ft_rep_post
condition_dummy:PID_bin 2.699 4.391 0.615 0.539 -5.920 11.318 775 ft_rep_post
party_numeric:PID_bin 1.238 0.812 1.524 0.128 -0.357 2.833 775 ft_rep_post
condition_dummy:party_numeric:PID_bin -0.345 1.142 -0.302 0.763 -2.588 1.897 775 ft_rep_post

For Hypotheses 6a through 6c, I will regress post-treatment affective ratings toward the Democratic Party onto the same variables identified for testing Hypotheses 5a through 5c.

H6 <- lm_robust(ft_dem_post ~ condition_dummy * party_numeric * PID_bin,
                            data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 47.634 7.376 6.458 0.000 33.154 62.113 775 ft_dem_post
condition_dummy -1.507 9.832 -0.153 0.878 -20.808 17.794 775 ft_dem_post
party_numeric -2.290 2.191 -1.045 0.296 -6.591 2.011 775 ft_dem_post
PID_bin 22.525 3.958 5.691 0.000 14.755 30.295 775 ft_dem_post
condition_dummy:party_numeric 1.422 2.855 0.498 0.619 -4.184 7.027 775 ft_dem_post
condition_dummy:PID_bin 1.531 5.283 0.290 0.772 -8.839 11.901 775 ft_dem_post
party_numeric:PID_bin -3.236 1.187 -2.727 0.007 -5.565 -0.906 775 ft_dem_post
condition_dummy:party_numeric:PID_bin -1.151 1.574 -0.731 0.465 -4.239 1.938 775 ft_dem_post

Deviations from PAP

I convert party_numeric into a categorical variable to determine whether the above model-based predictions correspond to the raw data.

Hypothesis 1

H1_factor <- lm_robust(SPV_meta_R ~ condition_dummy * factor(party_numeric),
                       data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 42.221 2.174 19.420 0.000 37.953 46.489 773 SPV_meta_R
condition_dummy 2.437 3.244 0.751 0.453 -3.930 8.805 773 SPV_meta_R
factor(party_numeric)2 -1.669 3.714 -0.449 0.653 -8.959 5.621 773 SPV_meta_R
factor(party_numeric)3 0.329 4.590 0.072 0.943 -8.681 9.339 773 SPV_meta_R
factor(party_numeric)5 -11.253 3.849 -2.924 0.004 -18.809 -3.698 773 SPV_meta_R
factor(party_numeric)6 -15.086 3.209 -4.701 0.000 -21.386 -8.787 773 SPV_meta_R
factor(party_numeric)7 -10.043 3.529 -2.846 0.005 -16.969 -3.116 773 SPV_meta_R
condition_dummy:factor(party_numeric)2 7.684 5.320 1.444 0.149 -2.759 18.126 773 SPV_meta_R
condition_dummy:factor(party_numeric)3 4.963 6.450 0.770 0.442 -7.698 17.625 773 SPV_meta_R
condition_dummy:factor(party_numeric)5 4.695 7.355 0.638 0.523 -9.743 19.133 773 SPV_meta_R
condition_dummy:factor(party_numeric)6 0.599 4.988 0.120 0.904 -9.193 10.391 773 SPV_meta_R
condition_dummy:factor(party_numeric)7 -2.788 5.945 -0.469 0.639 -14.458 8.882 773 SPV_meta_R
emm_H1_factor <- emmeans(H1_factor, ~ condition_dummy | party_numeric,
                         vcov. = vcov(H1_factor))
contr_H1_factor <- contrast(emm_H1_factor,
                            method = list("Treatment - Control" = c(-1, 1)),
                            by = "party_numeric")
contr_H1_factor_df <- as.data.frame(confint(contr_H1_factor))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control 1 2.437 3.244 773 0.751 0.453
Treatment - Control 2 10.121 4.216 773 2.401 0.017
Treatment - Control 3 7.401 5.575 773 1.327 0.185
Treatment - Control 5 7.132 6.601 773 1.081 0.280
Treatment - Control 6 3.037 3.789 773 0.801 0.423
Treatment - Control 7 -0.350 4.982 773 -0.070 0.944

Hypothesis 2

H2_factor <- lm_robust(moral_disengagement_outgroup ~ condition_dummy * factor(party_numeric),
                       data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 3.530 0.081 43.449 0.000 3.371 3.690 777 moral_disengagement_outgroup
condition_dummy -0.035 0.120 -0.291 0.771 -0.271 0.201 777 moral_disengagement_outgroup
factor(party_numeric)2 -0.361 0.142 -2.553 0.011 -0.639 -0.084 777 moral_disengagement_outgroup
factor(party_numeric)3 -0.395 0.171 -2.319 0.021 -0.730 -0.061 777 moral_disengagement_outgroup
factor(party_numeric)5 -0.810 0.237 -3.412 0.001 -1.276 -0.344 777 moral_disengagement_outgroup
factor(party_numeric)6 -1.051 0.172 -6.109 0.000 -1.388 -0.713 777 moral_disengagement_outgroup
factor(party_numeric)7 -0.375 0.181 -2.074 0.038 -0.730 -0.020 777 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)2 0.405 0.212 1.916 0.056 -0.010 0.820 777 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)3 0.169 0.233 0.727 0.468 -0.288 0.626 777 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)5 -0.335 0.335 -1.001 0.317 -0.994 0.323 777 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)6 -0.015 0.247 -0.061 0.951 -0.500 0.470 777 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)7 0.316 0.262 1.207 0.228 -0.198 0.830 777 moral_disengagement_outgroup
emm_H2_factor <- emmeans(H2_factor, ~ condition_dummy | party_numeric,
                         vcov. = vcov(H2_factor))
contr_H2_factor <- contrast(emm_H2_factor,
                            method = list("Treatment - Control" = c(-1, 1)),
                            by = "party_numeric")
contr_H2_factor_df <- as.data.frame(confint(contr_H2_factor))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control 1 -0.035 0.120 777 -0.291 0.771
Treatment - Control 2 0.370 0.174 777 2.128 0.034
Treatment - Control 3 0.134 0.199 777 0.673 0.501
Treatment - Control 5 -0.370 0.313 777 -1.184 0.237
Treatment - Control 6 -0.050 0.216 777 -0.232 0.817
Treatment - Control 7 0.281 0.233 777 1.209 0.227

Hypothesis 3

H3_factor <- lm_robust(SPV_individual ~ condition_dummy * factor(party_numeric),
                       data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 22.551 1.661 13.576 0.000 19.290 25.811 767 SPV_individual
condition_dummy 1.466 2.405 0.610 0.542 -3.255 6.187 767 SPV_individual
factor(party_numeric)2 -1.403 2.461 -0.570 0.569 -6.234 3.427 767 SPV_individual
factor(party_numeric)3 -1.114 3.464 -0.322 0.748 -7.915 5.686 767 SPV_individual
factor(party_numeric)5 -3.185 4.237 -0.752 0.452 -11.503 5.133 767 SPV_individual
factor(party_numeric)6 -4.958 2.867 -1.729 0.084 -10.586 0.670 767 SPV_individual
factor(party_numeric)7 1.479 3.624 0.408 0.683 -5.635 8.594 767 SPV_individual
condition_dummy:factor(party_numeric)2 6.180 3.840 1.609 0.108 -1.358 13.718 767 SPV_individual
condition_dummy:factor(party_numeric)3 2.946 4.741 0.621 0.535 -6.361 12.253 767 SPV_individual
condition_dummy:factor(party_numeric)5 -4.624 6.547 -0.706 0.480 -17.476 8.229 767 SPV_individual
condition_dummy:factor(party_numeric)6 -4.370 4.044 -1.080 0.280 -12.309 3.570 767 SPV_individual
condition_dummy:factor(party_numeric)7 -1.111 5.637 -0.197 0.844 -12.178 9.955 767 SPV_individual
emm_H3_factor <- emmeans(H3_factor, ~ condition_dummy | party_numeric,
                         vcov. = vcov(H3_factor))
contr_H3_factor <- contrast(emm_H3_factor,
                            method = list("Treatment - Control" = c(-1, 1)),
                            by = "party_numeric")
contr_H3_factor_df <- as.data.frame(confint(contr_H3_factor))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control 1 1.466 2.405 767 0.610 0.542
Treatment - Control 2 7.647 2.994 767 2.554 0.011
Treatment - Control 3 4.412 4.086 767 1.080 0.281
Treatment - Control 5 -3.157 6.090 767 -0.518 0.604
Treatment - Control 6 -2.903 3.252 767 -0.893 0.372
Treatment - Control 7 0.355 5.099 767 0.070 0.944

Hypothesis 4a

H4a_factor <- lm_robust(ft_rep_post ~ condition_dummy * factor(party_numeric),
                        data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 17.937 1.724 10.406 0.000 14.553 21.321 775 ft_rep_post
condition_dummy -5.210 2.206 -2.361 0.018 -9.542 -0.879 775 ft_rep_post
factor(party_numeric)2 6.907 2.923 2.363 0.018 1.168 12.646 775 ft_rep_post
factor(party_numeric)3 4.616 3.592 1.285 0.199 -2.435 11.667 775 ft_rep_post
factor(party_numeric)5 42.676 3.853 11.077 0.000 35.113 50.239 775 ft_rep_post
factor(party_numeric)6 54.958 2.985 18.409 0.000 49.097 60.818 775 ft_rep_post
factor(party_numeric)7 67.304 2.550 26.389 0.000 62.298 72.311 775 ft_rep_post
condition_dummy:factor(party_numeric)2 2.687 4.092 0.657 0.512 -5.346 10.721 775 ft_rep_post
condition_dummy:factor(party_numeric)3 1.376 4.693 0.293 0.769 -7.836 10.589 775 ft_rep_post
condition_dummy:factor(party_numeric)5 -3.753 6.197 -0.606 0.545 -15.917 8.412 775 ft_rep_post
condition_dummy:factor(party_numeric)6 -2.371 4.050 -0.585 0.558 -10.321 5.579 775 ft_rep_post
condition_dummy:factor(party_numeric)7 7.398 3.627 2.039 0.042 0.277 14.518 775 ft_rep_post
emm_H4a_factor <- emmeans(H4a_factor, ~ condition_dummy | party_numeric,
                         vcov. = vcov(H4a_factor))
contr_H4a_factor <- contrast(emm_H4a_factor,
                            method = list("Treatment - Control" = c(-1, 1)),
                            by = "party_numeric")
contr_H4a_factor_df <- as.data.frame(confint(contr_H4a_factor))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control 1 -5.210 2.206 775 -2.361 0.018
Treatment - Control 2 -2.523 3.447 775 -0.732 0.464
Treatment - Control 3 -3.834 4.142 775 -0.926 0.355
Treatment - Control 5 -8.963 5.791 775 -1.548 0.122
Treatment - Control 6 -7.581 3.396 775 -2.232 0.026
Treatment - Control 7 2.187 2.879 775 0.760 0.448

Hypothesis 4b

H4b_factor <- lm_robust(ft_rep_post ~ condition_dummy * factor(party_numeric)
                                      + condition_dummy * ft_rep_pre,
                                      data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 0.786 0.379 2.074 0.038 0.042 1.529 772 ft_rep_post
condition_dummy -1.210 0.601 -2.013 0.044 -2.390 -0.030 772 ft_rep_post
factor(party_numeric)2 -0.259 0.820 -0.315 0.753 -1.869 1.352 772 ft_rep_post
factor(party_numeric)3 2.267 1.341 1.691 0.091 -0.365 4.899 772 ft_rep_post
factor(party_numeric)5 0.970 1.767 0.549 0.583 -2.499 4.439 772 ft_rep_post
factor(party_numeric)6 4.057 1.724 2.353 0.019 0.672 7.442 772 ft_rep_post
factor(party_numeric)7 4.638 1.983 2.339 0.020 0.745 8.530 772 ft_rep_post
ft_rep_pre 0.938 0.022 41.802 0.000 0.894 0.982 772 ft_rep_post
condition_dummy:factor(party_numeric)2 0.911 1.216 0.749 0.454 -1.477 3.298 772 ft_rep_post
condition_dummy:factor(party_numeric)3 -2.036 1.611 -1.264 0.207 -5.199 1.127 772 ft_rep_post
condition_dummy:factor(party_numeric)5 0.645 3.440 0.187 0.851 -6.109 7.398 772 ft_rep_post
condition_dummy:factor(party_numeric)6 1.265 2.557 0.495 0.621 -3.754 6.285 772 ft_rep_post
condition_dummy:factor(party_numeric)7 5.139 3.099 1.658 0.098 -0.944 11.222 772 ft_rep_post
condition_dummy:ft_rep_pre -0.044 0.035 -1.251 0.211 -0.114 0.025 772 ft_rep_post
emm_H4b_factor <- emmeans(H4b_factor, ~ condition_dummy | party_numeric,
                         vcov. = vcov(H4b_factor))
contr_H4b_factor <- contrast(emm_H4b_factor,
                            method = list("Treatment - Control" = c(-1, 1)),
                            by = "party_numeric")
contr_H4b_factor_df <- as.data.frame(confint(contr_H4b_factor))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control 1 -2.883 1.170 772 -2.464 0.014
Treatment - Control 2 -1.973 1.179 772 -1.673 0.095
Treatment - Control 3 -4.920 1.619 772 -3.039 0.002
Treatment - Control 5 -2.239 3.221 772 -0.695 0.487
Treatment - Control 6 -1.618 1.721 772 -0.940 0.347
Treatment - Control 7 2.256 2.133 772 1.058 0.291

For the following hypothesis groups, I collapsed Weak and Medium Partisan Self-Concept into the same group given the low N.

data_clean <- data_clean |>
  mutate(
    PID_bin_collapsed = case_when(
      PID_bin %in% c(0, 1) ~ "Weak-Medium",
      PID_bin == 2          ~ "Strong",
      TRUE                  ~ NA_character_
    ),
    PID_bin_collapsed = factor(PID_bin_collapsed,
                               levels = c("Weak-Medium", "Strong"))
  )

Hypothesis 5

H5_factor <- lm_robust(ft_rep_post ~ condition_dummy * factor(party_numeric) * PID_bin_collapsed,
                       data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 12.474 2.640 4.726 0.000 7.292 17.655 759 ft_rep_post
condition_dummy -4.768 3.731 -1.278 0.202 -12.092 2.557 759 ft_rep_post
factor(party_numeric)2 12.145 4.114 2.952 0.003 4.070 20.221 759 ft_rep_post
factor(party_numeric)3 10.453 4.280 2.442 0.015 2.050 18.856 759 ft_rep_post
factor(party_numeric)5 46.633 4.529 10.296 0.000 37.742 55.525 759 ft_rep_post
factor(party_numeric)6 52.860 4.936 10.709 0.000 43.169 62.550 759 ft_rep_post
factor(party_numeric)7 59.360 7.852 7.559 0.000 43.944 74.775 759 ft_rep_post
PID_bin_collapsedStrong 6.424 3.289 1.953 0.051 -0.032 12.881 759 ft_rep_post
condition_dummy:factor(party_numeric)2 -0.276 5.863 -0.047 0.962 -11.786 11.233 759 ft_rep_post
condition_dummy:factor(party_numeric)3 0.433 5.832 0.074 0.941 -11.017 11.882 759 ft_rep_post
condition_dummy:factor(party_numeric)5 -4.692 6.739 -0.696 0.486 -17.922 8.537 759 ft_rep_post
condition_dummy:factor(party_numeric)6 3.353 6.143 0.546 0.585 -8.705 15.412 759 ft_rep_post
condition_dummy:factor(party_numeric)7 -20.066 9.676 -2.074 0.038 -39.059 -1.072 759 ft_rep_post
condition_dummy:PID_bin_collapsedStrong -0.480 4.486 -0.107 0.915 -9.288 8.327 759 ft_rep_post
factor(party_numeric)2:PID_bin_collapsedStrong -5.985 5.879 -1.018 0.309 -17.526 5.557 759 ft_rep_post
factor(party_numeric)3:PID_bin_collapsedStrong -9.351 10.747 -0.870 0.385 -30.449 11.747 759 ft_rep_post
factor(party_numeric)5:PID_bin_collapsedStrong 9.135 6.962 1.312 0.190 -4.533 22.803 759 ft_rep_post
factor(party_numeric)6:PID_bin_collapsedStrong 7.942 5.710 1.391 0.165 -3.267 19.151 759 ft_rep_post
factor(party_numeric)7:PID_bin_collapsedStrong 8.781 8.301 1.058 0.290 -7.515 25.078 759 ft_rep_post
condition_dummy:factor(party_numeric)2:PID_bin_collapsedStrong 5.466 8.302 0.658 0.511 -10.833 21.764 759 ft_rep_post
condition_dummy:factor(party_numeric)3:PID_bin_collapsedStrong 4.315 13.350 0.323 0.747 -21.893 30.524 759 ft_rep_post
condition_dummy:factor(party_numeric)5:PID_bin_collapsedStrong -1.726 23.623 -0.073 0.942 -48.101 44.649 759 ft_rep_post
condition_dummy:factor(party_numeric)6:PID_bin_collapsedStrong -8.805 8.850 -0.995 0.320 -26.178 8.567 759 ft_rep_post
condition_dummy:factor(party_numeric)7:PID_bin_collapsedStrong 27.724 10.307 2.690 0.007 7.490 47.959 759 ft_rep_post
emm_H5_factor <- emmeans(H5_factor, ~ condition_dummy | party_numeric + PID_bin_collapsed,
                         vcov. = vcov(H5_factor))
contr_H5_factor <- contrast(emm_H5_factor,
                            method = list("Treatment - Control" = c(-1, 1)),
                            by = c("party_numeric", "PID_bin_collapsed"))
contr_H5_factor_df <- as.data.frame(confint(contr_H5_factor))
contrast party_numeric PID_bin_collapsed estimate SE df t.ratio p.value
Treatment - Control 1 Weak-Medium -4.768 3.731 759 -1.278 0.202
Treatment - Control 2 Weak-Medium -5.044 4.522 759 -1.115 0.265
Treatment - Control 3 Weak-Medium -4.335 4.483 759 -0.967 0.334
Treatment - Control 5 Weak-Medium -9.460 5.612 759 -1.686 0.092
Treatment - Control 6 Weak-Medium -1.414 4.880 759 -0.290 0.772
Treatment - Control 7 Weak-Medium -24.833 8.927 759 -2.782 0.006
Treatment - Control 1 Strong -5.248 2.491 759 -2.107 0.035
Treatment - Control 2 Strong -0.059 5.325 759 -0.011 0.991
Treatment - Control 3 Strong -0.500 11.748 759 -0.043 0.966
Treatment - Control 5 Strong -11.667 22.504 759 -0.518 0.604
Treatment - Control 6 Strong -10.700 5.863 759 -1.825 0.068
Treatment - Control 7 Strong 2.411 2.533 759 0.952 0.342

Hypothesis 6

H6_factor <- lm_robust(ft_dem_post ~ condition_dummy * factor(party_numeric) * PID_bin_collapsed,
                       data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 59.368 4.753 12.490 0.000 50.038 68.699 759 ft_dem_post
condition_dummy 7.749 6.818 1.137 0.256 -5.636 21.134 759 ft_dem_post
factor(party_numeric)2 -2.392 5.562 -0.430 0.667 -13.311 8.527 759 ft_dem_post
factor(party_numeric)3 -7.320 5.773 -1.268 0.205 -18.653 4.013 759 ft_dem_post
factor(party_numeric)5 -29.702 6.808 -4.362 0.000 -43.067 -16.336 759 ft_dem_post
factor(party_numeric)6 -13.405 7.351 -1.824 0.069 -27.835 1.025 759 ft_dem_post
factor(party_numeric)7 -29.535 14.188 -2.082 0.038 -57.387 -1.684 759 ft_dem_post
PID_bin_collapsedStrong 24.280 4.940 4.915 0.000 14.582 33.978 759 ft_dem_post
condition_dummy:factor(party_numeric)2 -7.575 8.073 -0.938 0.348 -23.423 8.273 759 ft_dem_post
condition_dummy:factor(party_numeric)3 -8.084 8.247 -0.980 0.327 -24.273 8.105 759 ft_dem_post
condition_dummy:factor(party_numeric)5 2.584 10.431 0.248 0.804 -17.893 23.061 759 ft_dem_post
condition_dummy:factor(party_numeric)6 -12.423 9.633 -1.290 0.198 -31.334 6.488 759 ft_dem_post
condition_dummy:factor(party_numeric)7 -7.083 18.906 -0.375 0.708 -44.197 30.031 759 ft_dem_post
condition_dummy:PID_bin_collapsedStrong -7.480 7.105 -1.053 0.293 -21.428 6.468 759 ft_dem_post
factor(party_numeric)2:PID_bin_collapsedStrong -4.697 6.258 -0.751 0.453 -16.982 7.587 759 ft_dem_post
factor(party_numeric)3:PID_bin_collapsedStrong -6.162 9.857 -0.625 0.532 -25.513 13.189 759 ft_dem_post
factor(party_numeric)5:PID_bin_collapsedStrong -5.280 14.478 -0.365 0.715 -33.701 23.142 759 ft_dem_post
factor(party_numeric)6:PID_bin_collapsedStrong -27.243 8.879 -3.068 0.002 -44.674 -9.811 759 ft_dem_post
factor(party_numeric)7:PID_bin_collapsedStrong -25.250 14.634 -1.725 0.085 -53.978 3.478 759 ft_dem_post
condition_dummy:factor(party_numeric)2:PID_bin_collapsedStrong 5.260 8.888 0.592 0.554 -12.188 22.707 759 ft_dem_post
condition_dummy:factor(party_numeric)3:PID_bin_collapsedStrong 14.148 12.505 1.131 0.258 -10.401 38.697 759 ft_dem_post
condition_dummy:factor(party_numeric)5:PID_bin_collapsedStrong -0.187 29.485 -0.006 0.995 -58.068 57.695 759 ft_dem_post
condition_dummy:factor(party_numeric)6:PID_bin_collapsedStrong 9.439 12.872 0.733 0.464 -15.830 34.709 759 ft_dem_post
condition_dummy:factor(party_numeric)7:PID_bin_collapsedStrong 1.551 19.647 0.079 0.937 -37.018 40.119 759 ft_dem_post
emm_H6_factor <- emmeans(H6_factor, ~ condition_dummy | party_numeric + PID_bin_collapsed,
                         vcov. = vcov(H6_factor))
contr_H6_factor <- contrast(emm_H6_factor,
                            method = list("Treatment - Control" = c(-1, 1)),
                            by = c("party_numeric", "PID_bin_collapsed"))
contr_H6_factor_df <- as.data.frame(confint(contr_H6_factor))
contrast party_numeric PID_bin_collapsed estimate SE df t.ratio p.value
Treatment - Control 1 Weak-Medium 7.749 6.818 759 1.137 0.256
Treatment - Control 2 Weak-Medium 0.174 4.323 759 0.040 0.968
Treatment - Control 3 Weak-Medium -0.334 4.639 759 -0.072 0.943
Treatment - Control 5 Weak-Medium 10.333 7.894 759 1.309 0.191
Treatment - Control 6 Weak-Medium -4.673 6.805 759 -0.687 0.492
Treatment - Control 7 Weak-Medium 0.667 17.634 759 0.038 0.970
Treatment - Control 1 Strong 0.269 1.998 759 0.135 0.893
Treatment - Control 2 Strong -2.047 3.135 759 -0.653 0.514
Treatment - Control 3 Strong 6.333 9.186 759 0.689 0.491
Treatment - Control 5 Strong 2.667 27.506 759 0.097 0.923
Treatment - Control 6 Strong -2.714 8.301 759 -0.327 0.744
Treatment - Control 7 Strong -5.263 4.957 759 -1.062 0.289

Planned Contrasts

Across all hypotheses, except Hypothesis 4b (which relies on a multivariate Ordinary Least Squares regression model), I will also employ planned contrasts using estimated marginal means to measure the difference in means between the treatment and control groups. This method will determine the model-based predictions of the average treatment effect for our identified groups of interest, measured as t-ratios and adjusted for covariates and unbalanced sample sizes. For our primary hypotheses (1a through 3b), along with Hypothesis 4a, our planned contrasts are fourfold: Republicans in the treatment condition versus Democrats in the treatment condition, Republicans in the control condition versus Democrats in the control condition, Republicans in the control condition versus Republicans in the treatment condition, and Democrats in the control condition versus Democrats in the treatment condition.

For all hypotheses, I define my groups based on the 7-point party identification scale detailed above, of which the six groups referenced are “Strong D,” “Weak D”, “Lean D”, “Lean R”, “Weak R,” and “Strong R”. As such, I deviate from the pre-analysis plan outlined for Hypotheses 1a through 4b, in which I defined my groups of interest as the control and treatment groups for Republicans and Democrats separately. However, this method allows me to ascertain deeper group-level differences in treatment effects that would otherwise not be observable if comparing treated Democrats to treated Republicans more broadly, for example.

Hypothesis 1

emm_H1<- emmeans(H1, ~ condition_dummy | party_numeric,
                 at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                 vcov. = vcov(H1))
contr_H1<- contrast(emm_H1,
                    method = list("Treatment - Control" = c(-1, 1)),
                    by = "party_numeric")
contr_H1_df <- as.data.frame(confint(contr_H1))
contr_H1_table <- summary(contr_H1) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_numeric = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                                labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control Strong D 5.828231 2.645362 781 2.2031886 0.0278727
Treatment - Control Weak D 5.347792 2.145046 781 2.4930894 0.0128697
Treatment - Control Lean D 4.867352 1.844564 781 2.6387546 0.0084869
Treatment - Control Lean R 3.906473 2.144420 781 1.8216922 0.0688841
Treatment - Control Weak R 3.426034 2.644516 781 1.2955241 0.1955223
Treatment - Control Strong R 2.945595 3.253660 781 0.9053174 0.3655765
pA_H1 <- data_clean |>
  filter(!is.na(exp_group_category)) |>
  group_by(party_numeric, exp_group_category) |>
  summarise(
    mean_y = mean(SPV_meta_R, na.rm = TRUE),
    se_y   = sd(SPV_meta_R, na.rm = TRUE) / sqrt(n()),
    .groups = "drop"
  ) |>
  ggplot(aes(x = factor(party_numeric), y = mean_y, color = exp_group_category)) +
  geom_errorbar(aes(ymin = mean_y - 1.96 * se_y,
                    ymax = mean_y + 1.96 * se_y),
                width = 0.15, linewidth = 0.6,
                position = position_dodge(width = 0.4)) +
  geom_point(size = 3, position = position_dodge(width = 0.4)) +
  scale_x_discrete(labels = pid_labels) +
  scale_color_manual(
    values = c(
      "Control R"   = "darkred",
      "Treatment R" = "hotpink",
      "Control D"   = "midnightblue",
      "Treatment D" = "dodgerblue"
    ),
    name = "Condition"
  ) +
  labs(title = "A", x = NULL,
       y = "Meta-Perceptions of Republican SPV\n(raw mean)") +
  base_theme +
  theme(legend.position = "bottom")

pB_H1 <- ggplot(contr_H1_factor_df, aes(x = party_numeric, y = estimate)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_smooth(method = "lm_robust", se = TRUE,
              color = "grey20", fill = "grey60",
              alpha = 0.2, linewidth = 0.9) +
  geom_errorbar(aes(ymin = lower.CL, ymax = upper.CL,
                    color = factor(party_numeric)),
                width = 0.15, linewidth = 0.6) +
  geom_point(aes(color = factor(party_numeric)), size = 3) +
  scale_color_manual(values = pid_colors, guide = "none") +
  scale_x_continuous(breaks = pid_breaks, labels = pid_labels) +
  labs(title = "B", x = "Party ID",
       y = "Difference in Means") +
  base_theme

Hypothesis 2

emm_H2<- emmeans(H2, ~ condition_dummy | party_numeric,
                 at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                 vcov. = vcov(H2))
contr_H2<- contrast(emm_H2,
                    method = list("Treatment - Control" = c(-1, 1)),
                    by = "party_numeric")
contr_H2_df <- as.data.frame(confint(contr_H2))
contr_H2_table <- summary(contr_H2) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_numeric = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                                labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control Strong D 0.0998034 0.1014437 785 0.9838303 0.3255021
Treatment - Control Weak D 0.0917773 0.0822541 785 1.1157771 0.2648590
Treatment - Control Lean D 0.0837512 0.0772990 785 1.0834710 0.2789321
Treatment - Control Lean R 0.0676990 0.1122377 785 0.6031754 0.5465662
Treatment - Control Weak R 0.0596729 0.1414570 785 0.4218450 0.6732536
Treatment - Control Strong R 0.0516469 0.1736587 785 0.2974044 0.7662365
pA_H2 <- data_clean |>
  filter(!is.na(exp_group_category)) |>
  group_by(party_numeric, exp_group_category) |>
  summarise(
    mean_y = mean(moral_disengagement_outgroup, na.rm = TRUE),
    se_y   = sd(moral_disengagement_outgroup, na.rm = TRUE) / sqrt(n()),
    .groups = "drop"
  ) |>
  ggplot(aes(x = factor(party_numeric), y = mean_y, color = exp_group_category)) +
  geom_errorbar(aes(ymin = mean_y - 1.96 * se_y,
                    ymax = mean_y + 1.96 * se_y),
                width = 0.15, linewidth = 0.6,
                position = position_dodge(width = 0.4)) +
  geom_point(size = 3, position = position_dodge(width = 0.4)) +
  scale_x_discrete(labels = pid_labels) +
  scale_color_manual(
    values = c(
      "Control R"   = "darkred",
      "Treatment R" = "hotpink",
      "Control D"   = "midnightblue",
      "Treatment D" = "dodgerblue"
    ),
    name = "Condition"
  ) +
  labs(title = "A", x = NULL,
       y = "Moral Disengagement (Out-Party)\n(raw mean)") +
  base_theme +
  theme(legend.position = "bottom")

pB_H2 <- ggplot(contr_H2_factor_df, aes(x = party_numeric, y = estimate)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_smooth(method = "lm_robust", se = TRUE,
              color = "grey20", fill = "grey60",
              alpha = 0.2, linewidth = 0.9) +
  geom_errorbar(aes(ymin = lower.CL, ymax = upper.CL,
                    color = factor(party_numeric)),
                width = 0.15, linewidth = 0.6) +
  geom_point(aes(color = factor(party_numeric)), size = 3) +
  scale_color_manual(values = pid_colors, guide = "none") +
  scale_x_continuous(breaks = pid_breaks, labels = pid_labels) +
  labs(title = "B", x = "Party ID",
       y = "Difference in Means") +
  base_theme

Hypothesis 3

emm_H3<- emmeans(H3, ~ condition_dummy | party_numeric,
                 at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                 vcov. = vcov(H3))
contr_H3<- contrast(emm_H3,
                    method = list("Treatment - Control" = c(-1, 1)),
                    by = "party_numeric")
contr_H3_df <- as.data.frame(confint(contr_H3))
contr_H3_table <- summary(contr_H3) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_numeric = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                                labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control Strong D 4.0441647 1.954600 775 2.0690494 0.0388725
Treatment - Control Weak D 3.1317498 1.573260 775 1.9906117 0.0468744
Treatment - Control Lean D 2.2193348 1.437483 775 1.5439036 0.1230199
Treatment - Control Lean R 0.3945049 2.014535 775 0.1958293 0.8447951
Treatment - Control Weak R -0.5179100 2.541483 775 -0.2037826 0.8385769
Treatment - Control Strong R -1.4303249 3.129928 775 -0.4569834 0.6478111
pA_H3 <- data_clean |>
  filter(!is.na(exp_group_category)) |>
  group_by(party_numeric, exp_group_category) |>
  summarise(
    mean_y = mean(SPV_individual, na.rm = TRUE),
    se_y   = sd(SPV_individual, na.rm = TRUE) / sqrt(n()),
    .groups = "drop"
  ) |>
  ggplot(aes(x = factor(party_numeric), y = mean_y, color = exp_group_category)) +
  geom_errorbar(aes(ymin = mean_y - 1.96 * se_y,
                    ymax = mean_y + 1.96 * se_y),
                width = 0.15, linewidth = 0.6,
                position = position_dodge(width = 0.4)) +
  geom_point(size = 3, position = position_dodge(width = 0.4)) +
  scale_x_discrete(labels = pid_labels) +
  scale_color_manual(
    values = c(
      "Control R"   = "darkred",
      "Treatment R" = "hotpink",
      "Control D"   = "midnightblue",
      "Treatment D" = "dodgerblue"
    ),
    name = "Condition"
  ) +
  labs(title = "A", x = NULL,
       y = "Individual SPV\n(raw mean)") +
  base_theme +
  theme(legend.position = "bottom")

pB_H3 <- ggplot(contr_H3_factor_df, aes(x = party_numeric, y = estimate)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_smooth(method = "lm_robust", se = TRUE,
              color = "grey20", fill = "grey60",
              alpha = 0.2, linewidth = 0.9) +
  geom_errorbar(aes(ymin = lower.CL, ymax = upper.CL,
                    color = factor(party_numeric)),
                width = 0.15, linewidth = 0.6) +
  geom_point(aes(color = factor(party_numeric)), size = 3) +
  scale_color_manual(values = pid_colors, guide = "none") +
  scale_x_continuous(breaks = pid_breaks, labels = pid_labels) +
  labs(title = "B", x = "Party ID",
       y = "Difference in Means") +
  base_theme

Hypothesis 4a

emm_H4a<- emmeans(H4a, ~ condition_dummy | party_numeric,
                 at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                 vcov. = vcov(H4a))
contr_H4a<- contrast(emm_H4a,
                    method = list("Treatment - Control" = c(-1, 1)),
                    by = "party_numeric")
contr_H4a_df <- as.data.frame(confint(contr_H4a))
contr_H4a_table <- summary(contr_H4a) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_numeric = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                                labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control Strong D -4.804423 1.949049 783 -2.465009 0.0139146
Treatment - Control Weak D -4.686386 1.613525 783 -2.904440 0.0037827
Treatment - Control Lean D -4.568350 1.423416 783 -3.209427 0.0013842
Treatment - Control Lean R -4.332277 1.650865 783 -2.624246 0.0088533
Treatment - Control Weak R -4.214241 2.000487 783 -2.106607 0.0354692
Treatment - Control Strong R -4.096204 2.428275 783 -1.686878 0.0920251
pA_H4a <- data_clean |>
  filter(!is.na(exp_group_category)) |>
  group_by(party_numeric, exp_group_category) |>
  summarise(
    mean_y = mean(ft_rep_post, na.rm = TRUE),
    se_y   = sd(ft_rep_post, na.rm = TRUE) / sqrt(n()),
    .groups = "drop"
  ) |>
  ggplot(aes(x = factor(party_numeric), y = mean_y, color = exp_group_category)) +
  geom_errorbar(aes(ymin = mean_y - 1.96 * se_y,
                    ymax = mean_y + 1.96 * se_y),
                width = 0.15, linewidth = 0.6,
                position = position_dodge(width = 0.4)) +
  geom_point(size = 3, position = position_dodge(width = 0.4)) +
  scale_x_discrete(labels = pid_labels) +
  scale_color_manual(
    values = c(
      "Control R"   = "darkred",
      "Treatment R" = "hotpink",
      "Control D"   = "midnightblue",
      "Treatment D" = "dodgerblue"
    ),
    name = "Condition"
  ) +
  labs(title = "A", x = NULL,
       y = "Affective Ratings:\nRepublican Party\n(raw mean)") +
  base_theme +
  theme(legend.position = "bottom")

pB_H4a <- ggplot() +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_smooth(data = contr_H4a_factor_df,
              aes(x = party_numeric, y = estimate),
              method = "lm_robust", se = TRUE,
              color = "grey20", fill = "grey60",
              alpha = 0.2, linewidth = 0.9) +
  geom_errorbar(data = contr_H4a_factor_df,
                aes(x = party_numeric, ymin = lower.CL, ymax = upper.CL,
                    color = factor(party_numeric)),
                width = 0.15, linewidth = 0.6) +
  geom_point(data = contr_H4a_factor_df,
             aes(x = party_numeric, y = estimate,
                 color = factor(party_numeric)),
             size = 3) +
  scale_color_manual(values = pid_colors, guide = "none") +
  scale_x_continuous(breaks = pid_breaks, labels = pid_labels) +
  labs(title = "B", x = "Party ID",
       y = "Difference in Means") +
  base_theme

Hypothesis 4b

emm_H4b<- emmeans(H4b, ~ condition_dummy | party_numeric,
                 at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                 vcov. = vcov(H4b))
contr_H4b<- contrast(emm_H4b,
                    method = list("Treatment - Control" = c(-1, 1)),
                    by = "party_numeric")
contr_H4b_df <- as.data.frame(confint(contr_H4b))
contr_H4b_table <- summary(contr_H4b) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_numeric = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                                labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value
Treatment - Control Strong D -2.7470714 1.1668581 780 -2.3542463 0.0188074
Treatment - Control Weak D -2.4389069 0.7780141 780 -3.1347848 0.0017842
Treatment - Control Lean D -2.1307424 0.5014888 780 -4.2488337 0.0000241
Treatment - Control Lean R -1.5144135 0.8667016 780 -1.7473297 0.0809737
Treatment - Control Weak R -1.2062490 1.2667547 780 -0.9522357 0.3412724
Treatment - Control Strong R -0.8980846 1.6913308 780 -0.5309929 0.5955749
pA_H4b <- data_clean |>
  filter(!is.na(exp_group_category)) |>
  group_by(party_numeric, exp_group_category) |>
  summarise(
    mean_y = mean(ft_rep_pre, na.rm = TRUE),
    se_y   = sd(ft_rep_pre, na.rm = TRUE) / sqrt(n()),
    .groups = "drop"
  ) |>
  ggplot(aes(x = factor(party_numeric), y = mean_y, color = exp_group_category)) +
  geom_errorbar(aes(ymin = mean_y - 1.96 * se_y,
                    ymax = mean_y + 1.96 * se_y),
                width = 0.15, linewidth = 0.6,
                position = position_dodge(width = 0.4)) +
  geom_point(size = 3, position = position_dodge(width = 0.4)) +
  scale_x_discrete(labels = pid_labels) +
  scale_color_manual(
    values = c(
      "Control R"   = "darkred",
      "Treatment R" = "hotpink",
      "Control D"   = "midnightblue",
      "Treatment D" = "dodgerblue"
    ),
    name = "Condition"
  ) +
  labs(title = "A", x = NULL,
       y = "Affective Ratings:\nRepublican Party\n(pre-treatment mean)") +
  base_theme +
  theme(legend.position = "bottom")

pB_H4b <- ggplot() +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_smooth(data = contr_H4b_factor_df,
              aes(x = party_numeric, y = estimate),
              method = "lm_robust", se = TRUE,
              color = "grey20", fill = "grey60",
              alpha = 0.2, linewidth = 0.9) +
  geom_errorbar(data = contr_H4b_factor_df,
                aes(x = party_numeric, ymin = lower.CL, ymax = upper.CL,
                    color = factor(party_numeric)),
                width = 0.15, linewidth = 0.6) +
  geom_point(data = contr_H4b_factor_df,
             aes(x = party_numeric, y = estimate,
                 color = factor(party_numeric)),
             size = 3) +
  scale_color_manual(values = pid_colors, guide = "none") +
  scale_x_continuous(breaks = pid_breaks, labels = pid_labels) +
  labs(title = "B", x = "Party ID",
       y = "Difference in Means") +
  base_theme

Hypothesis 5

For Hypotheses 5a through 6c, I establish three sets of planned contrasts based on partisan self-concept: weaker-identifying Republicans (H5a and H6a), stronger-identifying Republicans (H5b and H6b), and stronger-identifying Democrats (H5c and H6c). I created these bins based on the 7-point party identification scale detailed above. Given that the six groups referenced are “Strong D,” “Weak D”, “Lean D”, “Lean R”, “Weak R,” and “Strong R”, I plan to focus on the results for “Lean R”, “Strong D,” and “Strong R” as our primary groups of interest for each of the respective hypotheses.

emm_H5 <- emmeans(H5, ~ condition_dummy | party_numeric + PID_bin,
                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7), PID_bin = c(0, 1, 2)),
                       vcov. = vcov(H5))
contr_H5 <- contrast(emm_H5,
            method = list("Treatment - Control" = c(-1, 1)),
            by = c("party_numeric", "PID_bin"))
contr_table_H5 <- summary(contr_H5) |>
  as.data.frame() |>
          dplyr::select(contrast, party_numeric, PID_bin, estimate, SE, df, t.ratio, p.value) |>
          mutate(
            party_numeric = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                                   labels = c("Strong D", "Weak D", "Lean D",
                                              "Lean R", "Weak R", "Strong R")),
            PID_bin = factor(PID_bin, levels = 0:2,
                             labels = c("Weak", "Medium", "Strong")))
contrast party_numeric PID_bin estimate SE df t.ratio p.value
Treatment - Control Strong D Weak -9.130332 6.022727 775 -1.5159797 0.1299322
Treatment - Control Weak D Weak -8.081846 4.551179 775 -1.7757699 0.0761632
Treatment - Control Lean D Weak -7.033361 3.696906 775 -1.9024991 0.0574763
Treatment - Control Lean R Weak -4.936390 5.011645 775 -0.9849838 0.3249394
Treatment - Control Weak R Weak -3.887904 6.603952 775 -0.5887239 0.5562181
Treatment - Control Strong R Weak -2.839418 8.403670 775 -0.3378784 0.7355463
Treatment - Control Strong D Medium -6.776571 2.978819 775 -2.2749190 0.0231832
Treatment - Control Weak D Medium -6.073276 2.262054 775 -2.6848501 0.0074113
Treatment - Control Lean D Medium -5.369981 1.830555 775 -2.9335263 0.0034502
Treatment - Control Lean R Medium -3.963392 2.406359 775 -1.6470494 0.0999533
Treatment - Control Weak R Medium -3.260097 3.161669 775 -1.0311317 0.3028008
Treatment - Control Strong R Medium -2.556802 4.023959 775 -0.6353945 0.5253587
Treatment - Control Strong D Strong -4.422810 2.290807 775 -1.9306776 0.0538874
Treatment - Control Weak D Strong -4.064706 1.931356 775 -2.1045872 0.0356487
Treatment - Control Lean D Strong -3.706602 1.702886 775 -2.1766592 0.0298072
Treatment - Control Lean R Strong -2.990393 1.816931 775 -1.6458485 0.1002004
Treatment - Control Weak R Strong -2.632289 2.129078 775 -1.2363519 0.2167023
Treatment - Control Strong R Strong -2.274185 2.540089 775 -0.8953170 0.3708957

Weak/Med Partisan Self-Concept

p_H5_weakmed <- make_H5_H6_panels(
  "ft_rep_post", "Weak-Medium", contr_H5_factor_df,
  "Affective Ratings:\nRepublican Party\n(raw mean)",
  "Figure 4.5a: Republican Party Ratings — Weak-Medium PID Strength"
)
p_H5_weakmed

Strong Partisan Self-Concept

p_H5_strong <- make_H5_H6_panels(
  "ft_rep_post", "Strong", contr_H5_factor_df,
  "Affective Ratings:\nRepublican Party\n(raw mean)",
  "Figure 4.5b: Republican Party Ratings — Strong PID Strength"
)
p_H5_strong

Hypothesis 6

emm_H6 <- emmeans(H6, ~ condition_dummy | party_numeric + PID_bin,
                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7), PID_bin = c(0, 1, 2)),
                       vcov. = vcov(H6))
contr_H6 <- contrast(emm_H6,
            method = list("Treatment - Control" = c(-1, 1)),
            by = c("party_numeric", "PID_bin"))
contr_table_H6 <- summary(contr_H6) |>
  as.data.frame() |>
          dplyr::select(contrast, party_numeric, PID_bin, estimate, SE, df, t.ratio, p.value) |>
          mutate(
            party_numeric = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                                   labels = c("Strong D", "Weak D", "Lean D",
                                              "Lean R", "Weak R", "Strong R")),
            PID_bin = factor(PID_bin, levels = 0:2,
                             labels = c("Weak", "Medium", "Strong")))
contrast party_numeric PID_bin estimate SE df t.ratio p.value
Treatment - Control Strong D Weak -0.0856868 7.348324 775 -0.0116607 0.9906993
Treatment - Control Weak D Weak 1.3358716 5.256455 775 0.2541393 0.7994554
Treatment - Control Lean D Weak 2.7574300 4.191687 775 0.6578329 0.5108408
Treatment - Control Lean R Weak 5.6005468 6.809738 775 0.8224321 0.4110840
Treatment - Control Weak R Weak 7.0221052 9.232274 775 0.7606041 0.4471249
Treatment - Control Strong R Weak 8.4436637 11.849250 775 0.7125906 0.4763136
Treatment - Control Strong D Medium 0.2947229 3.597686 775 0.0819201 0.9347314
Treatment - Control Weak D Medium 0.5656399 2.583925 775 0.2189073 0.8267799
Treatment - Control Lean D Medium 0.8365569 2.064616 775 0.4051877 0.6854514
Treatment - Control Lean R Medium 1.3783909 3.315501 775 0.4157414 0.6777144
Treatment - Control Weak R Medium 1.6493078 4.487369 775 0.3675445 0.7133132
Treatment - Control Strong R Medium 1.9202248 5.756133 775 0.3335963 0.7387744
Treatment - Control Strong D Strong 0.6751326 1.781732 775 0.3789193 0.7048516
Treatment - Control Weak D Strong -0.2045918 1.544002 775 -0.1325075 0.8946173
Treatment - Control Lean D Strong -1.0843163 1.701438 775 -0.6372940 0.5241216
Treatment - Control Lean R Strong -2.8437651 2.796697 775 -1.0168299 0.3095517
Treatment - Control Weak R Strong -3.7234896 3.498169 775 -1.0644109 0.2874741
Treatment - Control Strong R Strong -4.6032140 4.237268 775 -1.0863637 0.2776559

Weak/Med Partisan Self-Concept

p_H6_weakmed <- make_H5_H6_panels(
  "ft_dem_post", "Weak-Medium", contr_H6_factor_df,
  "Affective Ratings:\nDemocratic Party\n(raw mean)",
  "Figure 4.6a: Democratic Party Ratings — Weak-Medium PID Strength"
)
p_H6_weakmed

Strong Partisan Self-Concept

p_H6_strong <- make_H5_H6_panels(
  "ft_dem_post", "Strong", contr_H6_factor_df,
  "Affective Ratings:\nDemocratic Party\n(raw mean)",
  "Figure 4.6b: Democratic Party Ratings — Strong PID Strength"
)
p_H6_strong

Exploratory Analyses

Post-Treatment FT as Outcome Variable

In addition to the pre-planned analyses, I will perform exploratory analyses on the post-treatment affective ratings for both parties, as I found during the pilot study that this measure was the only significant variable across all hypothesis models. I will first employ two Ordinary Least Squares (OLS) linear regression models with heteroskedasticity-robust standard errors, one for each party, regressing the party-specific post-treatment feeling thermometer ratings onto a three-way interaction between the treatment, partisan identity, and party-specific pre-treatment feeling thermometer rating as a continuous moderator. No other covariates will be included at outset.

model_ft_dem <- lm_robust(ft_dem_post ~ condition_dummy*PID_dummy*ft_dem_pre, data = data_clean)
model_ft_rep <- lm_robust(ft_rep_post ~ condition_dummy*PID_dummy*ft_rep_pre, data = data_clean)
FT Democrat
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 1.129 1.335 0.846 0.398 -1.491 3.749 777 ft_dem_post
condition_dummy 0.167 1.699 0.098 0.922 -3.168 3.503 777 ft_dem_post
PID_dummy -0.088 1.500 -0.059 0.953 -3.034 2.857 777 ft_dem_post
ft_dem_pre 0.983 0.016 60.641 0.000 0.951 1.015 777 ft_dem_post
condition_dummy:PID_dummy 1.126 2.260 0.498 0.618 -3.309 5.562 777 ft_dem_post
condition_dummy:ft_dem_pre 0.005 0.021 0.240 0.810 -0.036 0.046 777 ft_dem_post
PID_dummy:ft_dem_pre -0.017 0.025 -0.686 0.493 -0.066 0.032 777 ft_dem_post
condition_dummy:PID_dummy:ft_dem_pre -0.056 0.052 -1.075 0.283 -0.159 0.046 777 ft_dem_post
FT Republican
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 0.972 0.562 1.730 0.084 -0.131 2.075 778 ft_rep_post
condition_dummy -1.569 0.685 -2.290 0.022 -2.913 -0.224 778 ft_rep_post
PID_dummy 2.611 2.675 0.976 0.329 -2.641 7.862 778 ft_rep_post
ft_rep_pre 0.946 0.026 36.540 0.000 0.895 0.996 778 ft_rep_post
condition_dummy:PID_dummy 0.975 3.403 0.287 0.774 -5.704 7.654 778 ft_rep_post
condition_dummy:ft_rep_pre -0.030 0.039 -0.769 0.442 -0.107 0.047 778 ft_rep_post
PID_dummy:ft_rep_pre 0.004 0.041 0.086 0.932 -0.077 0.084 778 ft_rep_post
condition_dummy:PID_dummy:ft_rep_pre 0.014 0.060 0.236 0.813 -0.103 0.132 778 ft_rep_post
# |--------------------------------|
#         EXP_GROUP_CATEGORY
# |--------------------------------|
# 1.1: plot for Democratic Party FT
ggplot(data_clean, aes(x = ft_dem_pre, y = ft_dem_post,
                       color = exp_group_category, fill = exp_group_category, group = exp_group_category)) +
  geom_point() + 
  geom_smooth(method = "lm_robust", se = TRUE) +
  scale_color_manual(name = "Group", values = c("firebrick", "midnightblue","violetred", "dodgerblue"),
                     labels = c("Control (R)", "Control (D)", "Treatment (R)", "Treatment (D)")) +
  scale_fill_manual(name = "Group", values = c("lightsalmon", "lightsteelblue","lightpink", "lightblue"),
                    labels = c("Control (R)", "Control (D)", "Treatment (R)", "Treatment (D)")) +
  labs(x = "Pre-Treatment Ratings",
       y = "Post-Treatment Ratings",
       title = "Post-Treatment Affective Ratings for Democratic Party By Pre-Treatment Affective Ratings") +
  theme_minimal()

# 1.2: plot for Republican Party FT
ggplot(data_clean, aes(x = ft_rep_pre, y = ft_rep_post,
                       color = exp_group_category, fill = exp_group_category, group = exp_group_category)) +
  geom_point() +
  geom_smooth(method = "lm_robust", se = TRUE) +
  scale_color_manual(name = "Group", values = c("firebrick", "midnightblue","violetred", "dodgerblue"),
                     labels = c("Control (R)", "Control (D)", "Treatment (R)", "Treatment (D)")) +
  scale_fill_manual(name = "Group", values = c("lightsalmon", "lightsteelblue","lightpink", "lightblue"),
                    labels = c("Control (R)", "Control (D)", "Treatment (R)", "Treatment (D)")) +
  labs(x = "Pre-Treatment Ratings",
       y = "Post-Treatment Ratings",
       title = "Post-Treatment Affective Ratings for Republican Party By Pre-Treatment Affective Ratings") +
  theme_minimal()

# |--------------------------------|
#            PARTY_BIN
# |--------------------------------|
# 2.1: plot for Democratic Party FT
ggplot(data_clean, aes(x = ft_dem_pre, y = ft_dem_post,
                       color = party_category, fill = party_category, group = party_category)) +
  geom_point() + 
  geom_smooth(method = "lm_robust", se = TRUE) +
  scale_color_manual(name = "Party ID", values = c("orchid", "dodgerblue", "firebrick"),
                     labels = c("Independent", "Democrat", "Republican")) +
  scale_fill_manual(name = "Party ID", values = c("thistle", "lightblue", "lightpink"),
                    labels = c("Independent", "Democrat", "Republican")) +
  labs(x = "Pre-Treatment Ratings",
       y = "Post-Treatment Ratings",
       title = "Post-Treatment Affective Ratings for Democratic Party By Party ID") +
  theme_minimal()

# 2.2: plot for Democratic Party FT   
ggplot(data_clean, aes(x = ft_rep_pre, y = ft_rep_post,
                       color = party_category, fill = party_category, group = party_category)) +
  geom_point() +
  geom_smooth(method = "lm_robust", se = TRUE) +
  scale_color_manual(name = "Party ID", values = c("orchid", "dodgerblue", "firebrick"),
                     labels = c("Independent", "Democrat", "Republican")) +
  scale_fill_manual(name = "Party ID", values = c("thistle", "lightblue", "lightpink"),
                    labels = c("Independent", "Democrat", "Republican")) +
  labs(x = "Pre-Treatment Ratings",
       y = "Post-Treatment Ratings",
       title = "Post-Treatment Affective Ratings for Republican Party By Party ID") +
  theme_minimal()

I will then craft separate exploratory models adding the following covariates individually: PID strength, MAGA support, ideology, and the expanded party scale. Given that I focus on both affective ratings for the Democratic and Republican Party post-treatment, I will produce two models per individual covariate, i.e., two models for PID strength, two for MAGA support, etc. For the expanded party scale, I will replace the dichotomous variable for partisan identification with the 7-point ANES scale, producing a three-way interaction between the treatment, the expanded party scale, and the party-specific pre-treatment feeling thermometer rating. For PID strength, MAGA support, and ideology, I will add a three-way interaction between the treatment, the dichotomous measure of partisanship, and the chosen covariate to the initial model described.

Partisan Self-Concept

Democrats

lm_dem_pidstr <- lm_robust(ft_dem_post ~ condition_dummy*PID_dummy*ft_dem_pre
                           + condition_dummy*PID_dummy*PID_strength,
                           data = data_clean, se_type = "HC2")
FT Democrat
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 0.311 1.148 0.271 0.787 -1.943 2.564 769 ft_dem_post
condition_dummy 0.317 1.587 0.200 0.842 -2.799 3.433 769 ft_dem_post
PID_dummy -0.065 1.793 -0.036 0.971 -3.584 3.454 769 ft_dem_post
ft_dem_pre 0.950 0.033 28.680 0.000 0.885 1.015 769 ft_dem_post
PID_strength 1.026 0.699 1.468 0.143 -0.346 2.398 769 ft_dem_post
condition_dummy:PID_dummy 6.639 4.735 1.402 0.161 -2.656 15.935 769 ft_dem_post
condition_dummy:ft_dem_pre 0.007 0.041 0.176 0.860 -0.073 0.088 769 ft_dem_post
PID_dummy:ft_dem_pre 0.021 0.038 0.547 0.584 -0.053 0.095 769 ft_dem_post
condition_dummy:PID_strength -0.112 0.942 -0.119 0.905 -1.962 1.738 769 ft_dem_post
PID_dummy:PID_strength -0.889 0.849 -1.047 0.296 -2.557 0.778 769 ft_dem_post
condition_dummy:PID_dummy:ft_dem_pre -0.073 0.065 -1.122 0.262 -0.201 0.055 769 ft_dem_post
condition_dummy:PID_dummy:PID_strength -1.487 1.567 -0.949 0.343 -4.563 1.590 769 ft_dem_post
make_pA(data_clean, "PID_strength", "Partisan Self-Concept\n(raw mean)") /
  make_pB(contr_ft_D_df, "FT: Democratic Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Democratic Party) by Party ID | Covariate: Partisan Self-Concept")

Republicans

lm_rep_pidstr <- lm_robust(ft_rep_post ~ condition_dummy*PID_dummy*ft_rep_pre
                           + condition_dummy*PID_dummy*PID_strength,
                           data = data_clean, se_type = "HC2")
FT Republican
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 1.868 1.451 1.287 0.198 -0.981 4.716 770 ft_rep_post
condition_dummy -1.504 1.983 -0.759 0.448 -5.396 2.388 770 ft_rep_post
PID_dummy 0.207 2.673 0.077 0.938 -5.040 5.453 770 ft_rep_post
ft_rep_pre 0.944 0.027 35.127 0.000 0.891 0.997 770 ft_rep_post
PID_strength -0.281 0.345 -0.815 0.415 -0.959 0.397 770 ft_rep_post
condition_dummy:PID_dummy 1.230 3.854 0.319 0.750 -6.335 8.796 770 ft_rep_post
condition_dummy:ft_rep_pre -0.030 0.040 -0.735 0.462 -0.108 0.049 770 ft_rep_post
PID_dummy:ft_rep_pre -0.036 0.054 -0.658 0.511 -0.143 0.071 770 ft_rep_post
condition_dummy:PID_strength -0.022 0.510 -0.042 0.966 -1.024 0.980 770 ft_rep_post
PID_dummy:PID_strength 1.788 0.824 2.168 0.030 0.169 3.406 770 ft_rep_post
condition_dummy:PID_dummy:ft_rep_pre -0.065 0.093 -0.700 0.484 -0.246 0.117 770 ft_rep_post
condition_dummy:PID_dummy:PID_strength 1.731 1.503 1.152 0.250 -1.219 4.681 770 ft_rep_post
make_pA(data_clean, "PID_strength", "Partisan Self-Concept\n(raw mean)") /
  make_pB(contr_ft_R_df, "FT: Republican Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Republican Party) by Party ID | Covariate: Partisan Self-Concept")

MAGA

Democrats

lm_maga_D <- lm_robust(ft_dem_post ~ condition_dummy*PID_dummy*ft_dem_pre
                       + maga*condition_dummy*PID_dummy, data = data_clean)
FT Democrat
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 1.129 1.335 0.846 0.398 -1.491 3.749 775 ft_dem_post
condition_dummy 0.167 1.699 0.098 0.922 -3.169 3.503 775 ft_dem_post
PID_dummy -0.554 1.618 -0.342 0.732 -3.730 2.623 775 ft_dem_post
ft_dem_pre 0.983 0.016 60.641 0.000 0.951 1.015 775 ft_dem_post
maga NA NA NA NA NA NA NA ft_dem_post
condition_dummy:PID_dummy 2.555 2.463 1.038 0.300 -2.279 7.390 775 ft_dem_post
condition_dummy:ft_dem_pre 0.005 0.021 0.240 0.810 -0.036 0.046 775 ft_dem_post
PID_dummy:ft_dem_pre -0.013 0.025 -0.496 0.620 -0.062 0.037 775 ft_dem_post
condition_dummy:maga -2.496 2.042 -1.223 0.222 -6.503 1.512 775 ft_dem_post
PID_dummy:maga 0.783 1.066 0.734 0.463 -1.310 2.875 775 ft_dem_post
condition_dummy:PID_dummy:ft_dem_pre -0.073 0.053 -1.365 0.173 -0.178 0.032 775 ft_dem_post
condition_dummy:PID_dummy:maga NA NA NA NA NA NA NA ft_dem_post
make_pA(data_clean, "maga", "MAGA Support\n(raw mean)") /
  make_pB(contr_ft_D_df, "FT: Democratic Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Democratic Party) by Party ID | Covariate: MAGA Support")

Republicans

lm_maga_R <- lm_robust(ft_rep_post ~ condition_dummy*PID_dummy*ft_rep_pre
                       + maga*condition_dummy*PID_dummy, data = data_clean)
FT Republican
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 0.972 0.562 1.730 0.084 -0.131 2.075 776 ft_rep_post
condition_dummy -1.569 0.685 -2.290 0.022 -2.913 -0.224 776 ft_rep_post
PID_dummy 2.491 2.633 0.946 0.345 -2.678 7.660 776 ft_rep_post
ft_rep_pre 0.946 0.026 36.540 0.000 0.895 0.996 776 ft_rep_post
maga NA NA NA NA NA NA NA ft_rep_post
condition_dummy:PID_dummy 0.433 3.267 0.133 0.895 -5.980 6.846 776 ft_rep_post
condition_dummy:ft_rep_pre -0.030 0.039 -0.769 0.442 -0.107 0.047 776 ft_rep_post
PID_dummy:ft_rep_pre 0.009 0.041 0.219 0.827 -0.071 0.089 776 ft_rep_post
condition_dummy:maga 5.111 1.724 2.965 0.003 1.727 8.495 776 ft_rep_post
PID_dummy:maga -0.724 0.888 -0.815 0.415 -2.466 1.019 776 ft_rep_post
condition_dummy:PID_dummy:ft_rep_pre -0.001 0.060 -0.015 0.988 -0.118 0.117 776 ft_rep_post
condition_dummy:PID_dummy:maga NA NA NA NA NA NA NA ft_rep_post
make_pA(data_clean, "maga", "MAGA Support\n(raw mean)") /
  make_pB(contr_ft_R_df, "FT: Republican Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Republican Party) by Party ID | Covariate: MAGA Support")

Ideology

Democrats

lm_ideology_selfreport_D <- lm_robust(
  ft_dem_post ~ condition_dummy*PID_dummy*ft_dem_pre
  + condition_dummy*PID_dummy*ideology_selfreport,
  data = data_clean)
FT Democrat
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 0.396 1.377 0.287 0.774 -2.307 3.099 773 ft_dem_post
condition_dummy 2.330 2.021 1.153 0.249 -1.637 6.297 773 ft_dem_post
PID_dummy 0.945 3.390 0.279 0.781 -5.710 7.600 773 ft_dem_post
ft_dem_pre 0.985 0.015 65.806 0.000 0.955 1.014 773 ft_dem_post
ideology_selfreport 0.273 0.551 0.495 0.621 -0.810 1.355 773 ft_dem_post
condition_dummy:PID_dummy 13.045 7.857 1.660 0.097 -2.379 28.469 773 ft_dem_post
condition_dummy:ft_dem_pre 0.003 0.020 0.143 0.886 -0.036 0.042 773 ft_dem_post
PID_dummy:ft_dem_pre -0.019 0.024 -0.817 0.414 -0.066 0.027 773 ft_dem_post
condition_dummy:ideology_selfreport -0.973 0.747 -1.302 0.193 -2.439 0.494 773 ft_dem_post
PID_dummy:ideology_selfreport -0.323 0.755 -0.427 0.669 -1.805 1.160 773 ft_dem_post
condition_dummy:PID_dummy:ft_dem_pre -0.087 0.058 -1.500 0.134 -0.200 0.027 773 ft_dem_post
condition_dummy:PID_dummy:ideology_selfreport -1.343 1.377 -0.976 0.330 -4.047 1.360 773 ft_dem_post
make_pA(data_clean, "ideology_selfreport", "Self-Reported Ideology\n(raw mean)") /
  make_pB(contr_ft_D_df, "FT: Democratic Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Democratic Party) by Party ID | Covariate: Ideology")

Republicans

lm_ideology_selfreport_R <- lm_robust(
  ft_rep_post ~ condition_dummy*PID_dummy*ft_rep_pre
  + condition_dummy*PID_dummy*ideology_selfreport,
  data = data_clean)
FT Republican
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -0.392 0.544 -0.722 0.470 -1.459 0.675 774 ft_rep_post
condition_dummy 1.094 1.034 1.057 0.291 -0.937 3.125 774 ft_rep_post
PID_dummy 0.889 3.518 0.253 0.801 -6.018 7.795 774 ft_rep_post
ft_rep_pre 0.933 0.030 30.961 0.000 0.874 0.992 774 ft_rep_post
ideology_selfreport 0.729 0.436 1.672 0.095 -0.127 1.585 774 ft_rep_post
condition_dummy:PID_dummy -4.989 5.162 -0.967 0.334 -15.123 5.144 774 ft_rep_post
condition_dummy:ft_rep_pre -0.002 0.043 -0.035 0.972 -0.087 0.084 774 ft_rep_post
PID_dummy:ft_rep_pre 0.003 0.047 0.074 0.941 -0.088 0.095 774 ft_rep_post
condition_dummy:ideology_selfreport -1.528 0.673 -2.269 0.024 -2.850 -0.206 774 ft_rep_post
PID_dummy:ideology_selfreport 0.003 0.748 0.003 0.997 -1.467 1.472 774 ft_rep_post
condition_dummy:PID_dummy:ft_rep_pre -0.027 0.068 -0.393 0.694 -0.161 0.107 774 ft_rep_post
condition_dummy:PID_dummy:ideology_selfreport 2.276 1.271 1.791 0.074 -0.219 4.772 774 ft_rep_post
make_pA(data_clean, "ideology_selfreport", "Self-Reported Ideology\n(raw mean)") /
  make_pB(contr_ft_R_df, "FT: Republican Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Republican Party) by Party ID | Covariate: Ideology")

Party ID Strength (7-pt)

Democrats

lm_party_numeric_D <- lm_robust(
  ft_dem_post ~ condition_dummy*party_numeric*ft_dem_pre,
  data = data_clean)
FT Democrat
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 1.024 2.044 0.501 0.616 -2.987 5.036 777 ft_dem_post
condition_dummy 2.763 2.761 1.001 0.317 -2.656 8.182 777 ft_dem_post
party_numeric 0.041 0.365 0.112 0.911 -0.676 0.758 777 ft_dem_post
ft_dem_pre 0.993 0.024 42.039 0.000 0.946 1.039 777 ft_dem_post
condition_dummy:party_numeric -0.317 0.523 -0.607 0.544 -1.343 0.708 777 ft_dem_post
condition_dummy:ft_dem_pre -0.014 0.032 -0.446 0.655 -0.078 0.049 777 ft_dem_post
party_numeric:ft_dem_pre -0.006 0.005 -1.137 0.256 -0.015 0.004 777 ft_dem_post
condition_dummy:party_numeric:ft_dem_pre -0.005 0.010 -0.498 0.618 -0.025 0.015 777 ft_dem_post
make_pA(data_clean, "ft_dem_pre", "Pre-Treatment FT: Democratic Party\n(raw mean)") /
  make_pB(contr_ft_D_df, "FT: Democratic Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Democratic Party) by Party Affiliation Strength")

Republicans

lm_party_numeric_R <- lm_robust(
  ft_rep_post ~ condition_dummy*party_numeric*ft_rep_pre,
  data = data_clean)
FT Republican
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -0.326 0.792 -0.411 0.681 -1.880 1.228 778 ft_rep_post
condition_dummy -0.840 1.026 -0.819 0.413 -2.853 1.173 778 ft_rep_post
party_numeric 0.865 0.474 1.823 0.069 -0.066 1.796 778 ft_rep_post
ft_rep_pre 0.936 0.034 27.652 0.000 0.869 1.002 778 ft_rep_post
condition_dummy:party_numeric -0.307 0.565 -0.543 0.587 -1.417 0.802 778 ft_rep_post
condition_dummy:ft_rep_pre -0.061 0.052 -1.170 0.242 -0.163 0.041 778 ft_rep_post
party_numeric:ft_rep_pre -0.001 0.007 -0.087 0.931 -0.014 0.013 778 ft_rep_post
condition_dummy:party_numeric:ft_rep_pre 0.011 0.010 1.181 0.238 -0.008 0.031 778 ft_rep_post
make_pA(data_clean, "ft_rep_pre", "Pre-Treatment FT: Republican Party\n(raw mean)") /
  make_pB(contr_ft_R_df, "FT: Republican Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Republican Party) by Party Affiliation Strength")

Social Closeness

I deviate from the pre-analysis plan by also including social closeness as a covariate against the same outcome variables and main predictor variables.

Democrats

lm_social_closeness_D <- lm_robust(
  ft_dem_post ~ condition_dummy*PID_dummy*ft_dem_pre
  + condition_dummy*PID_dummy*social_closeness,
  data = data_clean)
FT Democrat
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 1.324 1.601 0.827 0.409 -1.820 4.468 771 ft_dem_post
condition_dummy 2.778 2.321 1.197 0.232 -1.779 7.335 771 ft_dem_post
PID_dummy -4.971 2.641 -1.882 0.060 -10.155 0.213 771 ft_dem_post
ft_dem_pre 0.983 0.016 61.885 0.000 0.952 1.014 771 ft_dem_post
social_closeness -0.074 0.613 -0.122 0.903 -1.277 1.128 771 ft_dem_post
condition_dummy:PID_dummy -2.933 4.917 -0.597 0.551 -12.585 6.718 771 ft_dem_post
condition_dummy:ft_dem_pre 0.011 0.021 0.544 0.587 -0.029 0.052 771 ft_dem_post
PID_dummy:ft_dem_pre -0.047 0.029 -1.600 0.110 -0.105 0.011 771 ft_dem_post
condition_dummy:social_closeness -1.259 0.780 -1.615 0.107 -2.790 0.272 771 ft_dem_post
PID_dummy:social_closeness 2.013 1.038 1.939 0.053 -0.025 4.051 771 ft_dem_post
condition_dummy:PID_dummy:ft_dem_pre -0.059 0.066 -0.889 0.374 -0.188 0.071 771 ft_dem_post
condition_dummy:PID_dummy:social_closeness 1.547 1.938 0.798 0.425 -2.258 5.351 771 ft_dem_post
make_pA(data_clean, "social_closeness", "Social Closeness\n(raw mean)") /
  make_pB(contr_ft_D_df, "FT: Democratic Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Democratic Party) by Party ID | Covariate: Social Closeness")

Republicans

lm_social_closeness_R <- lm_robust(
  ft_rep_post ~ condition_dummy*PID_dummy*ft_rep_pre
  + condition_dummy*PID_dummy*social_closeness,
  data = data_clean)
FT Republican
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -2.718 1.535 -1.770 0.077 -5.732 0.296 772 ft_rep_post
condition_dummy 0.192 1.728 0.111 0.912 -3.201 3.585 772 ft_rep_post
PID_dummy 7.119 4.366 1.630 0.103 -1.452 15.690 772 ft_rep_post
ft_rep_pre 0.899 0.038 23.439 0.000 0.823 0.974 772 ft_rep_post
social_closeness 1.894 0.810 2.338 0.020 0.304 3.483 772 ft_rep_post
condition_dummy:PID_dummy 9.201 6.995 1.315 0.189 -4.531 22.932 772 ft_rep_post
condition_dummy:ft_rep_pre -0.007 0.053 -0.126 0.900 -0.111 0.098 772 ft_rep_post
PID_dummy:ft_rep_pre 0.050 0.050 0.997 0.319 -0.049 0.149 772 ft_rep_post
condition_dummy:social_closeness -0.900 0.924 -0.974 0.330 -2.714 0.914 772 ft_rep_post
PID_dummy:social_closeness -2.157 1.072 -2.011 0.045 -4.262 -0.052 772 ft_rep_post
condition_dummy:PID_dummy:ft_rep_pre -0.027 0.072 -0.371 0.711 -0.167 0.114 772 ft_rep_post
condition_dummy:PID_dummy:social_closeness -1.822 1.692 -1.077 0.282 -5.142 1.499 772 ft_rep_post
make_pA(data_clean, "social_closeness", "Social Closeness\n(raw mean)") /
  make_pB(contr_ft_R_df, "FT: Republican Party\nDiff in Means (Treatment - Control)") +
  plot_annotation(
    title = "Figure: Post-Treatment FT (Republican Party) by Party ID | Covariate: Social Closeness")

Hypotheses Tests With Covariates

Additionally, I outline several exploratory analyses focused on support for political violence within each defined scenario. Primarily, I will doing an exploratory test of all included measures related to participants’ political “identification”, i.e., partisan identification, ideology, partisan self-concept and social closeness. I will craft a second Ordinary Least Squares (OLS) linear regression models with heteroskedasticity-robust standard errors for each of the 14 proposed hypotheses previously outlined to determine whether the introduction of any additional pre-treatment covariates alters the significance of the treatment effect. I have selected support for the MAGA movement, self-reported ideology, partisan self-concept, and social closeness as our socio-political variables of interest across all models, with ideology and MAGA support as the only two variables which I do not interact with the treatment given that the others correspond more strongly to partisanship as a social and political identity rather than a labeled affiliation.

Hypothesis 1

H1_cov <- lm_robust(SPV_meta_R ~ condition_dummy * factor(party_numeric)
                    + condition_dummy * PID_strength
                    + condition_dummy * social_closeness
                    + ideology_selfreport
                    + maga,
                    data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 48.881 7.553 6.472 0.000 34.054 63.708 761 SPV_meta_R
condition_dummy 14.456 11.918 1.213 0.226 -8.941 37.853 761 SPV_meta_R
factor(party_numeric)2 5.285 4.079 1.296 0.195 -2.722 13.292 761 SPV_meta_R
factor(party_numeric)3 9.416 5.223 1.803 0.072 -0.836 19.669 761 SPV_meta_R
factor(party_numeric)5 6.862 5.630 1.219 0.223 -4.189 17.914 761 SPV_meta_R
factor(party_numeric)6 1.675 4.882 0.343 0.732 -7.909 11.258 761 SPV_meta_R
factor(party_numeric)7 4.934 5.432 0.908 0.364 -5.730 15.599 761 SPV_meta_R
PID_strength 2.986 1.577 1.894 0.059 -0.109 6.081 761 SPV_meta_R
social_closeness -5.817 1.592 -3.653 0.000 -8.942 -2.691 761 SPV_meta_R
ideology_selfreport -2.352 0.936 -2.514 0.012 -4.189 -0.516 761 SPV_meta_R
maga -5.492 2.961 -1.855 0.064 -11.305 0.321 761 SPV_meta_R
condition_dummy:factor(party_numeric)2 3.081 5.693 0.541 0.589 -8.095 14.257 761 SPV_meta_R
condition_dummy:factor(party_numeric)3 -1.896 7.368 -0.257 0.797 -16.361 12.569 761 SPV_meta_R
condition_dummy:factor(party_numeric)5 1.061 9.247 0.115 0.909 -17.092 19.215 761 SPV_meta_R
condition_dummy:factor(party_numeric)6 -2.016 6.024 -0.335 0.738 -13.841 9.810 761 SPV_meta_R
condition_dummy:factor(party_numeric)7 -0.484 5.996 -0.081 0.936 -12.254 11.287 761 SPV_meta_R
condition_dummy:PID_strength -3.480 2.584 -1.347 0.178 -8.552 1.593 761 SPV_meta_R
condition_dummy:social_closeness 0.269 2.404 0.112 0.911 -4.450 4.988 761 SPV_meta_R

Hypothesis 2

H2_cov <- lm_robust(moral_disengagement_outgroup ~ condition_dummy * factor(party_numeric)
                    + condition_dummy * PID_strength
                    + condition_dummy * social_closeness
                    + ideology_selfreport
                    + maga,
                    data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 4.727 0.266 17.759 0.000 4.205 5.250 765 moral_disengagement_outgroup
condition_dummy 0.201 0.375 0.536 0.592 -0.535 0.937 765 moral_disengagement_outgroup
factor(party_numeric)2 -0.182 0.136 -1.336 0.182 -0.450 0.086 765 moral_disengagement_outgroup
factor(party_numeric)3 -0.177 0.184 -0.963 0.336 -0.538 0.184 765 moral_disengagement_outgroup
factor(party_numeric)5 -0.634 0.235 -2.699 0.007 -1.095 -0.173 765 moral_disengagement_outgroup
factor(party_numeric)6 -0.816 0.195 -4.179 0.000 -1.199 -0.433 765 moral_disengagement_outgroup
factor(party_numeric)7 -0.802 0.213 -3.764 0.000 -1.220 -0.384 765 moral_disengagement_outgroup
PID_strength 0.077 0.059 1.310 0.191 -0.039 0.193 765 moral_disengagement_outgroup
social_closeness -0.709 0.057 -12.413 0.000 -0.821 -0.597 765 moral_disengagement_outgroup
ideology_selfreport 0.099 0.037 2.701 0.007 0.027 0.171 765 moral_disengagement_outgroup
maga 0.390 0.127 3.071 0.002 0.140 0.639 765 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)2 0.292 0.191 1.533 0.126 -0.082 0.667 765 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)3 0.106 0.244 0.436 0.663 -0.372 0.585 765 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)5 0.204 0.320 0.638 0.524 -0.424 0.833 765 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)6 0.002 0.223 0.009 0.993 -0.436 0.440 765 moral_disengagement_outgroup
condition_dummy:factor(party_numeric)7 0.484 0.230 2.101 0.036 0.032 0.937 765 moral_disengagement_outgroup
condition_dummy:PID_strength -0.020 0.084 -0.233 0.816 -0.184 0.145 765 moral_disengagement_outgroup
condition_dummy:social_closeness -0.054 0.076 -0.711 0.477 -0.204 0.095 765 moral_disengagement_outgroup

Hypothesis 3

H3_cov <- lm_robust(SPV_individual ~ condition_dummy * factor(party_numeric)
                    + condition_dummy * PID_strength
                    + condition_dummy * social_closeness
                    + ideology_selfreport
                    + maga,
                    data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 28.258 6.655 4.246 0.000 15.193 41.324 755 SPV_individual
condition_dummy 15.895 10.536 1.509 0.132 -4.789 36.579 755 SPV_individual
factor(party_numeric)2 6.397 3.002 2.131 0.033 0.505 12.289 755 SPV_individual
factor(party_numeric)3 9.437 4.598 2.052 0.040 0.410 18.463 755 SPV_individual
factor(party_numeric)5 15.585 5.540 2.813 0.005 4.710 26.461 755 SPV_individual
factor(party_numeric)6 12.704 4.023 3.158 0.002 4.806 20.601 755 SPV_individual
factor(party_numeric)7 15.228 4.798 3.174 0.002 5.810 24.647 755 SPV_individual
PID_strength 3.508 1.550 2.263 0.024 0.465 6.552 755 SPV_individual
social_closeness -6.049 1.252 -4.830 0.000 -8.508 -3.590 755 SPV_individual
ideology_selfreport -2.697 0.697 -3.871 0.000 -4.065 -1.329 755 SPV_individual
maga -0.529 2.973 -0.178 0.859 -6.366 5.308 755 SPV_individual
condition_dummy:factor(party_numeric)2 2.815 4.334 0.650 0.516 -5.693 11.324 755 SPV_individual
condition_dummy:factor(party_numeric)3 -2.377 6.078 -0.391 0.696 -14.309 9.556 755 SPV_individual
condition_dummy:factor(party_numeric)5 -3.024 8.761 -0.345 0.730 -20.223 14.174 755 SPV_individual
condition_dummy:factor(party_numeric)6 -3.586 4.940 -0.726 0.468 -13.284 6.111 755 SPV_individual
condition_dummy:factor(party_numeric)7 2.495 5.555 0.449 0.653 -8.410 13.399 755 SPV_individual
condition_dummy:PID_strength -2.637 2.433 -1.084 0.279 -7.414 2.140 755 SPV_individual
condition_dummy:social_closeness -2.113 1.764 -1.198 0.231 -5.575 1.349 755 SPV_individual

Beginning with Hypothesis 4a, I include the pre-treatment affective ratings for both the Republican and Democratic Party, with the former transitioning into a treatment interaction term in Hypothesis 4b and the latter transitioning into a treatment interaction term in Hypothesis 5a.

Hypothesis 4a

H4a_cov <- lm_robust(ft_rep_post ~ condition_dummy * factor(party_numeric)
                     + condition_dummy * PID_strength
                     + condition_dummy * social_closeness
                     + ideology_selfreport
                     + maga
                     + ft_rep_pre
                     + ft_dem_pre,
                     data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -3.383 1.796 -1.883 0.060 -6.909 0.143 759 ft_rep_post
condition_dummy 3.425 2.963 1.156 0.248 -2.393 9.242 759 ft_rep_post
factor(party_numeric)2 0.015 0.852 0.018 0.986 -1.657 1.688 759 ft_rep_post
factor(party_numeric)3 2.685 1.664 1.614 0.107 -0.581 5.951 759 ft_rep_post
factor(party_numeric)5 1.451 2.022 0.718 0.473 -2.519 5.421 759 ft_rep_post
factor(party_numeric)6 4.465 1.815 2.461 0.014 0.903 8.027 759 ft_rep_post
factor(party_numeric)7 5.061 2.186 2.315 0.021 0.769 9.352 759 ft_rep_post
PID_strength 0.713 0.405 1.758 0.079 -0.083 1.509 759 ft_rep_post
social_closeness 1.439 0.461 3.120 0.002 0.533 2.344 759 ft_rep_post
ideology_selfreport 0.039 0.339 0.114 0.909 -0.628 0.705 759 ft_rep_post
maga 0.895 0.833 1.074 0.283 -0.741 2.531 759 ft_rep_post
ft_rep_pre 0.903 0.020 46.134 0.000 0.865 0.942 759 ft_rep_post
ft_dem_pre -0.016 0.013 -1.191 0.234 -0.042 0.010 759 ft_rep_post
condition_dummy:factor(party_numeric)2 0.357 1.319 0.271 0.787 -2.233 2.946 759 ft_rep_post
condition_dummy:factor(party_numeric)3 -3.028 2.167 -1.398 0.163 -7.281 1.225 759 ft_rep_post
condition_dummy:factor(party_numeric)5 -1.797 3.968 -0.453 0.651 -9.587 5.993 759 ft_rep_post
condition_dummy:factor(party_numeric)6 -0.846 1.621 -0.522 0.602 -4.029 2.337 759 ft_rep_post
condition_dummy:factor(party_numeric)7 2.379 1.439 1.654 0.099 -0.445 5.203 759 ft_rep_post
condition_dummy:PID_strength -0.733 0.682 -1.074 0.283 -2.071 0.606 759 ft_rep_post
condition_dummy:social_closeness -1.155 0.572 -2.019 0.044 -2.278 -0.032 759 ft_rep_post

Hypothesis 4b

H4b_cov <- lm_robust(ft_rep_post ~ condition_dummy * factor(party_numeric)
                     + condition_dummy * PID_strength
                     + condition_dummy * social_closeness
                     + condition_dummy * ft_rep_pre
                     + ideology_selfreport
                     + maga
                     + ft_dem_pre,
                     data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -3.103 1.836 -1.690 0.091 -6.707 0.502 758 ft_rep_post
condition_dummy 2.754 2.807 0.981 0.327 -2.756 8.264 758 ft_rep_post
factor(party_numeric)2 -0.088 0.881 -0.100 0.921 -1.817 1.641 758 ft_rep_post
factor(party_numeric)3 2.603 1.688 1.542 0.124 -0.711 5.916 758 ft_rep_post
factor(party_numeric)5 0.983 2.131 0.461 0.645 -3.200 5.166 758 ft_rep_post
factor(party_numeric)6 3.932 2.035 1.932 0.054 -0.064 7.927 758 ft_rep_post
factor(party_numeric)7 4.429 2.455 1.804 0.072 -0.390 9.247 758 ft_rep_post
PID_strength 0.653 0.408 1.600 0.110 -0.148 1.455 758 ft_rep_post
social_closeness 1.300 0.491 2.649 0.008 0.337 2.264 758 ft_rep_post
ft_rep_pre 0.914 0.026 34.999 0.000 0.863 0.966 758 ft_rep_post
ideology_selfreport 0.048 0.337 0.142 0.887 -0.614 0.710 758 ft_rep_post
maga 0.814 0.816 0.998 0.318 -0.787 2.416 758 ft_rep_post
ft_dem_pre -0.015 0.013 -1.145 0.253 -0.041 0.011 758 ft_rep_post
condition_dummy:factor(party_numeric)2 0.611 1.348 0.453 0.650 -2.034 3.256 758 ft_rep_post
condition_dummy:factor(party_numeric)3 -2.818 2.182 -1.292 0.197 -7.102 1.465 758 ft_rep_post
condition_dummy:factor(party_numeric)5 -0.909 3.958 -0.230 0.818 -8.679 6.861 758 ft_rep_post
condition_dummy:factor(party_numeric)6 0.287 2.567 0.112 0.911 -4.752 5.327 758 ft_rep_post
condition_dummy:factor(party_numeric)7 3.883 3.253 1.194 0.233 -2.503 10.269 758 ft_rep_post
condition_dummy:PID_strength -0.630 0.652 -0.966 0.334 -1.911 0.650 758 ft_rep_post
condition_dummy:social_closeness -0.862 0.603 -1.429 0.153 -2.045 0.322 758 ft_rep_post
condition_dummy:ft_rep_pre -0.024 0.039 -0.625 0.532 -0.100 0.052 758 ft_rep_post

Hypothesis 5

H5_cov <- lm_robust(ft_rep_post ~ condition_dummy * factor(party_numeric) * PID_bin
                    + condition_dummy * social_closeness
                    + condition_dummy * ft_rep_pre
                    + condition_dummy * ft_dem_pre
                    + ideology_selfreport
                    + maga,
                    data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -1.838 1.344 -1.367 0.172 -4.476 0.801 747 ft_rep_post
condition_dummy 1.727 2.557 0.675 0.500 -3.293 6.748 747 ft_rep_post
factor(party_numeric)2 -1.567 2.015 -0.777 0.437 -5.524 2.390 747 ft_rep_post
factor(party_numeric)3 -1.434 1.794 -0.799 0.424 -4.957 2.088 747 ft_rep_post
factor(party_numeric)5 0.152 2.400 0.063 0.949 -4.559 4.863 747 ft_rep_post
factor(party_numeric)6 1.400 2.068 0.677 0.498 -2.659 5.460 747 ft_rep_post
factor(party_numeric)7 3.231 3.042 1.062 0.288 -2.740 9.203 747 ft_rep_post
PID_bin 0.628 0.561 1.119 0.263 -0.473 1.728 747 ft_rep_post
social_closeness 1.508 0.465 3.245 0.001 0.596 2.421 747 ft_rep_post
ft_rep_pre 0.914 0.028 33.168 0.000 0.860 0.968 747 ft_rep_post
ft_dem_pre -0.021 0.017 -1.295 0.196 -0.054 0.011 747 ft_rep_post
ideology_selfreport 0.052 0.333 0.156 0.876 -0.601 0.705 747 ft_rep_post
maga 0.694 0.809 0.858 0.391 -0.895 2.283 747 ft_rep_post
condition_dummy:factor(party_numeric)2 -0.214 3.221 -0.066 0.947 -6.537 6.110 747 ft_rep_post
condition_dummy:factor(party_numeric)3 2.070 2.983 0.694 0.488 -3.786 7.925 747 ft_rep_post
condition_dummy:factor(party_numeric)5 3.740 5.881 0.636 0.525 -7.804 15.285 747 ft_rep_post
condition_dummy:factor(party_numeric)6 -1.926 4.010 -0.480 0.631 -9.799 5.947 747 ft_rep_post
condition_dummy:factor(party_numeric)7 3.134 4.923 0.637 0.525 -6.531 12.799 747 ft_rep_post
condition_dummy:PID_bin -0.740 1.225 -0.604 0.546 -3.145 1.664 747 ft_rep_post
factor(party_numeric)2:PID_bin 0.705 1.363 0.517 0.605 -1.971 3.380 747 ft_rep_post
factor(party_numeric)3:PID_bin 4.340 3.001 1.446 0.149 -1.552 10.232 747 ft_rep_post
factor(party_numeric)5:PID_bin 0.063 1.736 0.036 0.971 -3.345 3.471 747 ft_rep_post
factor(party_numeric)6:PID_bin 1.251 1.466 0.854 0.394 -1.626 4.129 747 ft_rep_post
factor(party_numeric)7:PID_bin 0.556 1.686 0.330 0.742 -2.753 3.866 747 ft_rep_post
condition_dummy:social_closeness -1.073 0.604 -1.776 0.076 -2.259 0.113 747 ft_rep_post
condition_dummy:ft_rep_pre -0.024 0.040 -0.592 0.554 -0.103 0.055 747 ft_rep_post
condition_dummy:ft_dem_pre 0.007 0.028 0.251 0.802 -0.048 0.062 747 ft_rep_post
condition_dummy:factor(party_numeric)2:PID_bin 0.851 2.049 0.415 0.678 -3.171 4.873 747 ft_rep_post
condition_dummy:factor(party_numeric)3:PID_bin -5.459 3.720 -1.468 0.143 -12.762 1.843 747 ft_rep_post
condition_dummy:factor(party_numeric)5:PID_bin -4.709 8.241 -0.571 0.568 -20.887 11.469 747 ft_rep_post
condition_dummy:factor(party_numeric)6:PID_bin 2.554 2.457 1.039 0.299 -2.270 7.378 747 ft_rep_post
condition_dummy:factor(party_numeric)7:PID_bin 0.504 3.194 0.158 0.875 -5.765 6.774 747 ft_rep_post

Hypothesis 6

H6_cov <- lm_robust(ft_dem_post ~ condition_dummy * factor(party_numeric) * PID_bin
                    + condition_dummy * social_closeness
                    + condition_dummy * ft_rep_pre
                    + condition_dummy * ft_dem_pre
                    + ideology_selfreport
                    + maga,
                    data = data_clean, se_type = "HC2")
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 1.479 1.659 0.892 0.373 -1.777 4.735 747 ft_dem_post
condition_dummy 3.192 3.044 1.048 0.295 -2.784 9.168 747 ft_dem_post
factor(party_numeric)2 -3.839 2.199 -1.746 0.081 -8.157 0.478 747 ft_dem_post
factor(party_numeric)3 0.843 1.540 0.548 0.584 -2.180 3.866 747 ft_dem_post
factor(party_numeric)5 -0.880 1.992 -0.442 0.659 -4.790 3.030 747 ft_dem_post
factor(party_numeric)6 -1.134 1.893 -0.599 0.550 -4.851 2.584 747 ft_dem_post
factor(party_numeric)7 -1.432 2.360 -0.607 0.544 -6.066 3.201 747 ft_dem_post
PID_bin 0.795 0.857 0.927 0.354 -0.888 2.477 747 ft_dem_post
social_closeness 0.454 0.555 0.818 0.414 -0.635 1.542 747 ft_dem_post
ft_rep_pre 0.012 0.016 0.774 0.439 -0.019 0.043 747 ft_dem_post
ft_dem_pre 0.957 0.019 49.977 0.000 0.920 0.995 747 ft_dem_post
ideology_selfreport -0.226 0.324 -0.698 0.485 -0.863 0.410 747 ft_dem_post
maga -0.018 1.072 -0.017 0.986 -2.123 2.087 747 ft_dem_post
condition_dummy:factor(party_numeric)2 4.748 3.708 1.280 0.201 -2.532 12.029 747 ft_dem_post
condition_dummy:factor(party_numeric)3 -2.409 3.108 -0.775 0.439 -8.511 3.693 747 ft_dem_post
condition_dummy:factor(party_numeric)5 6.483 4.623 1.402 0.161 -2.592 15.559 747 ft_dem_post
condition_dummy:factor(party_numeric)6 -1.327 4.389 -0.302 0.762 -9.944 7.290 747 ft_dem_post
condition_dummy:factor(party_numeric)7 13.409 3.417 3.924 0.000 6.700 20.118 747 ft_dem_post
condition_dummy:PID_bin 0.822 1.685 0.488 0.626 -2.486 4.129 747 ft_dem_post
factor(party_numeric)2:PID_bin 1.914 1.268 1.510 0.132 -0.575 4.403 747 ft_dem_post
factor(party_numeric)3:PID_bin -2.754 2.118 -1.300 0.194 -6.913 1.405 747 ft_dem_post
factor(party_numeric)5:PID_bin -1.905 1.178 -1.618 0.106 -4.217 0.406 747 ft_dem_post
factor(party_numeric)6:PID_bin -0.924 1.715 -0.539 0.590 -4.291 2.442 747 ft_dem_post
factor(party_numeric)7:PID_bin -0.615 1.370 -0.449 0.654 -3.305 2.075 747 ft_dem_post
condition_dummy:social_closeness -0.882 0.829 -1.065 0.287 -2.509 0.745 747 ft_dem_post
condition_dummy:ft_rep_pre -0.026 0.035 -0.740 0.460 -0.093 0.042 747 ft_dem_post
condition_dummy:ft_dem_pre -0.023 0.036 -0.638 0.524 -0.092 0.047 747 ft_dem_post
condition_dummy:factor(party_numeric)2:PID_bin -2.960 2.132 -1.388 0.166 -7.146 1.227 747 ft_dem_post
condition_dummy:factor(party_numeric)3:PID_bin 3.636 2.763 1.316 0.189 -1.788 9.059 747 ft_dem_post
condition_dummy:factor(party_numeric)5:PID_bin -3.076 3.278 -0.938 0.348 -9.510 3.359 747 ft_dem_post
condition_dummy:factor(party_numeric)6:PID_bin 2.695 3.214 0.838 0.402 -3.615 9.006 747 ft_dem_post
condition_dummy:factor(party_numeric)7:PID_bin -8.109 2.984 -2.718 0.007 -13.967 -2.251 747 ft_dem_post

Scenario-Specific SPV

On the micro level, across each of the six scenarios, I will conduct two Ordinary Least Squares (OLS) linear regression models with heteroskedasticity-robust standard errors, one focused on individual support for political violence and the other on meta-perceptions of Republicans’ support for political violence. For the former, I will create two additional Ordinary Least Squares (OLS) linear regression models with heteroskedasticity-robust standard errors to distinguish between Republicans’ reported SPV and Democrats’ reported SPV within each SPV scenario. Across each of these four models, I plan to regress each of the six scenario-specific measures of SPV separately onto a three-way interaction between condition assignment, the numeric version of the ANES 7-point party identification scale, and the grouped version of partisan self-concept used in Hypotheses 5a through 6c. Additional specified covariates include the interaction between the treatment and social closeness, support for the MAGA movement, and self-reported ideology.

I deviated from the pre-analysis plan by removing the additional specified covariates from each model, as this simplifies the ability to draw conclusions about the average treatment effect. The only covariates included are PID_dummy, which represents the dichotomous effect of being a Democrat versus a Republican, and PID_bin, the grouped version of partisan self-concept.

Scenario: Protesting without a permit

Models

# 1.1: form models for:
# A: Individual SPV (Aggregated)
lm_protest_indiv <- lm_robust(SPV_indiv_protest ~ condition_dummy * PID_dummy * PID_bin,
                              data = data_clean, se_type = "HC2")
# B: Meta-Perceptions of Republican SPV 
lm_protest_meta_R <- lm_robust(SPV_meta_protest ~ condition_dummy * PID_dummy * PID_bin,
                               data = data_clean, se_type = "HC2")
# C: Individual SPV (Reps only)
lm_R_protest <- lm_robust(spv_Rprotest ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
# D: Individual SPV (Dems only)
lm_D_protest <- lm_robust(spv_Dprotest ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
Individual SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 42.795 4.136 10.346 0.000 34.675 50.915 774 SPV_indiv_protest
condition_dummy 15.132 6.411 2.360 0.019 2.547 27.718 774 SPV_indiv_protest
PID_dummy -26.558 6.080 -4.368 0.000 -38.492 -14.623 774 SPV_indiv_protest
PID_bin 4.368 2.612 1.672 0.095 -0.760 9.496 774 SPV_indiv_protest
condition_dummy:PID_dummy 2.301 10.215 0.225 0.822 -17.752 22.355 774 SPV_indiv_protest
condition_dummy:PID_bin -5.930 3.960 -1.498 0.135 -13.704 1.843 774 SPV_indiv_protest
PID_dummy:PID_bin 13.091 4.024 3.253 0.001 5.191 20.990 774 SPV_indiv_protest
condition_dummy:PID_dummy:PID_bin -6.951 6.904 -1.007 0.314 -20.503 6.601 774 SPV_indiv_protest
Meta-Perceptions Republican SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 57.366 4.687 12.238 0.000 48.164 66.567 777 SPV_meta_protest
condition_dummy 10.715 6.962 1.539 0.124 -2.952 24.381 777 SPV_meta_protest
PID_dummy -9.016 6.890 -1.309 0.191 -22.542 4.510 777 SPV_meta_protest
PID_bin -0.929 2.888 -0.322 0.748 -6.599 4.741 777 SPV_meta_protest
condition_dummy:PID_dummy 8.520 9.999 0.852 0.394 -11.108 28.148 777 SPV_meta_protest
condition_dummy:PID_bin -2.945 4.218 -0.698 0.485 -11.225 5.335 777 SPV_meta_protest
PID_dummy:PID_bin 6.206 4.309 1.440 0.150 -2.253 14.665 777 SPV_meta_protest
condition_dummy:PID_dummy:PID_bin -10.385 6.528 -1.591 0.112 -23.200 2.430 777 SPV_meta_protest
Individual SPV (Republicans Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 16.237 4.455 3.644 0.000 7.463 25.012 253 spv_Rprotest
condition_dummy 17.434 7.953 2.192 0.029 1.772 33.096 253 spv_Rprotest
PID_bin 17.458 3.061 5.703 0.000 11.430 23.487 253 spv_Rprotest
condition_dummy:PID_bin -12.881 5.655 -2.278 0.024 -24.018 -1.745 253 spv_Rprotest
Individual SPV (Democrats Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 42.795 4.136 10.346 0.000 34.669 50.921 521 spv_Dprotest
condition_dummy 15.132 6.411 2.360 0.019 2.537 27.728 521 spv_Dprotest
PID_bin 4.368 2.612 1.672 0.095 -0.764 9.500 521 spv_Dprotest
condition_dummy:PID_bin -5.930 3.960 -1.498 0.135 -13.710 1.849 521 spv_Dprotest

Party ID (Dummy)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
emm_protest_indiv <- emmeans(lm_protest_indiv, ~ condition_dummy * PID_dummy,
                             vcov. = vcov(lm_protest_indiv))
emm_protest_indiv_df <- as.data.frame(confint(emm_protest_indiv)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_protest_indiv <- contrast(emm_protest_indiv,
                                method = list(
                                  "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                  "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                  "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                  "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_protest_indiv_df <- as.data.frame(confint(contr_protest_indiv))
contr_table_protest_indiv <- summary(contr_protest_indiv) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -6.830133 2.951703 774 -2.3139637 0.0209308
Control D vs. Treatment D 6.195672 2.550776 774 2.4289363 0.0153699
Control R vs. Treatment R -1.978148 3.827324 774 -0.5168488 0.6054093
Treatment D vs. Treatment R -15.003953 3.527367 774 -4.2535843 0.0000236
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
emm_protest_meta_R <- emmeans(lm_protest_meta_R, ~ condition_dummy * PID_dummy,
                              vcov. = vcov(lm_protest_meta_R))
emm_protest_meta_R_df <- as.data.frame(confint(emm_protest_meta_R)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_protest_meta_R <- contrast(emm_protest_meta_R,
                                 method = list(
                                   "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                   "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                   "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                   "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_protest_meta_R_df <- as.data.frame(confint(contr_protest_meta_R))
contr_table_protest_meta_R <- summary(contr_protest_meta_R) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R 0.3363275 2.859830 777 0.1176040 0.9064118
Control D vs. Treatment D 6.2770729 2.672940 777 2.3483778 0.0191051
Control R vs. Treatment R -0.8533573 3.460719 777 -0.2465838 0.8052955
Treatment D vs. Treatment R -6.7941027 3.307953 777 -2.0538690 0.0403225

Party ID (7-pt)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
protest_indiv_partyaffil <- lm_robust(SPV_indiv_protest ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_protest_indiv_partyaffil<- emmeans(protest_indiv_partyaffil, ~ condition_dummy * party_numeric,
                                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                       vcov. = vcov(protest_indiv_partyaffil))
contr_protest_indiv_partyaffil<- contrast(emm_protest_indiv_partyaffil,
                                          method = list("Treatment - Control" = c(-1, 1)),
                                          by = "party_numeric")
contr_protest_indiv_partyaffil_df <- confint(contr_protest_indiv_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Individual Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 7.0566203 2.959668 782 1.2467864 12.866454 Strong D Individual Ratings
Treatment - Control 2 5.4523769 2.371865 782 0.7964009 10.108353 Weak D Individual Ratings
Treatment - Control 3 3.8481336 2.128025 782 -0.3291845 8.025452 Lean D Individual Ratings
Treatment - Control 5 0.6396468 2.905838 782 -5.0645201 6.343814 Lean R Individual Ratings
Treatment - Control 6 -0.9645965 3.668318 782 -8.1655119 6.236319 Weak R Individual Ratings
Treatment - Control 7 -2.5688399 4.528338 782 -11.4579778 6.320298 Strong R Individual Ratings
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
protest_meta_R_partyaffil <- lm_robust(SPV_meta_protest ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_protest_meta_R_partyaffil<- emmeans(protest_meta_R_partyaffil, ~ condition_dummy * party_numeric,
                                        at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                        vcov. = vcov(protest_meta_R_partyaffil))
contr_protest_meta_R_partyaffil<- contrast(emm_protest_meta_R_partyaffil,
                                           method = list("Treatment - Control" = c(-1, 1)),
                                           by = "party_numeric")
contr_protest_meta_R_partyaffil_df <- confint(contr_protest_meta_R_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Meta-Perceptions of Republicans' Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 6.0762027 3.053646 785 0.0819242 12.070481 Strong D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 2 5.1819775 2.460482 785 0.3520735 10.011881 Weak D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 3 4.2877522 2.125921 785 0.1145901 8.460914 Lean D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 5 2.4993018 2.580640 785 -2.5664697 7.565073 Lean R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 6 1.6050766 3.214701 785 -4.7053504 7.915503 Weak R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 7 0.7108514 3.968028 785 -7.0783494 8.500052 Strong R Meta-Perceptions of Republicans’ Ratings

Party ID (7-pt) + Partisan Self-Concept

lm_protest_indiv_R_7 <- lm_robust(SPV_indiv_protest ~ condition_dummy * party_numeric * PID_bin,
                                  data = data_clean, se_type = "HC2")
emm_protest_indiv_R_7<- emmeans(lm_protest_indiv_R_7, ~ condition_dummy | party_numeric,
                                at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                vcov. = vcov(lm_protest_indiv_R_7))
contr_protest_indiv_R_7<- contrast(emm_protest_indiv_R_7,
                                   method = list("Treatment - Control" = c(-1, 1)),
                                   by = "party_numeric")
contr_protest_indiv_R_7_df <- as.data.frame(confint(contr_protest_indiv_R_7))
contr_table_protest_indiv_R_7_df <- summary(contr_protest_indiv_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 6.9789524 3.059601 774 2.2810007 0.0228193 Strong D
Treatment - Control 2 5.4979017 2.452873 774 2.2414131 0.0252820 Weak D
Treatment - Control 3 4.0168511 2.163984 774 1.8562300 0.0638006 Lean D
Treatment - Control 5 1.0547498 2.836854 774 0.3718027 0.7101415 Lean R
Treatment - Control 6 -0.4263008 3.570212 774 -0.1194049 0.9049856 Weak R
Treatment - Control 7 -1.9073515 4.410884 774 -0.4324193 0.6655571 Strong R
lm_protest_meta_R_7 <- lm_robust(SPV_meta_protest ~ condition_dummy * party_numeric * PID_bin,
                                 data = data_clean, se_type = "HC2")
emm_protest_meta_R_7<- emmeans(lm_protest_meta_R_7, ~ condition_dummy | party_numeric,
                               at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                               vcov. = vcov(lm_protest_meta_R_7))
contr_protest_meta_R_7<- contrast(emm_protest_meta_R_7,
                                  method = list("Treatment - Control" = c(-1, 1)),
                                  by = "party_numeric")
contr_protest_meta_R_7_df <- as.data.frame(confint(contr_protest_meta_R_7))
contr_table_protest_meta_R_7_df <- summary(contr_protest_meta_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 4.970842 3.261950 777 1.5238864 0.1279440 Strong D
Treatment - Control 2 4.407223 2.605459 777 1.6915342 0.0911358 Weak D
Treatment - Control 3 3.843604 2.199456 777 1.7475253 0.0809413 Lean D
Treatment - Control 5 2.716367 2.576675 777 1.0542141 0.2921126 Lean R
Treatment - Control 6 2.152748 3.223618 777 0.6678049 0.5044564 Weak R
Treatment - Control 7 1.589129 4.005654 777 0.3967215 0.6916818 Strong R

Factor models for panel plots

protest_indiv_factor <- lm_robust(SPV_indiv_protest ~ condition_dummy * factor(party_numeric),
                                  data = data_clean, se_type = "HC2")
emm_protest_indiv_factor <- emmeans(protest_indiv_factor, ~ condition_dummy | party_numeric,
                                    vcov. = vcov(protest_indiv_factor))
contr_protest_indiv_factor_df <- confint(contrast(emm_protest_indiv_factor,
                                                  method = list("Treatment - Control" = c(-1, 1)),
                                                  by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

protest_meta_R_factor <- lm_robust(SPV_meta_protest ~ condition_dummy * factor(party_numeric),
                                   data = data_clean, se_type = "HC2")
emm_protest_meta_R_factor <- emmeans(protest_meta_R_factor, ~ condition_dummy | party_numeric,
                                     vcov. = vcov(protest_meta_R_factor))
contr_protest_meta_R_factor_df <- confint(contrast(emm_protest_meta_R_factor,
                                                   method = list("Treatment - Control" = c(-1, 1)),
                                                   by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

p_protest_indiv <- make_SPV_panels(
  "SPV_indiv_protest",
  contr_protest_indiv_partyaffil_df,
  contr_protest_indiv_factor_df,
  "Individual SPV: Protest\n(raw mean)",
  "Figure: Protest Without a Permit — Individual Ratings",
  color_A = c("Control R" = "firebrick", "Treatment R" = "salmon",
              "Control D" = "hotpink",   "Treatment D" = "pink"))

p_protest_meta_R <- make_SPV_panels(
  "SPV_meta_protest",
  contr_protest_meta_R_partyaffil_df,
  contr_protest_meta_R_factor_df,
  "Meta-Perceptions of Republican SPV: Protest\n(raw mean)",
  "Figure: Protest Without a Permit — Meta-Perceptions",
  color_A = c("Control R" = "firebrick", "Treatment R" = "salmon",
              "Control D" = "hotpink",   "Treatment D" = "pink"))

Scenario: Vandalizing opposing party’s signs

Models

# 1.1: form models for:
# A: Individual SPV (Aggregated)
lm_vandalize_indiv <- lm_robust(SPV_indiv_vandalize ~ condition_dummy * PID_dummy * PID_bin,
                              data = data_clean, se_type = "HC2")
# B: Meta-Perceptions of Republican SPV 
lm_vandalize_meta_R <- lm_robust(SPV_meta_vandalize ~ condition_dummy * PID_dummy * PID_bin,
                               data = data_clean, se_type = "HC2")
# C: Individual SPV (Reps only)
lm_R_vandalize <- lm_robust(spv_Rvandalize ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
# D: Individual SPV (Dems only)
lm_D_vandalize <- lm_robust(spv_Dvandalize ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
Individual SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 32.932 4.171 7.895 0.000 24.744 41.121 772 SPV_indiv_vandalize
condition_dummy 7.143 7.003 1.020 0.308 -6.605 20.891 772 SPV_indiv_vandalize
PID_dummy -28.169 6.052 -4.655 0.000 -40.049 -16.289 772 SPV_indiv_vandalize
PID_bin -2.083 2.547 -0.818 0.414 -7.083 2.917 772 SPV_indiv_vandalize
condition_dummy:PID_dummy 2.273 9.608 0.237 0.813 -16.587 21.133 772 SPV_indiv_vandalize
condition_dummy:PID_bin -0.132 4.183 -0.032 0.975 -8.345 8.080 772 SPV_indiv_vandalize
PID_dummy:PID_bin 15.264 3.983 3.832 0.000 7.445 23.082 772 SPV_indiv_vandalize
condition_dummy:PID_dummy:PID_bin -6.212 6.333 -0.981 0.327 -18.644 6.220 772 SPV_indiv_vandalize
Meta-Perceptions Republican SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 47.768 4.808 9.934 0.000 38.329 57.207 773 SPV_meta_vandalize
condition_dummy 13.445 7.576 1.775 0.076 -1.427 28.317 773 SPV_meta_vandalize
PID_dummy -22.082 6.643 -3.324 0.001 -35.122 -9.042 773 SPV_meta_vandalize
PID_bin -0.377 2.990 -0.126 0.900 -6.247 5.492 773 SPV_meta_vandalize
condition_dummy:PID_dummy 11.520 11.305 1.019 0.308 -10.671 33.712 773 SPV_meta_vandalize
condition_dummy:PID_bin -4.542 4.563 -0.995 0.320 -13.500 4.415 773 SPV_meta_vandalize
PID_dummy:PID_bin 8.770 4.349 2.017 0.044 0.233 17.307 773 SPV_meta_vandalize
condition_dummy:PID_dummy:PID_bin -10.516 7.301 -1.440 0.150 -24.847 3.815 773 SPV_meta_vandalize
Individual SPV (Republicans Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 4.763 4.385 1.086 0.278 -3.872 13.398 254 spv_Rvandalize
condition_dummy 9.416 6.577 1.432 0.153 -3.537 22.369 254 spv_Rvandalize
PID_bin 13.181 3.062 4.305 0.000 7.151 19.211 254 spv_Rvandalize
condition_dummy:PID_bin -6.344 4.754 -1.334 0.183 -15.707 3.019 254 spv_Rvandalize
Individual SPV (Democrats Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 32.932 4.171 7.895 0.000 24.738 41.127 518 spv_Dvandalize
condition_dummy 7.143 7.003 1.020 0.308 -6.616 20.902 518 spv_Dvandalize
PID_bin -2.083 2.547 -0.818 0.414 -7.087 2.921 518 spv_Dvandalize
condition_dummy:PID_bin -0.132 4.183 -0.032 0.975 -8.351 8.086 518 spv_Dvandalize

Party ID (Dummy)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
emm_vandalize_indiv <- emmeans(lm_vandalize_indiv, ~ condition_dummy * PID_dummy,
                             vcov. = vcov(lm_vandalize_indiv))
emm_vandalize_indiv_df <- as.data.frame(confint(emm_vandalize_indiv)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_vandalize_indiv <- contrast(emm_vandalize_indiv,
                                method = list(
                                  "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                  "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                  "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                  "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_vandalize_indiv_df <- as.data.frame(confint(contr_vandalize_indiv))
contr_table_vandalize_indiv <- summary(contr_vandalize_indiv) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -5.1666652 2.753057 772 -1.8767011 0.0609360
Control D vs. Treatment D 6.9436643 2.563970 772 2.7081689 0.0069153
Control R vs. Treatment R -0.1446896 3.389855 772 -0.0426831 0.9659652
Treatment D vs. Treatment R -12.2550191 3.238169 772 -3.7845525 0.0001659
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
emm_vandalize_meta_R <- emmeans(lm_vandalize_meta_R, ~ condition_dummy * PID_dummy,
                              vcov. = vcov(lm_vandalize_meta_R))
emm_vandalize_meta_R_df <- as.data.frame(confint(emm_vandalize_meta_R)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_vandalize_meta_R <- contrast(emm_vandalize_meta_R,
                                 method = list(
                                   "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                   "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                   "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                   "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_vandalize_meta_R_df <- as.data.frame(confint(contr_vandalize_meta_R))
contr_table_vandalize_meta_R <- summary(contr_vandalize_meta_R) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -8.865556 2.946239 773 -3.0091100 0.0027053
Control D vs. Treatment D 6.599702 2.892820 773 2.2814076 0.0227955
Control R vs. Treatment R 2.271952 3.516133 773 0.6461508 0.5183735
Treatment D vs. Treatment R -13.193306 3.471495 773 -3.8004682 0.0001558

Party ID (7-pt)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
vandalize_indiv_partyaffil <- lm_robust(SPV_indiv_vandalize ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_vandalize_indiv_partyaffil<- emmeans(vandalize_indiv_partyaffil, ~ condition_dummy * party_numeric,
                                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                       vcov. = vcov(vandalize_indiv_partyaffil))
contr_vandalize_indiv_partyaffil<- contrast(emm_vandalize_indiv_partyaffil,
                                          method = list("Treatment - Control" = c(-1, 1)),
                                          by = "party_numeric")
contr_vandalize_indiv_partyaffil_df <- confint(contr_vandalize_indiv_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Individual Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 8.0913299 2.930071 780 2.3395716 13.843088 Strong D Individual Ratings
Treatment - Control 2 6.4550897 2.355784 780 1.8306622 11.079517 Weak D Individual Ratings
Treatment - Control 3 4.8188496 2.052619 780 0.7895374 8.848162 Lean D Individual Ratings
Treatment - Control 5 1.5463693 2.576369 780 -3.5110681 6.603807 Lean R Individual Ratings
Treatment - Control 6 -0.0898709 3.224682 780 -6.4199547 6.240213 Weak R Individual Ratings
Treatment - Control 7 -1.7261110 3.982286 780 -9.5433785 6.091156 Strong R Individual Ratings
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
vandalize_meta_R_partyaffil <- lm_robust(SPV_meta_vandalize ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_vandalize_meta_R_partyaffil<- emmeans(vandalize_meta_R_partyaffil, ~ condition_dummy * party_numeric,
                                        at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                        vcov. = vcov(vandalize_meta_R_partyaffil))
contr_vandalize_meta_R_partyaffil<- contrast(emm_vandalize_meta_R_partyaffil,
                                           method = list("Treatment - Control" = c(-1, 1)),
                                           by = "party_numeric")
contr_vandalize_meta_R_partyaffil_df <- confint(contr_vandalize_meta_R_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Meta-Perceptions of Republicans' Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 6.532577 3.269176 781 0.1151645 12.949988 Strong D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 2 6.034259 2.641108 781 0.8497477 11.218770 Weak D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 3 5.535941 2.270913 781 1.0781248 9.993758 Lean D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 5 4.539306 2.683505 781 -0.7284307 9.807042 Lean R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 6 4.040988 3.326223 781 -2.4884067 10.570383 Weak R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 7 3.542671 4.101215 781 -4.5080400 11.593381 Strong R Meta-Perceptions of Republicans’ Ratings

Party ID (7-pt) + Partisan Self-Concept

lm_vandalize_indiv_R_7 <- lm_robust(SPV_indiv_vandalize ~ condition_dummy * party_numeric * PID_bin,
                                  data = data_clean, se_type = "HC2")
emm_vandalize_indiv_R_7<- emmeans(lm_vandalize_indiv_R_7, ~ condition_dummy | party_numeric,
                                at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                vcov. = vcov(lm_vandalize_indiv_R_7))
contr_vandalize_indiv_R_7<- contrast(emm_vandalize_indiv_R_7,
                                   method = list("Treatment - Control" = c(-1, 1)),
                                   by = "party_numeric")
contr_vandalize_indiv_R_7_df <- as.data.frame(confint(contr_vandalize_indiv_R_7))
contr_table_vandalize_indiv_R_7_df <- summary(contr_vandalize_indiv_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 7.5900529 3.192076 772 2.3777796 0.0176598 Strong D
Treatment - Control 2 6.2708727 2.539107 772 2.4697156 0.0137373 Weak D
Treatment - Control 3 4.9516925 2.132891 772 2.3215870 0.0205146 Lean D
Treatment - Control 5 2.3133321 2.507363 772 0.9226156 0.3564958 Lean R
Treatment - Control 6 0.9941519 3.149977 772 0.3156061 0.7523868 Weak R
Treatment - Control 7 -0.3250284 3.924574 772 -0.0828188 0.9340171 Strong R
lm_vandalize_meta_R_7 <- lm_robust(SPV_meta_vandalize ~ condition_dummy * party_numeric * PID_bin,
                                 data = data_clean, se_type = "HC2")
emm_vandalize_meta_R_7<- emmeans(lm_vandalize_meta_R_7, ~ condition_dummy | party_numeric,
                               at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                               vcov. = vcov(lm_vandalize_meta_R_7))
contr_vandalize_meta_R_7<- contrast(emm_vandalize_meta_R_7,
                                  method = list("Treatment - Control" = c(-1, 1)),
                                  by = "party_numeric")
contr_vandalize_meta_R_7_df <- as.data.frame(confint(contr_vandalize_meta_R_7))
contr_table_vandalize_meta_R_7_df <- summary(contr_vandalize_meta_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 5.531969 3.531539 773 1.566447 0.1176532 Strong D
Treatment - Control 2 5.320441 2.817176 773 1.888572 0.0593233 Weak D
Treatment - Control 3 5.108912 2.349322 773 2.174632 0.0299602 Lean D
Treatment - Control 5 4.685854 2.653172 773 1.766133 0.0777683 Lean R
Treatment - Control 6 4.474325 3.313080 773 1.350503 0.1772499 Weak R
Treatment - Control 7 4.262796 4.126959 773 1.032914 0.3019669 Strong R

Factor models for panel plots

vandalize_indiv_factor <- lm_robust(SPV_indiv_vandalize ~ condition_dummy * factor(party_numeric),
                                  data = data_clean, se_type = "HC2")
emm_vandalize_indiv_factor <- emmeans(vandalize_indiv_factor, ~ condition_dummy | party_numeric,
                                    vcov. = vcov(vandalize_indiv_factor))
contr_vandalize_indiv_factor_df <- confint(contrast(emm_vandalize_indiv_factor,
                                                  method = list("Treatment - Control" = c(-1, 1)),
                                                  by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

vandalize_meta_R_factor <- lm_robust(SPV_meta_vandalize ~ condition_dummy * factor(party_numeric),
                                   data = data_clean, se_type = "HC2")
emm_vandalize_meta_R_factor <- emmeans(vandalize_meta_R_factor, ~ condition_dummy | party_numeric,
                                     vcov. = vcov(vandalize_meta_R_factor))
contr_vandalize_meta_R_factor_df <- confint(contrast(emm_vandalize_meta_R_factor,
                                                   method = list("Treatment - Control" = c(-1, 1)),
                                                   by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

p_vandalize_indiv <- make_SPV_panels(
  "SPV_indiv_vandalize",
  contr_vandalize_indiv_partyaffil_df,
  contr_vandalize_indiv_factor_df,
  "Individual SPV: Vandalize\n(raw mean)",
  "Figure: Vandalizing Opposing Party's Signs — Individual Ratings",
  color_A = c("Control R" = "darkorange",  "Treatment R" = "lightsalmon",
              "Control D" = "coral",        "Treatment D" = "peachpuff"))

p_vandalize_meta_R <- make_SPV_panels(
  "SPV_meta_vandalize",
  contr_vandalize_meta_R_partyaffil_df,
  contr_vandalize_meta_R_factor_df,
  "Meta-Perceptions of Republican SPV: Vandalize\n(raw mean)",
  "Figure: Vandalizing Opposing Party's Signs — Meta-Perceptions",
  color_A = c("Control R" = "darkorange",  "Treatment R" = "lightsalmon",
              "Control D" = "coral",        "Treatment D" = "peachpuff"))

Scenario: Messaging threats online to an out-party representative

Models

# 1.1: form models for:
# A: Individual SPV (Aggregated)
lm_message_indiv <- lm_robust(SPV_indiv_message ~ condition_dummy * PID_dummy * PID_bin,
                              data = data_clean, se_type = "HC2")
# B: Meta-Perceptions of Republican SPV 
lm_message_meta_R <- lm_robust(SPV_meta_message ~ condition_dummy * PID_dummy * PID_bin,
                               data = data_clean, se_type = "HC2")
# C: Individual SPV (Reps only)
lm_R_message <- lm_robust(spv_Rmessage ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
# D: Individual SPV (Dems only)
lm_D_message <- lm_robust(spv_Dmessage ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
Individual SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 11.479 3.016 3.806 0.000 5.559 17.399 776 SPV_indiv_message
condition_dummy 9.043 5.074 1.782 0.075 -0.917 19.004 776 SPV_indiv_message
PID_dummy -10.487 5.260 -1.994 0.047 -20.813 -0.161 776 SPV_indiv_message
PID_bin 1.658 1.939 0.855 0.393 -2.149 5.464 776 SPV_indiv_message
condition_dummy:PID_dummy -10.092 7.429 -1.358 0.175 -24.675 4.492 776 SPV_indiv_message
condition_dummy:PID_bin -4.948 3.103 -1.595 0.111 -11.039 1.142 776 SPV_indiv_message
PID_dummy:PID_bin 8.394 3.593 2.336 0.020 1.340 15.448 776 SPV_indiv_message
condition_dummy:PID_dummy:PID_bin 4.245 5.458 0.778 0.437 -6.470 14.960 776 SPV_indiv_message
Meta-Perceptions Republican SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 32.821 4.818 6.813 0.000 23.364 42.278 775 SPV_meta_message
condition_dummy 16.817 7.474 2.250 0.025 2.144 31.489 775 SPV_meta_message
PID_dummy -25.232 6.005 -4.202 0.000 -37.021 -13.443 775 SPV_meta_message
PID_bin 0.340 2.940 0.116 0.908 -5.432 6.112 775 SPV_meta_message
condition_dummy:PID_dummy 2.535 10.416 0.243 0.808 -17.911 22.982 775 SPV_meta_message
condition_dummy:PID_bin -7.061 4.498 -1.570 0.117 -15.890 1.769 775 SPV_meta_message
PID_dummy:PID_bin 9.672 3.970 2.436 0.015 1.880 17.465 775 SPV_meta_message
condition_dummy:PID_dummy:PID_bin -3.328 6.882 -0.484 0.629 -16.837 10.180 775 SPV_meta_message
Individual SPV (Republicans Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 0.992 4.310 0.230 0.818 -7.496 9.480 254 spv_Rmessage
condition_dummy -1.048 5.426 -0.193 0.847 -11.735 9.638 254 spv_Rmessage
PID_bin 10.052 3.025 3.323 0.001 4.094 16.009 254 spv_Rmessage
condition_dummy:PID_bin -0.703 4.491 -0.157 0.876 -9.547 8.140 254 spv_Rmessage
Individual SPV (Democrats Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 11.479 3.016 3.806 0.000 5.555 17.403 522 spv_Dmessage
condition_dummy 9.043 5.074 1.782 0.075 -0.924 19.011 522 spv_Dmessage
PID_bin 1.658 1.939 0.855 0.393 -2.152 5.467 522 spv_Dmessage
condition_dummy:PID_bin -4.948 3.103 -1.595 0.111 -11.044 1.147 522 spv_Dmessage

Party ID (Dummy)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
emm_message_indiv <- emmeans(lm_message_indiv, ~ condition_dummy * PID_dummy,
                             vcov. = vcov(lm_message_indiv))
emm_message_indiv_df <- as.data.frame(confint(emm_message_indiv)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_message_indiv <- contrast(emm_message_indiv,
                                method = list(
                                  "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                  "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                  "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                  "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_message_indiv_df <- as.data.frame(confint(contr_message_indiv))
contr_table_message_indiv <- summary(contr_message_indiv) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R 2.162887 2.665734 776 0.8113664 0.4174041
Control D vs. Treatment D 1.586123 2.048571 776 0.7742580 0.4390141
Control R vs. Treatment R -2.108281 3.401649 776 -0.6197822 0.5355832
Treatment D vs. Treatment R -1.531517 2.943080 776 -0.5203789 0.6029480
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
emm_message_meta_R <- emmeans(lm_message_meta_R, ~ condition_dummy * PID_dummy,
                              vcov. = vcov(lm_message_meta_R))
emm_message_meta_R_df <- as.data.frame(confint(emm_message_meta_R)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_message_meta_R <- contrast(emm_message_meta_R,
                                 method = list(
                                   "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                   "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                   "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                   "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_message_meta_R_df <- as.data.frame(confint(contr_message_meta_R))
contr_table_message_meta_R <- summary(contr_message_meta_R) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -10.656018 2.905269 775 -3.667825 0.0002613
Control D vs. Treatment D 6.176294 2.905850 775 2.125469 0.0338632
Control R vs. Treatment R 3.695746 3.556667 775 1.039104 0.2990806
Treatment D vs. Treatment R -13.136567 3.557142 775 -3.693012 0.0002372

Party ID (7-pt)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
message_indiv_partyaffil <- lm_robust(SPV_indiv_message ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_message_indiv_partyaffil<- emmeans(message_indiv_partyaffil, ~ condition_dummy * party_numeric,
                                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                       vcov. = vcov(message_indiv_partyaffil))
contr_message_indiv_partyaffil<- contrast(emm_message_indiv_partyaffil,
                                          method = list("Treatment - Control" = c(-1, 1)),
                                          by = "party_numeric")
contr_message_indiv_partyaffil_df <- confint(contr_message_indiv_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Individual Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 1.4912600 2.324198 784 -3.071128 6.053648 Strong D Individual Ratings
Treatment - Control 2 0.7895172 1.870194 784 -2.881664 4.460698 Weak D Individual Ratings
Treatment - Control 3 0.0877744 1.734743 784 -3.317516 3.493065 Lean D Individual Ratings
Treatment - Control 5 -1.3157113 2.506126 784 -6.235223 3.603801 Lean R Individual Ratings
Treatment - Control 6 -2.0174541 3.168643 784 -8.237483 4.202575 Weak R Individual Ratings
Treatment - Control 7 -2.7191969 3.900757 784 -10.376361 4.937967 Strong R Individual Ratings
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
message_meta_R_partyaffil <- lm_robust(SPV_meta_message ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_message_meta_R_partyaffil<- emmeans(message_meta_R_partyaffil, ~ condition_dummy * party_numeric,
                                        at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                        vcov. = vcov(message_meta_R_partyaffil))
contr_message_meta_R_partyaffil<- contrast(emm_message_meta_R_partyaffil,
                                           method = list("Treatment - Control" = c(-1, 1)),
                                           by = "party_numeric")
contr_message_meta_R_partyaffil_df <- confint(contr_message_meta_R_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Meta-Perceptions of Republicans' Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 5.807870 3.289241 783 -0.6489039 12.264644 Strong D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 2 5.593071 2.658699 783 0.3740494 10.812093 Weak D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 3 5.378273 2.285402 783 0.8920331 9.864513 Lean D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 5 4.948676 2.691882 783 -0.3354840 10.232836 Lean R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 6 4.733878 3.333919 783 -1.8106001 11.278356 Weak R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 7 4.519079 4.109575 783 -3.5480098 12.586169 Strong R Meta-Perceptions of Republicans’ Ratings

Party ID (7-pt) + Partisan Self-Concept

lm_message_indiv_R_7 <- lm_robust(SPV_indiv_message ~ condition_dummy * party_numeric * PID_bin,
                                  data = data_clean, se_type = "HC2")
emm_message_indiv_R_7<- emmeans(lm_message_indiv_R_7, ~ condition_dummy | party_numeric,
                                at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                vcov. = vcov(lm_message_indiv_R_7))
contr_message_indiv_R_7<- contrast(emm_message_indiv_R_7,
                                   method = list("Treatment - Control" = c(-1, 1)),
                                   by = "party_numeric")
contr_message_indiv_R_7_df <- as.data.frame(confint(contr_message_indiv_R_7))
contr_table_message_indiv_R_7_df <- summary(contr_message_indiv_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 2.4302838 2.392370 776 1.0158477 0.3100185 Strong D
Treatment - Control 2 1.5926309 1.961566 776 0.8119181 0.4170876 Weak D
Treatment - Control 3 0.7549779 1.804752 776 0.4183277 0.6758233 Lean D
Treatment - Control 5 -0.9203281 2.435399 776 -0.3778961 0.7056111 Lean R
Treatment - Control 6 -1.7579810 3.032461 776 -0.5797209 0.5622711 Weak R
Treatment - Control 7 -2.5956340 3.707500 776 -0.7001037 0.4840724 Strong R
lm_message_meta_R_7 <- lm_robust(SPV_meta_message ~ condition_dummy * party_numeric * PID_bin,
                                 data = data_clean, se_type = "HC2")
emm_message_meta_R_7<- emmeans(lm_message_meta_R_7, ~ condition_dummy | party_numeric,
                               at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                               vcov. = vcov(lm_message_meta_R_7))
contr_message_meta_R_7<- contrast(emm_message_meta_R_7,
                                  method = list("Treatment - Control" = c(-1, 1)),
                                  by = "party_numeric")
contr_message_meta_R_7_df <- as.data.frame(confint(contr_message_meta_R_7))
contr_table_message_meta_R_7_df <- summary(contr_message_meta_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 6.025631 3.479417 775 1.731793 0.0837083 Strong D
Treatment - Control 2 5.814006 2.800035 775 2.076405 0.0381856 Weak D
Treatment - Control 3 5.602382 2.355789 775 2.378134 0.0176420 Lean D
Treatment - Control 5 5.179133 2.626008 775 1.972246 0.0489367 Lean R
Treatment - Control 6 4.967509 3.245389 775 1.530636 0.1262675 Weak R
Treatment - Control 7 4.755884 4.018068 775 1.183625 0.2369246 Strong R

Factor models for panel plots

message_indiv_factor <- lm_robust(SPV_indiv_message ~ condition_dummy * factor(party_numeric),
                                  data = data_clean, se_type = "HC2")
emm_message_indiv_factor <- emmeans(message_indiv_factor, ~ condition_dummy | party_numeric,
                                    vcov. = vcov(message_indiv_factor))
contr_message_indiv_factor_df <- confint(contrast(emm_message_indiv_factor,
                                                  method = list("Treatment - Control" = c(-1, 1)),
                                                  by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

message_meta_R_factor <- lm_robust(SPV_meta_message ~ condition_dummy * factor(party_numeric),
                                   data = data_clean, se_type = "HC2")
emm_message_meta_R_factor <- emmeans(message_meta_R_factor, ~ condition_dummy | party_numeric,
                                     vcov. = vcov(message_meta_R_factor))
contr_message_meta_R_factor_df <- confint(contrast(emm_message_meta_R_factor,
                                                   method = list("Treatment - Control" = c(-1, 1)),
                                                   by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

p_message_indiv <- make_SPV_panels(
  "SPV_indiv_message",
  contr_message_indiv_partyaffil_df,
  contr_message_indiv_factor_df,
  "Individual SPV: Message\n(raw mean)",
  "Figure: Messaging Threats Online — Individual Ratings",
  color_A = c("Control R" = "goldenrod", "Treatment R" = "khaki",
              "Control D" = "gold",       "Treatment D" = "wheat"))

p_message_meta_R <- make_SPV_panels(
  "SPV_meta_message",
  contr_message_meta_R_partyaffil_df,
  contr_message_meta_R_factor_df,
  "Meta-Perceptions of Republican SPV: Message\n(raw mean)",
  "Figure: Messaging Threats Online — Meta-Perceptions",
  color_A = c("Control R" = "goldenrod", "Treatment R" = "khaki",
              "Control D" = "gold",       "Treatment D" = "wheat"))

Scenario: Physically assaulting an out-party member

Models

# 1.1: form models for:
# A: Individual SPV (Aggregated)
lm_assault_indiv <- lm_robust(SPV_indiv_assault ~ condition_dummy * PID_dummy * PID_bin,
                              data = data_clean, se_type = "HC2")
# B: Meta-Perceptions of Republican SPV 
lm_assault_meta_R <- lm_robust(SPV_meta_assault ~ condition_dummy * PID_dummy * PID_bin,
                               data = data_clean, se_type = "HC2")
# C: Individual SPV (Reps only)
lm_R_assault <- lm_robust(spv_Rassault ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
# D: Individual SPV (Dems only)
lm_D_assault <- lm_robust(spv_Dassault ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
Individual SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 9.179 2.423 3.788 0.000 4.422 13.936 776 SPV_indiv_assault
condition_dummy 10.027 4.814 2.083 0.038 0.577 19.476 776 SPV_indiv_assault
PID_dummy -12.890 3.770 -3.419 0.001 -20.291 -5.489 776 SPV_indiv_assault
PID_bin 1.572 1.618 0.972 0.331 -1.603 4.748 776 SPV_indiv_assault
condition_dummy:PID_dummy -8.759 6.489 -1.350 0.177 -21.498 3.980 776 SPV_indiv_assault
condition_dummy:PID_bin -5.673 2.875 -1.973 0.049 -11.316 -0.029 776 SPV_indiv_assault
PID_dummy:PID_bin 10.652 3.038 3.506 0.000 4.687 16.616 776 SPV_indiv_assault
condition_dummy:PID_dummy:PID_bin 4.767 5.008 0.952 0.341 -5.063 14.597 776 SPV_indiv_assault
Meta-Perceptions Republican SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 32.391 4.947 6.548 0.000 22.681 42.102 776 SPV_meta_assault
condition_dummy 18.053 7.672 2.353 0.019 2.991 33.114 776 SPV_meta_assault
PID_dummy -32.920 5.765 -5.711 0.000 -44.237 -21.604 776 SPV_meta_assault
PID_bin 0.344 3.010 0.114 0.909 -5.565 6.252 776 SPV_meta_assault
condition_dummy:PID_dummy 7.925 10.202 0.777 0.438 -12.101 27.951 776 SPV_meta_assault
condition_dummy:PID_bin -7.579 4.616 -1.642 0.101 -16.641 1.483 776 SPV_meta_assault
PID_dummy:PID_bin 14.458 3.898 3.709 0.000 6.805 22.111 776 SPV_meta_assault
condition_dummy:PID_dummy:PID_bin -7.131 6.747 -1.057 0.291 -20.376 6.114 776 SPV_meta_assault
Individual SPV (Republicans Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -3.711 2.888 -1.285 0.200 -9.399 1.976 254 spv_Rassault
condition_dummy 1.268 4.352 0.291 0.771 -7.303 9.838 254 spv_Rassault
PID_bin 12.224 2.572 4.753 0.000 7.159 17.289 254 spv_Rassault
condition_dummy:PID_bin -0.906 4.100 -0.221 0.825 -8.981 7.169 254 spv_Rassault
Individual SPV (Democrats Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 9.179 2.423 3.788 0.000 4.418 13.940 522 spv_Dassault
condition_dummy 10.027 4.814 2.083 0.038 0.570 19.484 522 spv_Dassault
PID_bin 1.572 1.618 0.972 0.331 -1.605 4.750 522 spv_Dassault
condition_dummy:PID_bin -5.673 2.875 -1.973 0.049 -11.320 -0.025 522 spv_Dassault

Party ID (Dummy)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
emm_assault_indiv <- emmeans(lm_assault_indiv, ~ condition_dummy * PID_dummy,
                             vcov. = vcov(lm_assault_indiv))
emm_assault_indiv_df <- as.data.frame(confint(emm_assault_indiv)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_assault_indiv <- contrast(emm_assault_indiv,
                                method = list(
                                  "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                  "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                  "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                  "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_assault_indiv_df <- as.data.frame(confint(contr_assault_indiv))
contr_table_assault_indiv <- summary(contr_assault_indiv) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R 3.161920 2.421940 776 1.3055317 0.1920988
Control D vs. Treatment D 1.477989 1.862313 776 0.7936311 0.4276528
Control R vs. Treatment R -0.097438 3.235799 776 -0.0301125 0.9759851
Treatment D vs. Treatment R 1.586492 2.841269 776 0.5583746 0.5767497
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
emm_assault_meta_R <- emmeans(lm_assault_meta_R, ~ condition_dummy * PID_dummy,
                              vcov. = vcov(lm_assault_meta_R))
emm_assault_meta_R_df <- as.data.frame(confint(emm_assault_meta_R)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_assault_meta_R <- contrast(emm_assault_meta_R,
                                 method = list(
                                   "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                   "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                   "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                   "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_assault_meta_R_df <- as.data.frame(confint(contr_assault_meta_R))
contr_table_assault_meta_R <- summary(contr_assault_meta_R) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -11.131716 2.804346 776 -3.969451 0.0000787
Control D vs. Treatment D 6.631068 2.886408 776 2.297343 0.0218646
Control R vs. Treatment R 3.809534 3.341862 776 1.139943 0.2546615
Treatment D vs. Treatment R -13.953250 3.411016 776 -4.090643 0.0000475

Party ID (7-pt)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
assault_indiv_partyaffil <- lm_robust(SPV_indiv_assault ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_assault_indiv_partyaffil<- emmeans(assault_indiv_partyaffil, ~ condition_dummy * party_numeric,
                                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                       vcov. = vcov(assault_indiv_partyaffil))
contr_assault_indiv_partyaffil<- contrast(emm_assault_indiv_partyaffil,
                                          method = list("Treatment - Control" = c(-1, 1)),
                                          by = "party_numeric")
contr_assault_indiv_partyaffil_df <- confint(contr_assault_indiv_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Individual Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 0.8867638 2.117820 784 -3.270506 5.044033 Strong D Individual Ratings
Treatment - Control 2 0.7101517 1.697449 784 -2.621932 4.042235 Weak D Individual Ratings
Treatment - Control 3 0.5335396 1.602081 784 -2.611337 3.678416 Lean D Individual Ratings
Treatment - Control 5 0.1803155 2.409315 784 -4.549156 4.909787 Lean R Individual Ratings
Treatment - Control 6 0.0037034 3.059020 784 -6.001136 6.008542 Weak R Individual Ratings
Treatment - Control 7 -0.1729087 3.768231 784 -7.569925 7.224108 Strong R Individual Ratings
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
assault_meta_R_partyaffil <- lm_robust(SPV_meta_assault ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_assault_meta_R_partyaffil<- emmeans(assault_meta_R_partyaffil, ~ condition_dummy * party_numeric,
                                        at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                        vcov. = vcov(assault_meta_R_partyaffil))
contr_assault_meta_R_partyaffil<- contrast(emm_assault_meta_R_partyaffil,
                                           method = list("Treatment - Control" = c(-1, 1)),
                                           by = "party_numeric")
contr_assault_meta_R_partyaffil_df <- confint(contr_assault_meta_R_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Meta-Perceptions of Republicans' Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 6.562129 3.253665 784 0.1752020 12.94906 Strong D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 2 6.167428 2.634814 784 0.9953029 11.33955 Weak D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 3 5.772727 2.257687 784 1.3408998 10.20455 Lean D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 5 4.983325 2.608441 784 -0.1370299 10.10368 Lean R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 6 4.588624 3.218054 784 -1.7283977 10.90565 Weak R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 7 4.193923 3.963178 784 -3.5857725 11.97362 Strong R Meta-Perceptions of Republicans’ Ratings

Party ID (7-pt) + Partisan Self-Concept

lm_assault_indiv_R_7 <- lm_robust(SPV_indiv_assault ~ condition_dummy * party_numeric * PID_bin,
                                  data = data_clean, se_type = "HC2")
emm_assault_indiv_R_7<- emmeans(lm_assault_indiv_R_7, ~ condition_dummy | party_numeric,
                                at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                vcov. = vcov(lm_assault_indiv_R_7))
contr_assault_indiv_R_7<- contrast(emm_assault_indiv_R_7,
                                   method = list("Treatment - Control" = c(-1, 1)),
                                   by = "party_numeric")
contr_assault_indiv_R_7_df <- as.data.frame(confint(contr_assault_indiv_R_7))
contr_table_assault_indiv_R_7_df <- summary(contr_assault_indiv_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 1.7998829 2.238053 776 0.8042181 0.4215173 Strong D
Treatment - Control 2 1.5032622 1.829128 776 0.8218464 0.4114168 Weak D
Treatment - Control 3 1.2066415 1.683575 776 0.7167137 0.4737664 Lean D
Treatment - Control 5 0.6134002 2.295110 776 0.2672640 0.7893369 Lean R
Treatment - Control 6 0.3167795 2.865644 776 0.1105439 0.9120066 Weak R
Treatment - Control 7 0.0201588 3.508303 776 0.0057460 0.9954168 Strong R
lm_assault_meta_R_7 <- lm_robust(SPV_meta_assault ~ condition_dummy * party_numeric * PID_bin,
                                 data = data_clean, se_type = "HC2")
emm_assault_meta_R_7<- emmeans(lm_assault_meta_R_7, ~ condition_dummy | party_numeric,
                               at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                               vcov. = vcov(lm_assault_meta_R_7))
contr_assault_meta_R_7<- contrast(emm_assault_meta_R_7,
                                  method = list("Treatment - Control" = c(-1, 1)),
                                  by = "party_numeric")
contr_assault_meta_R_7_df <- as.data.frame(confint(contr_assault_meta_R_7))
contr_table_assault_meta_R_7_df <- summary(contr_assault_meta_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 6.604987 3.443888 776 1.917887 0.0554921 Strong D
Treatment - Control 2 6.283123 2.774568 776 2.264541 0.0238159 Weak D
Treatment - Control 3 5.961260 2.317901 776 2.571836 0.0103011 Lean D
Treatment - Control 5 5.317533 2.496252 776 2.130207 0.0334685 Lean R
Treatment - Control 6 4.995669 3.068459 776 1.628071 0.1039157 Weak R
Treatment - Control 7 4.673806 3.799498 776 1.230111 0.2190282 Strong R

Factor models for panel plots

assault_indiv_factor <- lm_robust(SPV_indiv_assault ~ condition_dummy * factor(party_numeric),
                                  data = data_clean, se_type = "HC2")
emm_assault_indiv_factor <- emmeans(assault_indiv_factor, ~ condition_dummy | party_numeric,
                                    vcov. = vcov(assault_indiv_factor))
contr_assault_indiv_factor_df <- confint(contrast(emm_assault_indiv_factor,
                                                  method = list("Treatment - Control" = c(-1, 1)),
                                                  by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

assault_meta_R_factor <- lm_robust(SPV_meta_assault ~ condition_dummy * factor(party_numeric),
                                   data = data_clean, se_type = "HC2")
emm_assault_meta_R_factor <- emmeans(assault_meta_R_factor, ~ condition_dummy | party_numeric,
                                     vcov. = vcov(assault_meta_R_factor))
contr_assault_meta_R_factor_df <- confint(contrast(emm_assault_meta_R_factor,
                                                   method = list("Treatment - Control" = c(-1, 1)),
                                                   by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

p_assault_indiv <- make_SPV_panels(
  "SPV_indiv_assault",
  contr_assault_indiv_partyaffil_df,
  contr_assault_indiv_factor_df,
  "Individual SPV: Assault\n(raw mean)",
  "Figure: Physically Assaulting an Out-Partisan — Individual Ratings",
  color_A = c("Control R" = "forestgreen", "Treatment R" = "yellowgreen",
              "Control D" = "limegreen",    "Treatment D" = "greenyellow"))

p_assault_meta_R <- make_SPV_panels(
  "SPV_meta_assault",
  contr_assault_meta_R_partyaffil_df,
  contr_assault_meta_R_factor_df,
  "Meta-Perceptions of Republican SPV: Assault\n(raw mean)",
  "Figure: Physically Assaulting an Out-Partisan — Meta-Perceptions",
  color_A = c("Control R" = "forestgreen", "Treatment R" = "yellowgreen",
              "Control D" = "limegreen",    "Treatment D" = "greenyellow"))

Scenario: To achieve political goals

Models

# 1.1: form models for:
# A: Individual SPV (Aggregated)
lm_justify_indiv <- lm_robust(SPV_indiv_justify ~ condition_dummy * PID_dummy * PID_bin,
                              data = data_clean, se_type = "HC2")
# B: Meta-Perceptions of Republican SPV 
lm_justify_meta_R <- lm_robust(SPV_meta_justify ~ condition_dummy * PID_dummy * PID_bin,
                               data = data_clean, se_type = "HC2")
# C: Individual SPV (Reps only)
lm_R_justify <- lm_robust(spv_Rjustify ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
# D: Individual SPV (Dems only)
lm_D_justify <- lm_robust(spv_Djustify ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
Individual SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 14.413 3.166 4.553 0.000 8.198 20.627 777 SPV_indiv_justify
condition_dummy 8.146 5.645 1.443 0.149 -2.936 19.228 777 SPV_indiv_justify
PID_dummy -10.883 6.054 -1.798 0.073 -22.768 1.001 777 SPV_indiv_justify
PID_bin 0.348 1.954 0.178 0.859 -3.488 4.184 777 SPV_indiv_justify
condition_dummy:PID_dummy -13.252 8.346 -1.588 0.113 -29.634 3.131 777 SPV_indiv_justify
condition_dummy:PID_bin -3.449 3.395 -1.016 0.310 -10.113 3.215 777 SPV_indiv_justify
PID_dummy:PID_bin 7.190 3.988 1.803 0.072 -0.638 15.018 777 SPV_indiv_justify
condition_dummy:PID_dummy:PID_bin 5.163 5.825 0.886 0.376 -6.272 16.598 777 SPV_indiv_justify
Meta-Perceptions Republican SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 41.347 5.020 8.237 0.000 31.493 51.201 777 SPV_meta_justify
condition_dummy 2.817 7.838 0.359 0.719 -12.568 18.202 777 SPV_meta_justify
PID_dummy -29.849 6.339 -4.709 0.000 -42.293 -17.405 777 SPV_meta_justify
PID_bin -1.137 3.082 -0.369 0.712 -7.188 4.913 777 SPV_meta_justify
condition_dummy:PID_dummy 11.064 10.896 1.015 0.310 -10.324 32.452 777 SPV_meta_justify
condition_dummy:PID_bin 0.982 4.728 0.208 0.835 -8.300 10.264 777 SPV_meta_justify
PID_dummy:PID_bin 7.981 4.150 1.923 0.055 -0.166 16.127 777 SPV_meta_justify
condition_dummy:PID_dummy:PID_bin -9.722 6.998 -1.389 0.165 -23.459 4.015 777 SPV_meta_justify
Individual SPV (Republicans Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 3.529 5.161 0.684 0.495 -6.634 13.692 255 spv_Rjustify
condition_dummy -5.106 6.146 -0.831 0.407 -17.210 6.998 255 spv_Rjustify
PID_bin 7.538 3.476 2.169 0.031 0.693 14.383 255 spv_Rjustify
condition_dummy:PID_bin 1.714 4.734 0.362 0.718 -7.608 11.036 255 spv_Rjustify
Individual SPV (Democrats Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 14.413 3.166 4.553 0.000 8.193 20.632 522 spv_Djustify
condition_dummy 8.146 5.645 1.443 0.150 -2.945 19.236 522 spv_Djustify
PID_bin 0.348 1.954 0.178 0.859 -3.491 4.187 522 spv_Djustify
condition_dummy:PID_bin -3.449 3.395 -1.016 0.310 -10.118 3.220 522 spv_Djustify

Party ID (Dummy)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
emm_justify_indiv <- emmeans(lm_justify_indiv, ~ condition_dummy * PID_dummy,
                             vcov. = vcov(lm_justify_indiv))
emm_justify_indiv_df <- as.data.frame(confint(emm_justify_indiv)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_justify_indiv <- contrast(emm_justify_indiv,
                                method = list(
                                  "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                  "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                  "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                  "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_justify_indiv_df <- as.data.frame(confint(contr_justify_indiv))
contr_table_justify_indiv <- summary(contr_justify_indiv) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -0.0481568 2.583281 777 -0.0186417 0.9851317
Control D vs. Treatment D 2.9481517 2.129194 777 1.3846327 0.1665623
Control R vs. Treatment R -2.5234938 3.168450 777 -0.7964442 0.4260171
Treatment D vs. Treatment R -5.5198023 2.810552 777 -1.9639568 0.0498912
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
emm_justify_meta_R <- emmeans(lm_justify_meta_R, ~ condition_dummy * PID_dummy,
                              vcov. = vcov(lm_justify_meta_R))
emm_justify_meta_R_df <- as.data.frame(confint(emm_justify_meta_R)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_justify_meta_R <- contrast(emm_justify_meta_R,
                                 method = list(
                                   "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                   "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                   "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                   "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_justify_meta_R_df <- as.data.frame(confint(contr_justify_meta_R))
contr_table_justify_meta_R <- summary(contr_justify_meta_R) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -17.822025 2.854089 777 -6.2443824 0.0000000
Control D vs. Treatment D 4.297555 2.926006 777 1.4687444 0.1423069
Control R vs. Treatment R 0.710639 3.206779 777 0.2216052 0.8246794
Treatment D vs. Treatment R -21.408941 3.270951 777 -6.5451737 0.0000000

Party ID (7-pt)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
justify_indiv_partyaffil <- lm_robust(SPV_indiv_justify ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_justify_indiv_partyaffil<- emmeans(justify_indiv_partyaffil, ~ condition_dummy * party_numeric,
                                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                       vcov. = vcov(justify_indiv_partyaffil))
contr_justify_indiv_partyaffil<- contrast(emm_justify_indiv_partyaffil,
                                          method = list("Treatment - Control" = c(-1, 1)),
                                          by = "party_numeric")
contr_justify_indiv_partyaffil_df <- confint(contr_justify_indiv_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Individual Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 2.5208248 2.394745 785 -2.180038 7.221687 Strong D Individual Ratings
Treatment - Control 2 1.8361252 1.938295 785 -1.968729 5.640979 Weak D Individual Ratings
Treatment - Control 3 1.1514257 1.745909 785 -2.275776 4.578628 Lean D Individual Ratings
Treatment - Control 5 -0.2179735 2.331890 785 -4.795451 4.359504 Lean R Individual Ratings
Treatment - Control 6 -0.9026731 2.921645 785 -6.637835 4.832489 Weak R Individual Ratings
Treatment - Control 7 -1.5873726 3.592122 785 -8.638675 5.463930 Strong R Individual Ratings
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
justify_meta_R_partyaffil <- lm_robust(SPV_meta_justify ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_justify_meta_R_partyaffil<- emmeans(justify_meta_R_partyaffil, ~ condition_dummy * party_numeric,
                                        at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                        vcov. = vcov(justify_meta_R_partyaffil))
contr_justify_meta_R_partyaffil<- contrast(emm_justify_meta_R_partyaffil,
                                           method = list("Treatment - Control" = c(-1, 1)),
                                           by = "party_numeric")
contr_justify_meta_R_partyaffil_df <- confint(contr_justify_meta_R_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Meta-Perceptions of Republicans' Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 5.133102 3.298748 785 -1.3423106 11.608514 Strong D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 2 4.458389 2.673551 785 -0.7897656 9.706544 Weak D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 3 3.783677 2.258464 785 -0.6496661 8.217021 Lean D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 5 2.434253 2.462964 785 -2.4005216 7.269027 Lean R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 6 1.759541 3.013127 785 -4.1551996 7.674281 Weak R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 7 1.084828 3.711918 785 -6.2016314 8.371288 Strong R Meta-Perceptions of Republicans’ Ratings

Party ID (7-pt) + Partisan Self-Concept

lm_justify_indiv_R_7 <- lm_robust(SPV_indiv_justify ~ condition_dummy * party_numeric * PID_bin,
                                  data = data_clean, se_type = "HC2")
emm_justify_indiv_R_7<- emmeans(lm_justify_indiv_R_7, ~ condition_dummy | party_numeric,
                                at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                vcov. = vcov(lm_justify_indiv_R_7))
contr_justify_indiv_R_7<- contrast(emm_justify_indiv_R_7,
                                   method = list("Treatment - Control" = c(-1, 1)),
                                   by = "party_numeric")
contr_justify_indiv_R_7_df <- as.data.frame(confint(contr_justify_indiv_R_7))
contr_table_justify_indiv_R_7_df <- summary(contr_justify_indiv_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 3.2048173 2.586395 777 1.2391060 0.2156804 Strong D
Treatment - Control 2 2.3796634 2.093036 777 1.1369435 0.2559124 Weak D
Treatment - Control 3 1.5545095 1.834173 777 0.8475260 0.3969630 Lean D
Treatment - Control 5 -0.0957982 2.281901 777 -0.0419818 0.9665240 Lean R
Treatment - Control 6 -0.9209521 2.840169 777 -0.3242596 0.7458288 Weak R
Treatment - Control 7 -1.7461060 3.495437 777 -0.4995387 0.6175414 Strong R
lm_justify_meta_R_7 <- lm_robust(SPV_meta_justify ~ condition_dummy * party_numeric * PID_bin,
                                 data = data_clean, se_type = "HC2")
emm_justify_meta_R_7<- emmeans(lm_justify_meta_R_7, ~ condition_dummy | party_numeric,
                               at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                               vcov. = vcov(lm_justify_meta_R_7))
contr_justify_meta_R_7<- contrast(emm_justify_meta_R_7,
                                  method = list("Treatment - Control" = c(-1, 1)),
                                  by = "party_numeric")
contr_justify_meta_R_7_df <- as.data.frame(confint(contr_justify_meta_R_7))
contr_table_justify_meta_R_7_df <- summary(contr_justify_meta_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 3.970401 3.486615 777 1.1387552 0.2551562 Strong D
Treatment - Control 2 3.687270 2.802397 777 1.3157557 0.1886441 Weak D
Treatment - Control 3 3.404140 2.317908 777 1.4686262 0.1423389 Lean D
Treatment - Control 5 2.837879 2.424495 777 1.1705031 0.2421574 Lean R
Treatment - Control 6 2.554748 2.977313 777 0.8580719 0.3911174 Weak R
Treatment - Control 7 2.271618 3.697692 777 0.6143340 0.5391745 Strong R

Factor models for panel plots

justify_indiv_factor <- lm_robust(SPV_indiv_justify ~ condition_dummy * factor(party_numeric),
                                  data = data_clean, se_type = "HC2")
emm_justify_indiv_factor <- emmeans(justify_indiv_factor, ~ condition_dummy | party_numeric,
                                    vcov. = vcov(justify_indiv_factor))
contr_justify_indiv_factor_df <- confint(contrast(emm_justify_indiv_factor,
                                                  method = list("Treatment - Control" = c(-1, 1)),
                                                  by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

justify_meta_R_factor <- lm_robust(SPV_meta_justify ~ condition_dummy * factor(party_numeric),
                                   data = data_clean, se_type = "HC2")
emm_justify_meta_R_factor <- emmeans(justify_meta_R_factor, ~ condition_dummy | party_numeric,
                                     vcov. = vcov(justify_meta_R_factor))
contr_justify_meta_R_factor_df <- confint(contrast(emm_justify_meta_R_factor,
                                                   method = list("Treatment - Control" = c(-1, 1)),
                                                   by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

p_justify_indiv <- make_SPV_panels(
  "SPV_indiv_justify",
  contr_justify_indiv_partyaffil_df,
  contr_justify_indiv_factor_df,
  "Individual SPV: Justify\n(raw mean)",
  "Figure: Achieving In-Party Political Goals — Individual Ratings",
  color_A = c("Control R" = "midnightblue", "Treatment R" = "deepskyblue",
              "Control D" = "dodgerblue",    "Treatment D" = "lightblue"))

p_justify_meta_R <- make_SPV_panels(
  "SPV_meta_justify",
  contr_justify_meta_R_partyaffil_df,
  contr_justify_meta_R_factor_df,
  "Meta-Perceptions of Republican SPV: Justify\n(raw mean)",
  "Figure: Achieving In-Party Political Goals — Meta-Perceptions",
  color_A = c("Control R" = "midnightblue", "Treatment R" = "deepskyblue",
              "Control D" = "dodgerblue",    "Treatment D" = "lightblue"))

Scenario: If the other party wins the next election

Models

# 1.1: form models for:
# A: Individual SPV (Aggregated)
lm_predict_indiv <- lm_robust(SPV_indiv_predict ~ condition_dummy * PID_dummy * PID_bin,
                              data = data_clean, se_type = "HC2")
# B: Meta-Perceptions of Republican SPV 
lm_predict_meta_R <- lm_robust(SPV_meta_predict ~ condition_dummy * PID_dummy * PID_bin,
                               data = data_clean, se_type = "HC2")
# C: Individual SPV (Reps only)
lm_R_predict <- lm_robust(spv_Rpredict ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
# D: Individual SPV (Dems only)
lm_D_predict <- lm_robust(spv_Dpredict ~ condition_dummy * PID_bin,
                          data = data_clean, se_type = "HC2")
Individual SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 8.684 2.738 3.171 0.002 3.309 14.060 774 SPV_indiv_predict
condition_dummy 17.457 5.768 3.027 0.003 6.135 28.780 774 SPV_indiv_predict
PID_dummy -10.176 4.263 -2.387 0.017 -18.544 -1.808 774 SPV_indiv_predict
PID_bin 2.585 1.848 1.399 0.162 -1.042 6.212 774 SPV_indiv_predict
condition_dummy:PID_dummy -19.921 7.012 -2.841 0.005 -33.686 -6.155 774 SPV_indiv_predict
condition_dummy:PID_bin -8.557 3.462 -2.471 0.014 -15.353 -1.760 774 SPV_indiv_predict
PID_dummy:PID_bin 5.563 3.183 1.748 0.081 -0.684 11.811 774 SPV_indiv_predict
condition_dummy:PID_dummy:PID_bin 9.284 5.019 1.850 0.065 -0.569 19.137 774 SPV_indiv_predict
Meta-Perceptions Republican SPV
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 39.627 5.498 7.207 0.000 28.834 50.420 775 SPV_meta_predict
condition_dummy 10.335 7.970 1.297 0.195 -5.311 25.981 775 SPV_meta_predict
PID_dummy -33.162 6.271 -5.288 0.000 -45.472 -20.851 775 SPV_meta_predict
PID_bin 2.282 3.347 0.682 0.496 -4.289 8.852 775 SPV_meta_predict
condition_dummy:PID_dummy 4.300 10.272 0.419 0.676 -15.864 24.464 775 SPV_meta_predict
condition_dummy:PID_bin -3.871 4.864 -0.796 0.426 -13.418 5.677 775 SPV_meta_predict
PID_dummy:PID_bin 5.689 4.083 1.393 0.164 -2.327 13.705 775 SPV_meta_predict
condition_dummy:PID_dummy:PID_bin -4.508 6.656 -0.677 0.498 -17.574 8.559 775 SPV_meta_predict
Individual SPV (Republicans Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) -1.492 3.267 -0.457 0.648 -7.926 4.942 255 spv_Rpredict
condition_dummy -2.463 3.988 -0.618 0.537 -10.317 5.390 255 spv_Rpredict
PID_bin 8.148 2.591 3.145 0.002 3.045 13.251 255 spv_Rpredict
condition_dummy:PID_bin 0.728 3.634 0.200 0.841 -6.429 7.884 255 spv_Rpredict
Individual SPV (Democrats Only)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 8.684 2.738 3.171 0.002 3.305 14.064 519 spv_Dpredict
condition_dummy 17.457 5.768 3.027 0.003 6.126 28.789 519 spv_Dpredict
PID_bin 2.585 1.848 1.399 0.162 -1.045 6.215 519 spv_Dpredict
condition_dummy:PID_bin -8.557 3.462 -2.471 0.014 -15.358 -1.755 519 spv_Dpredict

Party ID (Dummy)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
emm_predict_indiv <- emmeans(lm_predict_indiv, ~ condition_dummy * PID_dummy,
                             vcov. = vcov(lm_predict_indiv))
emm_predict_indiv_df <- as.data.frame(confint(emm_predict_indiv)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_predict_indiv <- contrast(emm_predict_indiv,
                                method = list(
                                  "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                  "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                  "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                  "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_predict_indiv_df <- as.data.frame(confint(contr_predict_indiv))
contr_table_predict_indiv <- summary(contr_predict_indiv) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -1.791972 2.244967 774 -0.7982174 0.4249892
Control D vs. Treatment D 4.562643 2.103483 774 2.1690898 0.0303796
Control R vs. Treatment R -1.366805 2.655832 774 -0.5146426 0.6069497
Treatment D vs. Treatment R -7.721419 2.537363 774 -3.0430884 0.0024208
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
emm_predict_meta_R <- emmeans(lm_predict_meta_R, ~ condition_dummy * PID_dummy,
                              vcov. = vcov(lm_predict_meta_R))
emm_predict_meta_R_df <- as.data.frame(confint(emm_predict_meta_R)) %>%
  mutate(
    condition_dummy = factor(condition_dummy, levels = c(0, 1),
                             labels = c("Control", "Treatment")),
    PID_dummy = factor(PID_dummy, levels = c(0, 1),
                       labels = c("Democrat", "Republican")),
    group = interaction(condition_dummy, PID_dummy))
contr_predict_meta_R <- contrast(emm_predict_meta_R,
                                 method = list(
                                   "Control D vs. Control R"     = c(-1,  0,  1,  0),
                                   "Control D vs. Treatment D"   = c(-1,  1,  0,  0),
                                   "Control R vs. Treatment R"   = c( 0,  0, -1,  1),
                                   "Treatment D vs. Treatment R" = c( 0, -1,  0,  1)))
contr_predict_meta_R_df <- as.data.frame(confint(contr_predict_meta_R))
contr_table_predict_meta_R <- summary(contr_predict_meta_R) |>
  as.data.frame() |>
  dplyr::select(contrast, estimate, SE, df, t.ratio, p.value)
contrast estimate SE df t.ratio p.value
Control D vs. Control R -24.588731 2.767836 775 -8.8837392 0.0000000
Control D vs. Treatment D 4.501966 3.006415 775 1.4974534 0.1346825
Control R vs. Treatment R 2.008337 3.010590 775 0.6670909 0.5049127
Treatment D vs. Treatment R -27.082360 3.231295 775 -8.3812707 0.0000000

Party ID (7-pt)

# form emmeans and contrast matrices for Individual SPV (Aggregated)
predict_indiv_partyaffil <- lm_robust(SPV_indiv_predict ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_predict_indiv_partyaffil<- emmeans(predict_indiv_partyaffil, ~ condition_dummy * party_numeric,
                                       at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                       vcov. = vcov(predict_indiv_partyaffil))
contr_predict_indiv_partyaffil<- contrast(emm_predict_indiv_partyaffil,
                                          method = list("Treatment - Control" = c(-1, 1)),
                                          by = "party_numeric")
contr_predict_indiv_partyaffil_df <- confint(contr_predict_indiv_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Individual Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 4.6637554 2.346620 782 0.0573361 9.270175 Strong D Individual Ratings
Treatment - Control 2 3.6530960 1.905508 782 -0.0874206 7.393613 Weak D Individual Ratings
Treatment - Control 3 2.6424366 1.660807 782 -0.6177305 5.902604 Lean D Individual Ratings
Treatment - Control 5 0.6211177 2.005456 782 -3.3155961 4.557832 Lean R Individual Ratings
Treatment - Control 6 -0.3895417 2.481554 782 -5.2608370 4.481753 Weak R Individual Ratings
Treatment - Control 7 -1.4002012 3.049155 782 -7.3856985 4.585296 Strong R Individual Ratings
# form emmeans and contrast matrices for Meta-Perceptions of Republican SPV
predict_meta_R_partyaffil <- lm_robust(SPV_meta_predict ~ condition_dummy * party_numeric, data = data_clean, se_type = "HC2")
emm_predict_meta_R_partyaffil<- emmeans(predict_meta_R_partyaffil, ~ condition_dummy * party_numeric,
                                        at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                        vcov. = vcov(predict_meta_R_partyaffil))
contr_predict_meta_R_partyaffil<- contrast(emm_predict_meta_R_partyaffil,
                                           method = list("Treatment - Control" = c(-1, 1)),
                                           by = "party_numeric")
contr_predict_meta_R_partyaffil_df <- confint(contr_predict_meta_R_partyaffil) |>
  as.data.frame() |>
  mutate(
    party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                         labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")),
    model = "Meta-Perceptions of Republicans' Ratings")
contrast party_numeric estimate SE df lower.CL upper.CL party_label model
Treatment - Control 1 4.927844 3.420618 783 -1.7868235 11.642511 Strong D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 2 4.620863 2.771708 783 -0.8199958 10.061721 Weak D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 3 4.313882 2.304094 783 -0.2090517 8.836815 Lean D Meta-Perceptions of Republicans’ Ratings
Treatment - Control 5 3.699919 2.344367 783 -0.9020688 8.301908 Lean R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 6 3.392938 2.838446 783 -2.1789269 8.964804 Weak R Meta-Perceptions of Republicans’ Ratings
Treatment - Control 7 3.085957 3.501749 783 -3.7879695 9.959884 Strong R Meta-Perceptions of Republicans’ Ratings

Party ID (7-pt) + Partisan Self-Concept

lm_predict_indiv_R_7 <- lm_robust(SPV_indiv_predict ~ condition_dummy * party_numeric * PID_bin,
                                  data = data_clean, se_type = "HC2")
emm_predict_indiv_R_7<- emmeans(lm_predict_indiv_R_7, ~ condition_dummy | party_numeric,
                                at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                                vcov. = vcov(lm_predict_indiv_R_7))
contr_predict_indiv_R_7<- contrast(emm_predict_indiv_R_7,
                                   method = list("Treatment - Control" = c(-1, 1)),
                                   by = "party_numeric")
contr_predict_indiv_R_7_df <- as.data.frame(confint(contr_predict_indiv_R_7))
contr_table_predict_indiv_R_7_df <- summary(contr_predict_indiv_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 6.5198746 2.548158 774 2.5586618 0.0106968 Strong D
Treatment - Control 2 4.9436022 2.063012 774 2.3963035 0.0167978 Weak D
Treatment - Control 3 3.3673299 1.743837 774 1.9309884 0.0538494 Lean D
Treatment - Control 5 0.2147852 1.917551 774 0.1120101 0.9108444 Lean R
Treatment - Control 6 -1.3614872 2.351188 774 -0.5790636 0.5627147 Weak R
Treatment - Control 7 -2.9377596 2.898484 774 -1.0135504 0.3111140 Strong R
lm_predict_meta_R_7 <- lm_robust(SPV_meta_predict ~ condition_dummy * party_numeric * PID_bin,
                                 data = data_clean, se_type = "HC2")
emm_predict_meta_R_7<- emmeans(lm_predict_meta_R_7, ~ condition_dummy | party_numeric,
                               at = list(party_numeric = c(1, 2, 3, 5, 6, 7)),
                               vcov. = vcov(lm_predict_meta_R_7))
contr_predict_meta_R_7<- contrast(emm_predict_meta_R_7,
                                  method = list("Treatment - Control" = c(-1, 1)),
                                  by = "party_numeric")
contr_predict_meta_R_7_df <- as.data.frame(confint(contr_predict_meta_R_7))
contr_table_predict_meta_R_7_df <- summary(contr_predict_meta_R_7) |>
  as.data.frame() |>
  dplyr::select(contrast, party_numeric, estimate, SE, df, t.ratio, p.value) |>
  mutate(party_label = factor(party_numeric, levels = c(1, 2, 3, 5, 6, 7),
                              labels = c("Strong D","Weak D","Lean D","Lean R","Weak R","Strong R")))
contrast party_numeric estimate SE df t.ratio p.value party_label
Treatment - Control 1 4.468594 3.605082 775 1.2395262 0.2155259 Strong D
Treatment - Control 2 4.297298 2.898957 775 1.4823598 0.1386511 Weak D
Treatment - Control 3 4.126001 2.362126 775 1.7467323 0.0810799 Lean D
Treatment - Control 5 3.783408 2.288245 775 1.6534103 0.0986524 Lean R
Treatment - Control 6 3.612111 2.777914 775 1.3002961 0.1938861 Weak R
Treatment - Control 7 3.440814 3.459177 775 0.9946917 0.3201967 Strong R

Factor models for panel plots

predict_indiv_factor <- lm_robust(SPV_indiv_predict ~ condition_dummy * factor(party_numeric),
                                  data = data_clean, se_type = "HC2")
emm_predict_indiv_factor <- emmeans(predict_indiv_factor, ~ condition_dummy | party_numeric,
                                    vcov. = vcov(predict_indiv_factor))
contr_predict_indiv_factor_df <- confint(contrast(emm_predict_indiv_factor,
                                                  method = list("Treatment - Control" = c(-1, 1)),
                                                  by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

predict_meta_R_factor <- lm_robust(SPV_meta_predict ~ condition_dummy * factor(party_numeric),
                                   data = data_clean, se_type = "HC2")
emm_predict_meta_R_factor <- emmeans(predict_meta_R_factor, ~ condition_dummy | party_numeric,
                                     vcov. = vcov(predict_meta_R_factor))
contr_predict_meta_R_factor_df <- confint(contrast(emm_predict_meta_R_factor,
                                                   method = list("Treatment - Control" = c(-1, 1)),
                                                   by = "party_numeric")) |>
  as.data.frame() |>
  mutate(party_numeric = as.numeric(as.character(party_numeric)))

p_predict_indiv <- make_SPV_panels(
  "SPV_indiv_predict",
  contr_predict_indiv_partyaffil_df,
  contr_predict_indiv_factor_df,
  "Individual SPV: Predict\n(raw mean)",
  "Figure: If Opposing Party Wins Next Election — Individual Ratings",
  color_A = c("Control R" = "darkorchid", "Treatment R" = "plum",
              "Control D" = "orchid",      "Treatment D" = "thistle"))

p_predict_meta_R <- make_SPV_panels(
  "SPV_meta_predict",
  contr_predict_meta_R_partyaffil_df,
  contr_predict_meta_R_factor_df,
  "Meta-Perceptions of Republican SPV: Predict\n(raw mean)",
  "Figure: If Opposing Party Wins Next Election — Meta-Perceptions",
  color_A = c("Control R" = "darkorchid", "Treatment R" = "plum",
              "Control D" = "orchid",      "Treatment D" = "thistle"))

Binned Scenarios SPV

Secondarily to the scenario-specific models, I plan to combine the four scenario-specific questions and the two broad-based questions into two, distinct averages measuring individual and meta-perceptions of Republicans’ SPV. I will then apply the same Ordinary Least Squares (OLS) linear regression models with heteroskedasticity-robust standard errors to these aggregated variables, including the exact same covariates as for each of the six individual questions regarding SPV scenarios.

I deviated from the pre-analysis plan by removing the additional specified covariates from each model, as this simplifies the ability to draw conclusions about the average treatment effect. The only covariates included are PID_dummy, which represents the dichotomous effect of being a Democrat versus a Republican, and PID_bin, the grouped version of partisan self-concept.

Create four baseline models

lm_indiv_scenario <- lm_robust(SPV_indiv_scenario ~ condition_dummy, data = data_clean)
lm_indiv_broad <- lm_robust(SPV_indiv_broad ~ condition_dummy, data = data_clean)
lm_meta_R_scenario <- lm_robust(SPV_meta_scenario ~ condition_dummy, data = data_clean)
lm_meta_R_broad <- lm_robust(SPV_meta_broad ~ condition_dummy, data = data_clean)
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 25.532 1.029 24.801 0.00 23.511 27.553 780 SPV_indiv_scenario
condition_dummy 2.373 1.525 1.556 0.12 -0.621 5.367 780 SPV_indiv_scenario
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 13.268 1.089 12.183 0.000 11.130 15.406 784 SPV_indiv_broad
condition_dummy 2.017 1.619 1.246 0.213 -1.161 5.195 784 SPV_indiv_broad
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 39.515 1.264 31.266 0.000 37.034 41.996 781 SPV_meta_scenario
condition_dummy 5.646 1.906 2.961 0.003 1.903 9.388 781 SPV_meta_scenario
term estimate std.error statistic p.value conf.low conf.high df outcome
(Intercept) 33.361 1.496 22.297 0.000 30.424 36.298 785 SPV_meta_broad
condition_dummy 5.446 2.242 2.429 0.015 1.045 9.847 785 SPV_meta_broad

INDIV_SCENARIO

# A: bivariate
lm_indiv_1 <- lm(SPV_indiv_scenario ~ condition_dummy, data = data_clean)
# B: multivariate
lm_indiv_1_cov <- lm(SPV_indiv_scenario ~ condition_dummy * PID_dummy * PID_bin,
                     data = data_clean)
term estimate std.error statistic p.value
(Intercept) 25.532 1.074 23.779 0.00
condition_dummy 2.373 1.524 1.557 0.12
term estimate std.error statistic p.value
(Intercept) 24.096 3.307 7.285 0.000
condition_dummy 10.277 4.731 2.172 0.030
PID_dummy -19.442 5.549 -3.504 0.000
PID_bin 1.379 2.017 0.683 0.495
condition_dummy:PID_dummy -3.594 8.072 -0.445 0.656
condition_dummy:PID_bin -4.166 2.861 -1.457 0.146
PID_dummy:PID_bin 11.729 3.407 3.443 0.001
condition_dummy:PID_dummy:PID_bin -0.921 5.019 -0.184 0.854

INDIV_BROAD

# A: bivariate
lm_indiv_2 <- lm(SPV_indiv_broad ~ condition_dummy, data = data_clean)
# B: multivariate
lm_indiv_2_cov <- lm(SPV_indiv_broad ~ condition_dummy * PID_dummy * PID_bin,
                     data = data_clean)
term estimate std.error statistic p.value
(Intercept) 13.268 1.141 11.626 0.000
condition_dummy 2.017 1.618 1.246 0.213
term estimate std.error statistic p.value
(Intercept) 11.304 3.612 3.129 0.002
condition_dummy 13.043 5.120 2.547 0.011
PID_dummy -10.285 5.997 -1.715 0.087
PID_bin 1.547 2.196 0.704 0.481
condition_dummy:PID_dummy -16.827 8.697 -1.935 0.053
condition_dummy:PID_bin -6.082 3.090 -1.968 0.049
PID_dummy:PID_bin 6.296 3.665 1.718 0.086
condition_dummy:PID_dummy:PID_bin 7.303 5.395 1.354 0.176

META_R_SCENARIO

# A: bivariate
lm_meta_R_1 <- lm(SPV_meta_scenario ~ condition_dummy, data = data_clean)
# B: multivariate
lm_meta_R_1_cov <- lm(SPV_meta_scenario ~ condition_dummy * PID_dummy * PID_bin,
                      data = data_clean)
term estimate std.error statistic p.value
(Intercept) 39.515 1.339 29.519 0.000
condition_dummy 5.646 1.904 2.965 0.003
term estimate std.error statistic p.value
(Intercept) 42.586 4.158 10.243 0.000
condition_dummy 14.340 5.947 2.411 0.016
PID_dummy -22.266 6.972 -3.194 0.001
PID_bin -0.156 2.536 -0.061 0.951
condition_dummy:PID_dummy 7.954 10.150 0.784 0.433
condition_dummy:PID_bin -5.355 3.594 -1.490 0.137
PID_dummy:PID_bin 9.710 4.271 2.274 0.023
condition_dummy:PID_dummy:PID_bin -7.892 6.317 -1.249 0.212

META_R_BROAD

# A: bivariate
lm_meta_R_2 <- lm(SPV_meta_broad ~ condition_dummy, data = data_clean)
# B: multivariate
lm_meta_R_2_cov <- lm(SPV_meta_broad ~ condition_dummy * PID_dummy * PID_bin,
                     data = data_clean)
term estimate std.error statistic p.value
(Intercept) 33.361 1.579 21.126 0.000
condition_dummy 5.446 2.240 2.431 0.015
term estimate std.error statistic p.value
(Intercept) 39.973 4.761 8.396 0.000
condition_dummy 7.090 6.748 1.051 0.294
PID_dummy -30.992 7.917 -3.915 0.000
PID_bin 0.859 2.898 0.297 0.767
condition_dummy:PID_dummy 7.535 11.485 0.656 0.512
condition_dummy:PID_bin -1.731 4.078 -0.425 0.671
PID_dummy:PID_bin 6.548 4.840 1.353 0.177
condition_dummy:PID_dummy:PID_bin -7.331 7.135 -1.027 0.305

Independent-Samples T-Tests

Lastly, in line with earlier work by Mernyk et al. (2022), I plan to perform three independent-samples t-tests comparing Republican to Democratic participants regarding their predicted and actual levels of support for political violence. The first t-test will compare Republicans’ reported individual SPV to Democrats’ meta-perceptions of Republicans’ SPV, while the second t-test will compare Republicans’ individual SPV to their own meta-perceptions of co-partisans’ SPV. The third t-test will compare meta-perceptions of Republicans’ SPV between Republicans and Democrats. I will use the standard p<.05 criteria in our two-tailed T-test to determine whether significant differences exist between individual support of partisan violence and meta-perceptions of Republicans’ support for partisan violence. For all t-tests, I plan to calculate the effect size as Cohen’s d.

# 8. outparty metaperceptions
# 8.1: actual views of R vs. how D think R will respond
t.test(na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_individual),
       na.omit((data_clean %>% filter(party_numeric <= 3))$SPV_meta_outgroup))
## 
##  Welch Two Sample t-test
## 
## data:  na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_individual) and na.omit((data_clean %>% filter(party_numeric <= 3))$SPV_meta_outgroup)
## t = -14.191, df = 628.49, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -28.62956 -21.66938
## sample estimates:
## mean of x mean of y 
##  19.62387  44.77333
# 8.2: effect size
cohen.d(na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_individual),
       na.omit((data_clean %>% filter(party_numeric <= 3))$SPV_meta_outgroup))
## 
## Cohen's d
## 
## d estimate: -0.996642 (large)
## 95 percent confidence interval:
##      lower      upper 
## -1.1540616 -0.8392224
# 9. inparty metaperceptions
# 9.1: actual views of R vs. how R think R will respond
t.test(na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_individual),
       na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_meta_ingroup))
## 
##  Welch Two Sample t-test
## 
## data:  na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_individual) and na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_meta_ingroup)
## t = -6.0073, df = 515, p-value = 3.568e-09
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -14.997798  -7.605754
## sample estimates:
## mean of x mean of y 
##  19.62387  30.92564
# 9.2: effect size
cohen.d(na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_individual),
        na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_meta_ingroup))
## 
## Cohen's d
## 
## d estimate: -0.5283701 (medium)
## 95 percent confidence interval:
##      lower      upper 
## -0.7041666 -0.3525736
# 10. are democrats' inaccuracies different from republicans' inaccuracies?
# 10.1: how D think R will respond vs. how R think R will respond
t.test(na.omit((data_clean %>% filter(party_numeric <= 3))$SPV_meta_outgroup),
       na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_meta_ingroup))
## 
##  Welch Two Sample t-test
## 
## data:  na.omit((data_clean %>% filter(party_numeric <= 3))$SPV_meta_outgroup) and na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_meta_ingroup)
## t = 7.7772, df = 629.73, p-value = 3.04e-14
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  10.35117 17.34422
## sample estimates:
## mean of x mean of y 
##  44.77333  30.92564
# 10.2: effect size
cohen.d(na.omit((data_clean %>% filter(party_numeric <= 3))$SPV_meta_outgroup),
        na.omit((data_clean %>% filter(party_numeric >= 4))$SPV_meta_ingroup))
## 
## Cohen's d
## 
## d estimate: 0.547227 (medium)
## 95 percent confidence interval:
##     lower     upper 
## 0.3959149 0.6985390