We are pivoting from the full 12-item SEB scale (descriptive + prescriptive) to prescriptive SEBs only (6 items). This document re-runs the key analyses from Study 1 (OCBI, UPB), Study 2 (status affordance), and the Study 3 manipulation pilot using only the prescriptive items, and puts the results side by side.
One question is whether prescriptive SEB has predictive power above and beyond status zero-sum beliefs (SZSB). Every model below is therefore fit in several specifications (bivariate → + SZSB → + all preregistered controls), and incremental tests are reported.
Prescriptive items used
| Study | Distribution-prescriptive | Attribute-prescriptive |
|---|---|---|
| Study 1 | dist_7, dist_8, dist_10
(original wording) |
attr_6, attr_8, attr_10 |
| Study 2, Study 3 pilot | dist_14, dist_15, dist_16
(revised wording) |
attr_6, attr_8, attr_10 |
Heads up: Study 1 used the original distribution-prescriptive wording (alpha = .61 in Study 1 notes). Studies 2 and 3 used the revised items that match the six statements in the email to Adam. So the Study 1 composite is not item-identical to the Study 2/3 composite. The alpha table below shows whether this matters.
Item wording below is taken from the question-text row of the
Qualtrics exports (raw_study1_data_8_4_25.csv,
raw_study2_fulldata_10_8_25.csv,
pilot_raw_data_11_11_25.csv). Items marked (R) are
reverse-scored (8 - x) in the code. All items use 1 = strongly disagree
to 7 = strongly agree unless noted otherwise.
Stem (all studies): “To what extent do you agree or disagree with each of the following statements about your team?” followed by “In my team…”
Team referent differs by study:
| Subscale | Study 1 (variable) | Study 2 and Study 3 pilot (variable) |
|---|---|---|
| Distribution | …Everyone who wants status should be able to attain it.
(dist_7) |
…Many members should be able to gain respect and admiration.
(dist_14) |
| Distribution | …All members should have the opportunity to be valued and admired.
(dist_8) |
…High status should not be granted to just a few people.
(dist_15) |
| Distribution | …Status or influence should not be limited to just a few
individuals. (dist_10) |
…High status should be shared among a wide range of members.
(dist_16) |
| Attribute | …High status should be based on a wide variety of attributes.
(attr_6) |
same (attr_6) |
| Attribute | …Everyone should have an opportunity to gain status for the unique
skills they bring. (attr_8) |
same (attr_8) |
| Attribute | …People should recognize a wide range of qualities when determining
who deserves status. (attr_10) |
same (attr_10) |
The three attribute items are identical across studies. The distribution items were reworded after Study 1; the Study 2 and pilot wording matches the six statements in the email to Adam.
Descriptive SEB items (dropped in this analysis),
shown for reference (dist_1R, dist_2R,
dist_5R are reverse-scored; the attribute items are
not):
| Subscale | Item |
|---|---|
| Distribution (R) | …A small number of members receive the most respect and admiration.
(dist_1R) |
| Distribution (R) | …Prestige and influence are concentrated in just a few members.
(dist_2R) |
| Distribution (R) | …High status is concentrated around certain members and not
distributed across all members. (dist_5R) |
| Attribute | …Many different attributes and skills are seen as worthy of respect
and admiration. (attr_3) |
| Attribute | …People gain status for contributing in a wide variety of ways.
(attr_4) |
| Attribute | …People value a broad range of strengths when offering respect.
(attr_5) |
Organizational citizenship behavior toward individuals, OCBI (Lee & Allen, 2002; 8 items; Study 1 and Study 3 pilot; 1 = never, 7 = always). Stem: “Please indicate how often you engage in the following behaviors at work:”
OCBI_1)OCBI_2)OCBI_3)OCBI_4)OCBI_5)OCBI_6)OCBI_7)OCBI_8)Unethical pro-organizational behavior, UPB (Umphress et al., 2010; 6 items; Study 1). Stem: “To what extent do you agree or disagree with each of the following statements?”
UPBs_1)UPBs_2)UPBs_3)UPBs_4)UPBs_5)UPBs_6)Inclusivity (1 item; Study 1, used as a mediator):
“I try to include others and make sure they feel valued in my team.”
(fv_inclusivity)
Status affordance (Choi & Anderson, 2024; 3 items; Study 2). Managers first listed the initials of up to 10 people they directly oversee; three were randomly selected and each was rated in random order: “Earlier you listed the initials of up to 10 people that you directly oversee at work. Now, we will ask a few questions about one of those individuals: [initials]. To what extent do you agree or disagree with each of the following statements about [initials]?”
affordance{1,2,3}_1)affordance{1,2,3}_2)affordance{1,2,3}_3)Dominance and prestige strategies (Study 3 pilot outcomes, and controls in Studies 1 and 2) are listed with the controls below.
Stem for status zero-sum beliefs, need for status, dominance, and prestige: “To what extent do you agree or disagree with each of the following statements?”
Status zero-sum beliefs, SZSB (Andrews-Fearon & Davidai, 2023, Journal of Experimental Psychology: General, 152(2), 389-409, Appendix A; 8 items listed)
SZSB_1)SZSB_2)SZSB_3)SZSB_4)SZSB_5R)SZSB_6R)SZSB_7R;
scored WITHOUT reversal, see note)SZSB_8R)
SZSB_7Ris not reverse-scored (error in the source paper). Appendix A of Andrews-Fearon and Davidai (2023) labels item 7 as “(reverse-coded)”, and the Qualtrics variable name (SZSB_7R) and the earlier Study 1, 2, and 3 scripts follow that label. We treat this as an error in the paper’s appendix and score the item without reversal, for three reasons:
- The item is worded in the zero-sum direction (agreement = more zero-sum thinking), unlike the genuinely reverse-worded items 5, 6, and 8.
- In all three datasets it correlates positively with items 1 to 4 (r of roughly .5 to .7).
- Scoring it as labeled gives SZSB alphas of about .76 (Study 1), .66 (Study 2), and .76 (pilot); scoring it un-reversed gives about .91, .85, and .90, closer to the .86 to .92 the paper reports.
(The paper’s text also says the scale has nine statements, but the appendix lists eight.) Consequence for comparability: SZSB values, and any model that includes SZSB, will differ slightly from the earlier analysis files that reversed item 7. In a Python re-run the prescriptive SEB coefficients barely moved (e.g., Study 1 OCBI b = .353 vs .350), but SZSB became a significant predictor of Study 2 status affordance. To reproduce the old scoring, set
szsb_no_reverse <- character(0).
Need for status (Flynn et al., 2006; 8 items)
need for status_1)need for status_2R)need for status_3)need for status_4)need for status_5)need for status_6)need for status_7R)need for status_8)Social dominance orientation, SDO (Ho et al., 2015; 8 items). Stem: “Show how much you favor or oppose each idea below. You can work quickly; your first feeling is generally best.”
sdo_1)sdo_2)sdo_3R)sdo_4R)sdo_5)sdo_6)sdo_7R)sdo_8R)Dominance and prestige (17 items; adapted by Lange et al., 2019 from Cheng et al., 2010, and used by Andrews-Fearon & Davidai, 2023, Appendix B, to measure willingness to use dominance and prestige strategies to attain higher rank. Item wording in the exports matches Appendix B exactly. The preregistrations cite Cheng et al., 2013 for this measure.)
Dominance (8 items)
dom_1)dom_2)dom_3)dom_4)dom_5R)dom_6)dom_7R)dom_8)Prestige (9 items)
prest_1)prest_2R)prest_3)prest_4R)prest_5)prest_6)prest_7)prest_8)prest_9R)library(tidyverse)
library(qualtRics) # read_survey()
library(lme4)
library(lmerTest) # p-values for lmer; load AFTER lme4
library(psych)
library(car) # VIF
library(lavaan)
library(knitr)
library(kableExtra)
set.seed(2025)
f_study1 <- read_survey("~/Google drive/My Drive/YEAR 2/PROJECTS/DEREK/Status Distribution/Studies/Study 1: Scale/Final Study 1/raw_study1_data_8.4.25.csv")
f_study2 <- read_survey("~/Google drive/My Drive/YEAR 2/PROJECTS/DEREK/Status Distribution/Studies/Study 2: Status Affordance/raw_study2_fulldata_10.8.25.csv")
f_pilot <- read_survey("~/Google drive/My Drive/YEAR 2/PROJECTS/DEREK/Status Distribution/Studies/Study 3: SEB Manipulation/pilot_raw_data_11.11.25.csv")
controls <- c("szsb", "nfs", "sdo", "dom", "prest")
# Qualtrics exports have 2 header rows (question text, ImportId) under the names.
# `drop_extra` removes additional rows, e.g., a researcher test response.
read_qualtrics <- function(path, drop_extra = 0) {
raw <- read.csv(path, na.strings = c("", "NA"), stringsAsFactors = FALSE)
raw[-seq_len(2 + drop_extra), ]
}
# Same exclusion rules as the preregistrations:
# bot screener, attention check, geolocation appearing 3+ times
apply_exclusions <- function(d) {
d %>%
rename_with(make.names) %>% # "need for status_1" -> "need.for.status_1"
filter(attn_bots != "14285733",
suppressWarnings(as.numeric(attn)) == 24) %>%
mutate(geolocation = paste(LocationLatitude, LocationLongitude, sep = "_")) %>%
group_by(geolocation) %>%
mutate(geo_frequency = n()) %>%
ungroup() %>%
filter(geo_frequency < 3)
}
# Row mean of items; any item name ending in "R" is reverse-coded (8 - x),
# except items listed in `no_reverse` (see SZSB_7R below)
scale_mean <- function(d, items, no_reverse = character(0)) {
m <- as.data.frame(lapply(d[, items], as.numeric))
rev_idx <- endsWith(items, "R") & !(items %in% no_reverse)
m[rev_idx] <- 8 - m[rev_idx]
rowMeans(m, na.rm = TRUE)
}
# Item lists (names as they appear after read.csv, i.e., spaces become dots)
items_szsb <- paste0("SZSB_", c(1:4, "5R", "6R", "7R", "8R"))
# SZSB_7R is worded in the zero-sum direction, so it is NOT reverse-scored here.
# Appendix A of Andrews-Fearon & Davidai (2023) mislabels it "(reverse-coded)"; see Measures section.
szsb_no_reverse <- "SZSB_7R"
items_nfs <- paste0("need.for.status_", c("1", "2R", "3", "4", "5", "6", "7R", "8"))
items_sdo <- paste0("sdo_", c("1", "2", "3R", "4R", "5", "6", "7R", "8R"))
items_dom <- paste0("dom_", c("1", "2", "3", "4", "5R", "6", "7R", "8"))
items_prest <- paste0("prest_", c("1", "2R", "3", "4R", "5", "6", "7", "8", "9R"))
items_ocbi <- paste0("OCBI_", 1:8)
items_upb <- paste0("UPBs_", 1:6)
items_presc_s1 <- c("dist_7", "dist_8", "dist_10", "attr_6", "attr_8", "attr_10")
items_presc_s23 <- c("dist_14", "dist_15", "dist_16", "attr_6", "attr_8", "attr_10")
# Prescriptive SEB + the preregistered control scales
score_common <- function(d, presc_items) {
d %>%
rename_with(make.names) %>%
mutate(
presc = scale_mean(., presc_items),
presc_dist = scale_mean(., presc_items[1:3]),
presc_attr = scale_mean(., presc_items[4:6]),
szsb = scale_mean(., items_szsb, no_reverse = szsb_no_reverse),
nfs = scale_mean(., items_nfs),
sdo = scale_mean(., items_sdo),
dom = scale_mean(., items_dom),
prest = scale_mean(., items_prest)
)
}
# Fit the same set of specifications for any DV (lm or random-intercept lmer)
fit_specs <- function(data, dv, mixed = FALSE, ctrl = controls, covar = NULL) {
# ctrl : control variables (drop the DV itself if it is also a control, e.g., dominance)
# covar: extra covariate(s) added to EVERY model (e.g., "cond_high" in the Study 3 pilot)
ctl <- paste(ctrl, collapse = " + ")
add <- if (is.null(covar)) "" else paste0(" + ", paste(covar, collapse = " + "))
rhs <- list(
bivariate = paste0("presc", add),
szsb_only = paste0("szsb", add),
plus_szsb = paste0("presc + szsb", add),
controls_only = paste0(ctl, add),
full = paste0("presc + ", ctl, add)
)
map(rhs, function(r) {
fml <- as.formula(paste(dv, "~", r, if (mixed) "+ (1 | ResponseId)" else ""))
if (mixed) lmer(fml, data = data) else lm(fml, data = data)
})
}
# z-score DV and predictors so coefficients are comparable across studies
zscore <- function(data, vars) {
data %>% mutate(across(all_of(vars), ~ as.numeric(scale(.x))))
}
# Pull one coefficient (works for lm and lmerTest::lmer)
get_coef <- function(model, term = "presc") {
cf <- summary(model)$coefficients
tibble(b = cf[term, "Estimate"],
se = cf[term, "Std. Error"],
p = cf[term, ncol(cf)])
}
# Incremental value of prescriptive SEB over (a) SZSB alone, (b) all controls
incremental <- function(mods, mixed = FALSE) {
a <- anova(mods$szsb_only, mods$plus_szsb)
b <- anova(mods$controls_only, mods$full)
if (!mixed) {
tibble(
comparison = c("SZSB -> SZSB + prescriptive SEB",
"All controls -> + prescriptive SEB"),
delta_R2 = c(summary(mods$plus_szsb)$r.squared - summary(mods$szsb_only)$r.squared,
summary(mods$full)$r.squared - summary(mods$controls_only)$r.squared),
test_stat = c(a$F[2], b$F[2]),
p = c(a$`Pr(>F)`[2], b$`Pr(>F)`[2]),
test = "F"
)
} else {
tibble(
comparison = c("SZSB -> SZSB + prescriptive SEB",
"All controls -> + prescriptive SEB"),
delta_R2 = NA_real_,
test_stat = c(a$Chisq[2], b$Chisq[2]),
p = c(a$`Pr(>Chisq)`[2], b$`Pr(>Chisq)`[2]),
test = "LRT chi-sq"
)
}
}
fmt_p <- function(p) ifelse(p < .001, "<.001", sub("^0", "", sprintf("%.3f", p)))
# ---- Study 1 -----------------------------------------------------------------
# Drop first row (test)
s1 <- f_study1 %>%
slice(-1) %>%
apply_exclusions() %>%
score_common(items_presc_s1) %>%
mutate(ocbi = scale_mean(., items_ocbi),
upb = scale_mean(., items_upb),
inclusivity = as.numeric(fv_inclusivity))
# ---- Study 2 -----------------------------------------------------------------
s2 <- f_study2 %>%
apply_exclusions() %>%
filter(ResponseId != "R_3YbMmG50lMF2JPv") %>% # flagged as bot-like in Study 2 notes
score_common(items_presc_s23) %>%
mutate(across(matches("^affordance[123]_[123]$"), as.numeric))
# Must nominate 3 subordinates (preregistered)
s2 <- s2 %>% filter(!is.na(selected1), !is.na(selected2), !is.na(selected3))
# ---- Study 3 pilot (SEB manipulation check) ------------------------------------
p <- f_pilot %>%
apply_exclusions() %>%
score_common(items_presc_s23) %>%
mutate(ocbi = scale_mean(., items_ocbi),
condition = factor(ifelse(FL_31_DO == "manipulation-lowSEB", "low", "high"),
levels = c("low", "high")), # effect = high - low
cond_high = as.numeric(condition == "high"))
tibble(
Study = c("Study 1", "Study 2 (rated 3 subordinates)", "Study 3 pilot"),
`N raw responses` = c(nrow(f_study1), nrow(f_study2), nrow(f_pilot)),
`N analyzed` = c(nrow(s1), nrow(s2), nrow(p))
) %>% kable() %>% kable_styling(full_width = FALSE)
| Study | N raw responses | N analyzed |
|---|---|---|
| Study 1 | 414 | 390 |
| Study 2 (rated 3 subordinates) | 227 | 157 |
| Study 3 pilot | 105 | 99 |
alpha_of <- function(d, items) round(psych::alpha(d[, items] %>% mutate(across(everything(), as.numeric)))$total$raw_alpha, 2)
tibble(
Study = c("Study 1", "Study 2", "Study 3 pilot"),
`Alpha, 6-item prescriptive` = c(alpha_of(s1, items_presc_s1),
alpha_of(s2, items_presc_s23),
alpha_of(p, items_presc_s23)),
`Alpha, distribution (3)` = c(alpha_of(s1, items_presc_s1[1:3]),
alpha_of(s2, items_presc_s23[1:3]),
alpha_of(p, items_presc_s23[1:3])),
`Alpha, attribute (3)` = c(alpha_of(s1, items_presc_s1[4:6]),
alpha_of(s2, items_presc_s23[4:6]),
alpha_of(p, items_presc_s23[4:6])),
M = c(mean(s1$presc), mean(s2$presc), mean(p$presc)),
SD = c(sd(s1$presc), sd(s2$presc), sd(p$presc))
) %>%
mutate(across(c(M, SD), ~ round(.x, 2))) %>%
kable() %>% kable_styling(full_width = FALSE)
| Study | Alpha, 6-item prescriptive | Alpha, distribution (3) | Alpha, attribute (3) | M | SD |
|---|---|---|---|---|---|
| Study 1 | 0.79 | 0.61 | 0.81 | 5.76 | 0.75 |
| Study 2 | 0.78 | 0.69 | 0.74 | 5.73 | 0.75 |
| Study 3 pilot | 0.87 | 0.79 | 0.82 | 5.70 | 0.94 |
# How much does prescriptive SEB overlap with SZSB and the other controls?
overlap <- bind_rows(
s1 %>% select(presc, all_of(controls)) %>% summarise(across(all_of(controls), ~ cor(presc, .x, use = "pair"))) %>% mutate(Study = "Study 1"),
s2 %>% select(presc, all_of(controls)) %>% summarise(across(all_of(controls), ~ cor(presc, .x, use = "pair"))) %>% mutate(Study = "Study 2"),
p %>% select(presc, all_of(controls)) %>% summarise(across(all_of(controls), ~ cor(presc, .x, use = "pair"))) %>% mutate(Study = "Study 3 pilot")
) %>% select(Study, everything())
overlap %>% mutate(across(where(is.numeric), ~ round(.x, 2))) %>%
kable(caption = "Correlation of prescriptive SEB with each control") %>%
kable_styling(full_width = FALSE)
| Study | szsb | nfs | sdo | dom | prest |
|---|---|---|---|---|---|
| Study 1 | -0.23 | 0.13 | -0.35 | -0.13 | 0.14 |
| Study 2 | -0.23 | 0.13 | -0.42 | -0.33 | 0.16 |
| Study 3 pilot | -0.46 | 0.03 | -0.43 | -0.40 | 0.09 |
redundancy <- function(d, label) {
m <- lm(presc ~ szsb + nfs + sdo + dom + prest, data = d)
r2 <- summary(m)$r.squared
tibble(Study = label, `R2 (presc SEB ~ controls)` = r2, `VIF (presc SEB)` = 1 / (1 - r2))
}
bind_rows(redundancy(s1, "Study 1"), redundancy(s2, "Study 2"), redundancy(p, "Study 3 pilot")) %>%
mutate(across(where(is.numeric), ~ round(.x, 2))) %>%
kable(caption = "High values would mean prescriptive SEB is largely redundant with the controls") %>%
kable_styling(full_width = FALSE)
| Study | R2 (presc SEB ~ controls) | VIF (presc SEB) |
|---|---|---|
| Study 1 | 0.18 | 1.21 |
| Study 2 | 0.26 | 1.35 |
| Study 3 pilot | 0.35 | 1.53 |
s1_ocbi <- fit_specs(s1, "ocbi")
s1_upb <- fit_specs(s1, "upb")
summary(s1_ocbi$full)
##
## Call:
## lm(formula = fml, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.67091 -0.73883 0.03573 0.72075 2.59732
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.899227 0.560790 3.387 0.000781 ***
## presc 0.349552 0.079810 4.380 1.54e-05 ***
## szsb 0.061764 0.048160 1.282 0.200452
## nfs 0.121520 0.084112 1.445 0.149349
## sdo -0.007658 0.042726 -0.179 0.857855
## dom -0.184551 0.059483 -3.103 0.002061 **
## prest 0.117087 0.089796 1.304 0.193044
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.076 on 383 degrees of freedom
## Multiple R-squared: 0.1179, Adjusted R-squared: 0.1041
## F-statistic: 8.531 on 6 and 383 DF, p-value: 1.033e-08
summary(s1_upb$full)
##
## Call:
## lm(formula = fml, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.9460 -0.8824 -0.2573 0.6770 5.0760
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.95722 0.65570 2.985 0.00302 **
## presc -0.18733 0.09332 -2.007 0.04540 *
## szsb 0.04523 0.05631 0.803 0.42237
## nfs -0.07538 0.09835 -0.766 0.44389
## sdo 0.10822 0.04996 2.166 0.03090 *
## dom 0.30426 0.06955 4.375 1.57e-05 ***
## prest 0.15627 0.10499 1.488 0.13748
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.258 on 383 degrees of freedom
## Multiple R-squared: 0.1471, Adjusted R-squared: 0.1337
## F-statistic: 11.01 on 6 and 383 DF, p-value: 2.504e-11
bind_rows(
incremental(s1_ocbi) %>% mutate(Outcome = "OCBI"),
incremental(s1_upb) %>% mutate(Outcome = "UPB")
) %>%
select(Outcome, comparison, delta_R2, test, test_stat, p) %>%
mutate(delta_R2 = round(delta_R2, 3), test_stat = round(test_stat, 2), p = fmt_p(p)) %>%
kable() %>% kable_styling(full_width = FALSE)
| Outcome | comparison | delta_R2 | test | test_stat | p |
|---|---|---|---|---|---|
| OCBI | SZSB -> SZSB + prescriptive SEB | 0.074 | F | 30.94 | <.001 |
| OCBI | All controls -> + prescriptive SEB | 0.044 | F | 19.18 | <.001 |
| UPB | SZSB -> SZSB + prescriptive SEB | 0.022 | F | 8.87 | .003 |
| UPB | All controls -> + prescriptive SEB | 0.009 | F | 4.03 | .045 |
sub_ocbi <- lm(ocbi ~ presc_dist + presc_attr + szsb + nfs + sdo + dom + prest, data = s1)
sub_upb <- lm(upb ~ presc_dist + presc_attr + szsb + nfs + sdo + dom + prest, data = s1)
summary(sub_ocbi)
##
## Call:
## lm(formula = ocbi ~ presc_dist + presc_attr + szsb + nfs + sdo +
## dom + prest, data = s1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.75566 -0.71728 0.04801 0.74087 2.62404
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.92426 0.56170 3.426 0.00068 ***
## presc_dist 0.11749 0.07680 1.530 0.12687
## presc_attr 0.23538 0.08007 2.940 0.00349 **
## szsb 0.05813 0.04835 1.202 0.23007
## nfs 0.11954 0.08417 1.420 0.15635
## sdo -0.01120 0.04293 -0.261 0.79438
## dom -0.18508 0.05950 -3.110 0.00201 **
## prest 0.11119 0.09008 1.234 0.21783
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.076 on 382 degrees of freedom
## Multiple R-squared: 0.1196, Adjusted R-squared: 0.1035
## F-statistic: 7.417 on 7 and 382 DF, p-value: 2.275e-08
summary(sub_upb)
##
## Call:
## lm(formula = upb ~ presc_dist + presc_attr + szsb + nfs + sdo +
## dom + prest, data = s1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.9939 -0.8750 -0.2399 0.6759 5.0586
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.93012 0.65685 2.938 0.0035 **
## presc_dist -0.03164 0.08981 -0.352 0.7248
## presc_attr -0.15929 0.09364 -1.701 0.0897 .
## szsb 0.04917 0.05655 0.869 0.3851
## nfs -0.07323 0.09843 -0.744 0.4573
## sdo 0.11205 0.05020 2.232 0.0262 *
## dom 0.30484 0.06959 4.381 1.53e-05 ***
## prest 0.16265 0.10534 1.544 0.1234
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.258 on 382 degrees of freedom
## Multiple R-squared: 0.1486, Adjusted R-squared: 0.133
## F-statistic: 9.521 on 7 and 382 DF, p-value: 6.505e-11
Your earlier Study 1 work found inclusivity fully mediated the full-scale SEB -> OCBI link. This re-tests that with prescriptive SEB only (bootstrapped indirect effect).
med_model <- '
inclusivity ~ a*presc
ocbi ~ cprime*presc + b*inclusivity
indirect := a*b
total := cprime + a*b
'
fit_med_s1 <- sem(med_model, data = s1, se = "bootstrap", bootstrap = 1000)
summary(fit_med_s1, standardized = TRUE, ci = TRUE)
## lavaan 0.7-2 ended normally after 1 iteration
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 5
##
## Number of observations 390
##
## Model Test User Model:
##
## Test statistic 0.000
## Degrees of freedom 0
##
## Parameter Estimates:
##
## Standard errors Bootstrap
## Number of requested bootstrap draws 1000
## Number of successful bootstrap draws 1000
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## inclusivity ~
## presc (a) 0.455 0.069 6.546 0.000 0.327 0.590
## ocbi ~
## presc (cprm) 0.131 0.072 1.817 0.069 -0.010 0.271
## inclsvt (b) 0.616 0.071 8.691 0.000 0.485 0.769
## Std.lv Std.all
##
## 0.455 0.385
##
## 0.131 0.087
## 0.616 0.482
##
## Variances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .inclusivity 0.671 0.075 8.988 0.000 0.521 0.818
## .ocbi 0.938 0.056 16.781 0.000 0.819 1.040
## Std.lv Std.all
## 0.671 0.852
## 0.938 0.728
##
## Defined Parameters:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## indirect 0.280 0.050 5.607 0.000 0.187 0.385
## total 0.411 0.076 5.389 0.000 0.264 0.563
## Std.lv Std.all
## 0.280 0.186
## 0.411 0.272
Each manager rated 3 subordinates, so ratings are nested within managers and analyzed with random intercepts (as preregistered).
s2_long <- s2 %>%
mutate(
aff_1 = rowMeans(across(c(affordance1_1, affordance1_2, affordance1_3)), na.rm = TRUE),
aff_2 = rowMeans(across(c(affordance2_1, affordance2_2, affordance2_3)), na.rm = TRUE),
aff_3 = rowMeans(across(c(affordance3_1, affordance3_2, affordance3_3)), na.rm = TRUE),
presc_c = presc - mean(presc) # grand-mean centered (manager level)
) %>%
select(ResponseId, presc, presc_c, presc_dist, presc_attr, all_of(controls),
aff_1, aff_2, aff_3) %>%
pivot_longer(starts_with("aff_"), names_to = "slot", values_to = "affordance")
cat("Managers:", n_distinct(s2_long$ResponseId), " | Ratings:", nrow(s2_long))
## Managers: 157 | Ratings: 471
s2_mods <- fit_specs(s2_long, "affordance", mixed = TRUE)
summary(s2_mods$bivariate)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: fml
## Data: data
##
## REML criterion at convergence: 1276.2
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.9932 -0.3320 0.0957 0.4486 2.5029
##
## Random effects:
## Groups Name Variance Std.Dev.
## ResponseId (Intercept) 0.2980 0.5459
## Residual 0.6525 0.8078
## Number of obs: 471, groups: ResponseId, 157
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 3.4166 0.4448 155.0000 7.682 1.66e-12 ***
## presc 0.3892 0.0770 155.0000 5.055 1.20e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr)
## presc -0.992
(Note: in study2_full_analysis_10_9_25.Rmd,
m2 referenced df_long_controls, which is never
created. This uses s2_long instead.)
summary(s2_mods$full)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: fml
## Data: data
##
## REML criterion at convergence: 1279.3
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -4.0416 -0.3525 0.1164 0.4612 2.5472
##
## Random effects:
## Groups Name Variance Std.Dev.
## ResponseId (Intercept) 0.2650 0.5148
## Residual 0.6525 0.8078
## Number of obs: 471, groups: ResponseId, 157
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 3.34713 0.66598 149.99999 5.026 1.41e-06 ***
## presc 0.28811 0.08642 150.00000 3.334 0.00108 **
## szsb 0.13458 0.05875 150.00000 2.291 0.02338 *
## nfs 0.27113 0.09519 150.00000 2.848 0.00501 **
## sdo -0.08261 0.04749 150.00000 -1.739 0.08400 .
## dom -0.10756 0.06356 150.00000 -1.692 0.09268 .
## prest -0.10924 0.10813 149.99999 -1.010 0.31401
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) presc szsb nfs sdo dom
## presc -0.749
## szsb -0.247 0.019
## nfs 0.055 -0.194 0.058
## sdo -0.363 0.297 -0.093 -0.068
## dom -0.128 0.245 -0.365 -0.349 -0.254
## prest -0.378 0.007 0.087 -0.661 0.130 0.025
incremental(s2_mods, mixed = TRUE) %>%
select(comparison, test, test_stat, p) %>%
mutate(test_stat = round(test_stat, 2), p = fmt_p(p)) %>%
kable() %>% kable_styling(full_width = FALSE)
| comparison | test | test_stat | p |
|---|---|---|---|
| SZSB -> SZSB + prescriptive SEB | LRT chi-sq | 26.16 | <.001 |
| All controls -> + prescriptive SEB | LRT chi-sq | 11.22 | <.001 |
lmer(affordance ~ presc_dist + presc_attr + szsb + nfs + sdo + dom + prest + (1 | ResponseId),
data = s2_long) %>% summary()
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: affordance ~ presc_dist + presc_attr + szsb + nfs + sdo + dom +
## prest + (1 | ResponseId)
## Data: s2_long
##
## REML criterion at convergence: 1281.6
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.9798 -0.3538 0.1125 0.4846 2.5620
##
## Random effects:
## Groups Name Variance Std.Dev.
## ResponseId (Intercept) 0.2650 0.5148
## Residual 0.6525 0.8078
## Number of obs: 471, groups: ResponseId, 157
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 3.42017 0.66995 149.00000 5.105 9.95e-07 ***
## presc_dist 0.20701 0.07626 149.00000 2.715 0.00742 **
## presc_attr 0.05602 0.09792 149.00000 0.572 0.56809
## szsb 0.12133 0.06022 149.00000 2.015 0.04575 *
## nfs 0.29396 0.09788 149.00000 3.003 0.00313 **
## sdo -0.07555 0.04801 149.00000 -1.574 0.11770
## dom -0.10680 0.06357 149.00000 -1.680 0.09503 .
## prest -0.10871 0.10813 149.00000 -1.005 0.31639
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) prsc_d prsc_t szsb nfs sdo dom
## presc_dist -0.332
## presc_attr -0.426 -0.489
## szsb -0.263 -0.170 0.205
## nfs 0.078 0.085 -0.292 0.004
## sdo -0.341 0.287 -0.002 -0.122 -0.031
## dom -0.126 0.149 0.098 -0.359 -0.336 -0.250
## prest -0.375 0.008 -0.001 0.084 -0.642 0.130 0.025
pilot_dvs <- c(presc = "Prescriptive SEB", szsb = "SZSB", nfs = "Need for status", ocbi = "OCBI")
pilot_tbl <- map_dfr(names(pilot_dvs), function(v) {
hi <- p[[v]][p$condition == "high"]; lo <- p[[v]][p$condition == "low"]
tt <- t.test(hi, lo)
sp <- sqrt(((length(hi) - 1) * var(hi) + (length(lo) - 1) * var(lo)) / (length(hi) + length(lo) - 2))
tibble(DV = pilot_dvs[[v]],
`M high SEB` = mean(hi), `M low SEB` = mean(lo),
diff = mean(hi) - mean(lo), d = (mean(hi) - mean(lo)) / sp,
t = unname(tt$statistic), p = tt$p.value)
})
pilot_tbl %>%
mutate(across(where(is.numeric), ~ round(.x, 2)), p = fmt_p(p)) %>%
kable(caption = "High vs. low SEB condition (positive = higher in high SEB)") %>%
kable_styling(full_width = FALSE)
| DV | M high SEB | M low SEB | diff | d | t | p |
|---|---|---|---|---|---|---|
| Prescriptive SEB | 6.00 | 5.41 | 0.59 | 0.65 | 3.24 | <.001 |
| SZSB | 2.64 | 3.43 | -0.79 | -0.71 | -3.53 | <.001 |
| Need for status | 4.72 | 4.47 | 0.24 | 0.21 | 1.05 | .290 |
| OCBI | 5.18 | 4.53 | 0.66 | 0.52 | 2.59 | .010 |
The manipulation may move SZSB as well as prescriptive SEB (it did in your pilot notes). That is the same confound raised in the email, so here is the effect on prescriptive SEB with and without SZSB held constant, plus a test of whether prescriptive SEB carries the condition effect on OCBI.
lm(presc ~ condition, data = p) %>% summary()
##
## Call:
## lm(formula = presc ~ condition, data = p)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.2467 -0.4133 0.0867 0.5867 1.5867
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.4133 0.1275 42.442 < 2e-16 ***
## conditionhigh 0.5867 0.1813 3.236 0.00166 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.9019 on 97 degrees of freedom
## Multiple R-squared: 0.09743, Adjusted R-squared: 0.08813
## F-statistic: 10.47 on 1 and 97 DF, p-value: 0.001659
lm(presc ~ condition + szsb + nfs + sdo + dom + prest, data = p) %>% summary()
##
## Call:
## lm(formula = presc ~ condition + szsb + nfs + sdo + dom + prest,
## data = p)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.29881 -0.46964 0.07605 0.46710 1.48230
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.66495 0.49295 13.521 < 2e-16 ***
## conditionhigh 0.55049 0.16494 3.337 0.001221 **
## szsb -0.12377 0.07849 -1.577 0.118231
## nfs 0.17868 0.11997 1.489 0.139794
## sdo -0.22342 0.06085 -3.671 0.000404 ***
## dom -0.22996 0.08367 -2.749 0.007205 **
## prest -0.09894 0.15219 -0.650 0.517230
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7442 on 92 degrees of freedom
## Multiple R-squared: 0.4172, Adjusted R-squared: 0.3792
## F-statistic: 10.98 on 6 and 92 DF, p-value: 3.411e-09
med_pilot <- '
presc ~ a*cond_high
ocbi ~ cprime*cond_high + b*presc
indirect := a*b
total := cprime + a*b
'
fit_med_p <- sem(med_pilot, data = p, se = "bootstrap", bootstrap = 1000)
summary(fit_med_p, standardized = TRUE, ci = TRUE)
## lavaan 0.7-2 ended normally after 1 iteration
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 5
##
## Number of observations 99
##
## Model Test User Model:
##
## Test statistic 0.000
## Degrees of freedom 0
##
## Parameter Estimates:
##
## Standard errors Bootstrap
## Number of requested bootstrap draws 1000
## Number of successful bootstrap draws 995
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## presc ~
## cnd_hgh (a) 0.587 0.183 3.203 0.001 0.213 0.946
## ocbi ~
## cnd_hgh (cprm) 0.478 0.244 1.963 0.050 -0.021 0.973
## presc (b) 0.307 0.146 2.097 0.036 0.014 0.571
## Std.lv Std.all
##
## 0.587 0.312
##
## 0.478 0.184
## 0.307 0.222
##
## Variances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .presc 0.797 0.206 3.872 0.000 0.458 1.253
## .ocbi 1.500 0.209 7.159 0.000 1.079 1.900
## Std.lv Std.all
## 0.797 0.903
## 1.500 0.891
##
## Defined Parameters:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## indirect 0.180 0.105 1.717 0.086 0.004 0.402
## total 0.659 0.252 2.609 0.009 0.123 1.168
## Std.lv Std.all
## 0.180 0.069
## 0.659 0.254
# Parallel mediation: prescriptive SEB and SZSB as competing mediators of condition -> OCBI
med_par <- '
presc ~ a1*cond_high
szsb ~ a2*cond_high
ocbi ~ cprime*cond_high + b1*presc + b2*szsb
presc ~~ szsb
ind_presc := a1*b1
ind_szsb := a2*b2
'
fit_par <- sem(med_par, data = p, se = "bootstrap", bootstrap = 1000)
summary(fit_par, standardized = TRUE, ci = TRUE)
## lavaan 0.7-2 ended normally after 9 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 9
##
## Number of observations 99
##
## Model Test User Model:
##
## Test statistic 0.000
## Degrees of freedom 0
##
## Parameter Estimates:
##
## Standard errors Bootstrap
## Number of requested bootstrap draws 1000
## Number of successful bootstrap draws 989
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## presc ~
## cnd_hgh (a1) 0.587 0.184 3.193 0.001 0.214 0.951
## szsb ~
## cnd_hgh (a2) -0.792 0.223 -3.550 0.000 -1.222 -0.331
## ocbi ~
## cnd_hgh (cprm) 0.506 0.263 1.921 0.055 -0.025 1.036
## presc (b1) 0.334 0.159 2.097 0.036 0.018 0.625
## szsb (b2) 0.054 0.145 0.375 0.707 -0.213 0.356
## Std.lv Std.all
##
## 0.587 0.312
##
## -0.792 -0.337
##
## 0.506 0.195
## 0.334 0.242
## 0.054 0.049
##
## Covariances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .presc ~~
## .szsb -0.389 0.153 -2.550 0.011 -0.726 -0.115
## Std.lv Std.all
##
## -0.389 -0.394
##
## Variances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .presc 0.797 0.205 3.887 0.000 0.462 1.251
## .szsb 1.224 0.139 8.800 0.000 0.952 1.492
## .ocbi 1.497 0.205 7.291 0.000 1.055 1.864
## Std.lv Std.all
## 0.797 0.903
## 1.224 0.886
## 1.497 0.889
##
## Defined Parameters:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## ind_presc 0.196 0.117 1.672 0.095 0.010 0.459
## ind_szsb -0.043 0.123 -0.351 0.726 -0.348 0.148
## Std.lv Std.all
## 0.196 0.075
## -0.043 -0.017
The Study 3 pilot measured willingness to use dominance and prestige strategies (the 17-item scale from Andrews-Fearon & Davidai, 2023, Appendix B) after the manipulation. These are the same outcomes Andrews-Fearon and Davidai used, where manipulating zero-sum beliefs raised dominance but not prestige. The questions here, raised in the email to Adam, are: (1) does the SEB manipulation change dominance and/or prestige, (2) does the effect survive accounting for SZSB, and (3) does SZSB (or prescriptive SEB) carry the effect? Note that SEB and SZSB in this dataset are the participant’s own scores (measured after the essay), not ratings of a manager’s beliefs.
dp_dvs <- c(dom = "Dominance (Cheng)", prest = "Prestige (Cheng)", nfs = "Need for status")
map_dfr(names(dp_dvs), function(v) {
hi <- p[[v]][p$condition == "high"]; lo <- p[[v]][p$condition == "low"]
tt <- t.test(hi, lo)
sp <- sqrt(((length(hi) - 1) * var(hi) + (length(lo) - 1) * var(lo)) / (length(hi) + length(lo) - 2))
tibble(DV = dp_dvs[[v]], `M high SEB` = mean(hi), `M low SEB` = mean(lo),
diff = mean(hi) - mean(lo), d = (mean(hi) - mean(lo)) / sp,
t = unname(tt$statistic), p = tt$p.value)
}) %>%
mutate(across(where(is.numeric), ~ round(.x, 2)), p = fmt_p(p)) %>%
kable(caption = "High vs. low SEB condition (positive = higher in high SEB)") %>%
kable_styling(full_width = FALSE)
| DV | M high SEB | M low SEB | diff | d | t | p |
|---|---|---|---|---|---|---|
| Dominance (Cheng) | 3.00 | 2.91 | 0.10 | 0.08 | 0.41 | .680 |
| Prestige (Cheng) | 4.78 | 4.52 | 0.26 | 0.29 | 1.44 | .150 |
| Need for status | 4.72 | 4.47 | 0.24 | 0.21 | 1.05 | .290 |
p %>% select(Dominance = dom, Prestige = prest, `Prescriptive SEB` = presc, SZSB = szsb) %>%
cor(use = "pairwise.complete.obs") %>% round(2) %>%
kable(caption = "Correlations in the pilot (both conditions pooled)") %>%
kable_styling(full_width = FALSE)
| Dominance | Prestige | Prescriptive SEB | SZSB | |
|---|---|---|---|---|
| Dominance | 1.00 | 0.30 | -0.40 | 0.38 |
| Prestige | 0.30 | 1.00 | 0.09 | -0.14 |
| Prescriptive SEB | -0.40 | 0.09 | 1.00 | -0.46 |
| SZSB | 0.38 | -0.14 | -0.46 | 1.00 |
Andrews-Fearon and Davidai test whether a manipulation moves
dominance more than prestige with a mixed model (strategy type
as a within-person factor, random intercept for participant). The same
test here: a significant condition:strategy term means the
essay affected the two strategies differently.
p_strat <- p %>%
select(ResponseId, condition, dom, prest) %>%
pivot_longer(c(dom, prest), names_to = "strategy", values_to = "willingness") %>%
mutate(strategy = factor(strategy, levels = c("prest", "dom"), labels = c("Prestige", "Dominance")))
m_strat <- lmer(willingness ~ condition * strategy + (1 | ResponseId), data = p_strat)
summary(m_strat)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: willingness ~ condition * strategy + (1 | ResponseId)
## Data: p_strat
##
## REML criterion at convergence: 570.3
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.87837 -0.62362 -0.03265 0.59113 3.06041
##
## Random effects:
## Groups Name Variance Std.Dev.
## ResponseId (Intercept) 0.3101 0.5569
## Residual 0.7575 0.8703
## Number of obs: 198, groups: ResponseId, 99
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 4.5222 0.1461 178.9047 30.948 < 2e-16
## conditionhigh 0.2624 0.2077 178.9047 1.263 0.208
## strategyDominance -1.6147 0.1741 97.0000 -9.276 4.9e-15
## conditionhigh:strategyDominance -0.1673 0.2474 97.0000 -0.676 0.501
##
## (Intercept) ***
## conditionhigh
## strategyDominance ***
## conditionhigh:strategyDominance
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) cndtnh strtgD
## conditinhgh -0.704
## strtgyDmnnc -0.596 0.419
## cndtnhgh:sD 0.419 -0.596 -0.704
dom_total <- lm(dom ~ condition, data = p)
dom_szsb <- lm(dom ~ condition + szsb, data = p)
dom_presc <- lm(dom ~ condition + presc, data = p)
dom_both <- lm(dom ~ condition + presc + szsb, data = p)
map_dfr(list(`Condition only` = dom_total, `+ SZSB` = dom_szsb,
`+ prescriptive SEB` = dom_presc, `+ both` = dom_both),
function(m) {
cf <- summary(m)$coefficients
tibble(`Condition (high - low)` = cf["conditionhigh", 1],
SE = cf["conditionhigh", 2], p = cf["conditionhigh", 4],
`SZSB b` = if ("szsb" %in% rownames(cf)) cf["szsb", 1] else NA,
`Prescriptive SEB b` = if ("presc" %in% rownames(cf)) cf["presc", 1] else NA,
R2 = summary(m)$r.squared)
}, .id = "Model") %>%
mutate(across(where(is.numeric), ~ round(.x, 2)), p = fmt_p(p)) %>%
kable(caption = "Dependent variable: dominance") %>% kable_styling(full_width = FALSE)
| Model | Condition (high - low) | SE | p | SZSB b | Prescriptive SEB b | R2 |
|---|---|---|---|---|---|---|
| Condition only | 0.10 | 0.23 | .680 | NA | NA | 0.00 |
|
0.44 | 0.22 | .050 | 0.43 | NA | 0.18 |
|
0.42 | 0.22 | .060 | NA | -0.55 | 0.19 |
|
0.57 | 0.22 | .010 | 0.30 | -0.40 | 0.26 |
prest_total <- lm(prest ~ condition, data = p)
prest_both <- lm(prest ~ condition + presc + szsb, data = p)
summary(prest_total)
##
## Call:
## lm(formula = prest ~ condition, data = p)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.8957 -0.7090 -0.0068 0.6599 2.2556
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.5222 0.1283 35.256 <2e-16 ***
## conditionhigh 0.2624 0.1823 1.439 0.153
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.907 on 97 degrees of freedom
## Multiple R-squared: 0.0209, Adjusted R-squared: 0.01081
## F-statistic: 2.071 on 1 and 97 DF, p-value: 0.1534
summary(prest_both)
##
## Call:
## lm(formula = prest ~ condition + presc + szsb, data = p)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.87487 -0.71011 0.00277 0.61070 2.54045
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.70631 0.79012 5.956 4.34e-08 ***
## conditionhigh 0.19166 0.19820 0.967 0.336
## presc 0.01531 0.11165 0.137 0.891
## szsb -0.07790 0.09010 -0.865 0.389
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.9116 on 95 degrees of freedom
## Multiple R-squared: 0.03128, Adjusted R-squared: 0.0006847
## F-statistic: 1.022 on 3 and 95 DF, p-value: 0.3863
Both mediators are lowered/raised by the essay, and both correlate with dominance in the expected direction. Bootstrapped indirect effects test which one carries any condition effect. If the direct effect has the opposite sign of the indirect effects, this is inconsistent mediation (suppression), so a near-zero total effect does not mean nothing is happening.
med_dom <- '
presc ~ a1*cond_high
szsb ~ a2*cond_high
dom ~ cprime*cond_high + b1*presc + b2*szsb
presc ~~ szsb
ind_presc := a1*b1
ind_szsb := a2*b2
total := cprime + a1*b1 + a2*b2
'
fit_med_dom <- sem(med_dom, data = p, se = "bootstrap", bootstrap = 1000)
summary(fit_med_dom, standardized = TRUE, ci = TRUE)
## lavaan 0.7-2 ended normally after 9 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 9
##
## Number of observations 99
##
## Model Test User Model:
##
## Test statistic 0.000
## Degrees of freedom 0
##
## Parameter Estimates:
##
## Standard errors Bootstrap
## Number of requested bootstrap draws 1000
## Number of successful bootstrap draws 994
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## presc ~
## cnd_hgh (a1) 0.587 0.184 3.186 0.001 0.213 0.950
## szsb ~
## cnd_hgh (a2) -0.792 0.223 -3.548 0.000 -1.222 -0.331
## dom ~
## cnd_hgh (cprm) 0.569 0.214 2.662 0.008 0.136 0.979
## presc (b1) -0.399 0.146 -2.740 0.006 -0.656 -0.082
## szsb (b2) 0.303 0.099 3.051 0.002 0.117 0.515
## Std.lv Std.all
##
## 0.587 0.312
##
## -0.792 -0.337
##
## 0.569 0.251
## -0.399 -0.330
## 0.303 0.314
##
## Covariances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .presc ~~
## .szsb -0.389 0.152 -2.554 0.011 -0.726 -0.115
## Std.lv Std.all
##
## -0.389 -0.394
##
## Variances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .presc 0.797 0.205 3.882 0.000 0.462 1.253
## .szsb 1.224 0.139 8.825 0.000 0.951 1.491
## .dom 0.953 0.121 7.894 0.000 0.689 1.164
## Std.lv Std.all
## 0.797 0.903
## 1.224 0.886
## 0.953 0.740
##
## Defined Parameters:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## ind_presc -0.234 0.129 -1.807 0.071 -0.525 -0.026
## ind_szsb -0.240 0.103 -2.331 0.020 -0.471 -0.078
## total 0.095 0.230 0.413 0.680 -0.372 0.538
## Std.lv Std.all
## -0.234 -0.103
## -0.240 -0.106
## 0.095 0.042
med_prest <- sub("dom ~", "prest ~", med_dom, fixed = TRUE)
fit_med_prest <- sem(med_prest, data = p, se = "bootstrap", bootstrap = 1000)
summary(fit_med_prest, standardized = TRUE, ci = TRUE)
## lavaan 0.7-2 ended normally after 9 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 9
##
## Number of observations 99
##
## Model Test User Model:
##
## Test statistic 0.000
## Degrees of freedom 0
##
## Parameter Estimates:
##
## Standard errors Bootstrap
## Number of requested bootstrap draws 1000
## Number of successful bootstrap draws 990
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## presc ~
## cnd_hgh (a1) 0.587 0.184 3.184 0.001 0.214 0.951
## szsb ~
## cnd_hgh (a2) -0.792 0.224 -3.545 0.000 -1.222 -0.331
## prest ~
## cnd_hgh (cprm) 0.192 0.188 1.018 0.308 -0.184 0.571
## presc (b1) 0.015 0.184 0.083 0.934 -0.275 0.415
## szsb (b2) -0.078 0.096 -0.808 0.419 -0.286 0.101
## Std.lv Std.all
##
## 0.587 0.312
##
## -0.792 -0.337
##
## 0.192 0.106
## 0.015 0.016
## -0.078 -0.101
##
## Covariances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .presc ~~
## .szsb -0.389 0.153 -2.545 0.011 -0.726 -0.114
## Std.lv Std.all
##
## -0.389 -0.394
##
## Variances:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## .presc 0.797 0.206 3.863 0.000 0.457 1.253
## .szsb 1.224 0.138 8.842 0.000 0.952 1.492
## .prest 0.797 0.105 7.584 0.000 0.554 0.957
## Std.lv Std.all
## 0.797 0.903
## 1.224 0.886
## 0.797 0.969
##
## Defined Parameters:
## Estimate Std.Err z-value P(>|z|) ci.lower ci.upper
## ind_presc 0.009 0.113 0.079 0.937 -0.218 0.241
## ind_szsb 0.062 0.083 0.739 0.460 -0.075 0.255
## total 0.262 0.176 1.487 0.137 -0.086 0.609
## Std.lv Std.all
## 0.009 0.005
## 0.062 0.034
## 0.262 0.145
Standardized (z-scored) coefficients for prescriptive SEB from every model, so all studies are on the same metric. The key comparison is how much the coefficient shrinks going from bivariate to + SZSB to full controls.
Study 3 pilot rows: the pilot manipulated SEB, so prescriptive SEB
there is partly condition-driven. To keep these rows comparable to the
correlational studies, condition (cond_high) is
included as a covariate in every pilot model, so the
coefficient reflects the within-condition association. When the outcome
is dominance or prestige, that scale is dropped from the control set (it
cannot be its own control).
z1 <- zscore(s1, c("ocbi", "upb", "presc", controls))
z2 <- zscore(s2_long, c("affordance", "presc", controls))
z3 <- zscore(p, c("ocbi", "dom", "prest", "presc", controls))
zm <- list(
`Study 1: OCBI` = fit_specs(z1, "ocbi"),
`Study 1: UPB` = fit_specs(z1, "upb"),
`Study 2: Status affordance` = fit_specs(z2, "affordance", mixed = TRUE),
`Study 3 pilot: OCBI` = fit_specs(z3, "ocbi", covar = "cond_high"),
`Study 3 pilot: Dominance` = fit_specs(z3, "dom", ctrl = setdiff(controls, "dom"), covar = "cond_high"),
`Study 3 pilot: Prestige` = fit_specs(z3, "prest", ctrl = setdiff(controls, "prest"), covar = "cond_high")
)
spec_labels <- c(bivariate = "Prescriptive SEB alone",
plus_szsb = "Plus SZSB",
full = "Plus all controls")
cross <- imap_dfr(zm, function(mods, label) {
map_dfr(names(spec_labels), function(s) {
get_coef(mods[[s]]) %>% mutate(Outcome = label, Specification = spec_labels[[s]])
})
}) %>%
mutate(lo = b - 1.96 * se, hi = b + 1.96 * se,
Specification = factor(Specification, levels = spec_labels),
Outcome = factor(Outcome, levels = names(zm)))
cross %>%
transmute(Outcome, Specification,
`std. b` = round(b, 2), SE = round(se, 2),
`95% CI` = sprintf("[%.2f, %.2f]", lo, hi), p = fmt_p(p)) %>%
kable() %>% kable_styling(full_width = FALSE) %>%
collapse_rows(columns = 1, valign = "top")
| Outcome | Specification | std. b | SE | 95% CI | p |
|---|---|---|---|---|---|
| Study 1: OCBI | Prescriptive SEB alone | 0.27 | 0.05 | [0.18, 0.37] | <.001 |
| Plus SZSB | 0.28 | 0.05 | [0.18, 0.38] | <.001 | |
| Plus all controls | 0.23 | 0.05 | [0.13, 0.34] | <.001 | |
| Study 1: UPB | Prescriptive SEB alone | -0.18 | 0.05 | [-0.28, -0.08] | <.001 |
| Plus SZSB | -0.15 | 0.05 | [-0.25, -0.05] | .003 | |
| Plus all controls | -0.10 | 0.05 | [-0.21, -0.00] | .045 | |
| Study 2: Status affordance | Prescriptive SEB alone | 0.29 | 0.06 | [0.17, 0.40] | <.001 |
| Plus SZSB | 0.31 | 0.06 | [0.19, 0.42] | <.001 | |
| Plus all controls | 0.21 | 0.06 | [0.09, 0.34] | .001 | |
| Study 3 pilot: OCBI | Prescriptive SEB alone | 0.22 | 0.10 | [0.02, 0.42] | .031 |
| Plus SZSB | 0.24 | 0.11 | [0.02, 0.46] | .032 | |
| Plus all controls | 0.28 | 0.13 | [0.03, 0.53] | .032 | |
| Study 3 pilot: Dominance | Prescriptive SEB alone | -0.45 | 0.10 | [-0.64, -0.26] | <.001 |
| Plus SZSB | -0.33 | 0.10 | [-0.53, -0.13] | .002 | |
| Plus all controls | -0.27 | 0.10 | [-0.47, -0.08] | .007 | |
| Study 3 pilot: Prestige | Prescriptive SEB alone | 0.06 | 0.11 | [-0.15, 0.26] | .604 |
| Plus SZSB | 0.02 | 0.12 | [-0.21, 0.24] | .891 | |
| Plus all controls | -0.05 | 0.07 | [-0.19, 0.10] | .517 |
ggplot(cross, aes(x = b, y = Outcome, color = Specification)) +
geom_vline(xintercept = 0, linetype = "dashed", color = "grey50") +
geom_pointrange(aes(xmin = lo, xmax = hi), position = position_dodge(width = 0.6)) +
scale_y_discrete(limits = rev) +
labs(x = "Standardized coefficient for prescriptive SEB (95% CI)", y = NULL,
title = "Prescriptive SEB effects across studies") +
theme_minimal(base_size = 13) +
theme(legend.position = "bottom", plot.title = element_text(face = "bold"))
# Incremental value over SZSB / controls, all outcomes in one table
bind_rows(
incremental(fit_specs(s1, "ocbi")) %>% mutate(Outcome = "Study 1: OCBI"),
incremental(fit_specs(s1, "upb")) %>% mutate(Outcome = "Study 1: UPB"),
incremental(s2_mods, mixed = TRUE) %>% mutate(Outcome = "Study 2: Status affordance"),
incremental(fit_specs(p, "ocbi", covar = "cond_high")) %>% mutate(Outcome = "Study 3 pilot: OCBI"),
incremental(fit_specs(p, "dom", ctrl = setdiff(controls, "dom"), covar = "cond_high")) %>%
mutate(Outcome = "Study 3 pilot: Dominance"),
incremental(fit_specs(p, "prest", ctrl = setdiff(controls, "prest"), covar = "cond_high")) %>%
mutate(Outcome = "Study 3 pilot: Prestige")
) %>%
transmute(Outcome, comparison, test,
delta_R2 = ifelse(is.na(delta_R2), "-", sprintf("%.3f", delta_R2)),
stat = round(test_stat, 2), p = fmt_p(p)) %>%
kable() %>% kable_styling(full_width = FALSE) %>%
collapse_rows(columns = 1, valign = "top")
| Outcome | comparison | test | delta_R2 | stat | p |
|---|---|---|---|---|---|
| Study 1: OCBI | SZSB -> SZSB + prescriptive SEB | F | 0.074 | 30.94 | <.001 |
| All controls -> + prescriptive SEB | F | 0.044 | 19.18 | <.001 | |
| Study 1: UPB | SZSB -> SZSB + prescriptive SEB | F | 0.022 | 8.87 | .003 |
| All controls -> + prescriptive SEB | F | 0.009 | 4.03 | .045 | |
| Study 2: Status affordance | SZSB -> SZSB + prescriptive SEB | LRT chi-sq |
|
26.16 | <.001 |
| All controls -> + prescriptive SEB | LRT chi-sq |
|
11.22 | <.001 | |
| Study 3 pilot: OCBI | SZSB -> SZSB + prescriptive SEB | F | 0.045 | 4.76 | .032 |
| All controls -> + prescriptive SEB | F | 0.045 | 4.76 | .032 | |
| Study 3 pilot: Dominance | SZSB -> SZSB + prescriptive SEB | F | 0.083 | 10.67 | .002 |
| All controls -> + prescriptive SEB | F | 0.047 | 7.55 | .007 | |
| Study 3 pilot: Prestige | SZSB -> SZSB + prescriptive SEB | F | 0.000 | 0.02 | .891 |
| All controls -> + prescriptive SEB | F | 0.001 | 0.42 | .517 |
OCBI is the one outcome measured in both Study 1 and the pilot.
Variables are z-scored within study; study_pilot shifts the
intercept and presc:study_pilot tests whether the
prescriptive SEB slope differs in the pilot. Condition is included as a
covariate (coded 0 for all Study 1 participants).
vars_pool <- c("ocbi", "presc", controls)
pooled <- bind_rows(
s1 %>% transmute(study = "Study 1", cond_high = 0, ocbi, presc, szsb, nfs, sdo, dom, prest),
p %>% transmute(study = "Study 3 pilot", cond_high, ocbi, presc, szsb, nfs, sdo, dom, prest)
) %>%
group_by(study) %>%
mutate(across(all_of(vars_pool), ~ as.numeric(scale(.x)))) %>%
ungroup() %>%
mutate(study = factor(study, levels = c("Study 1", "Study 3 pilot")))
m_pool <- lm(ocbi ~ presc * study + szsb + nfs + sdo + dom + prest + cond_high, data = pooled)
summary(m_pool)
##
## Call:
## lm(formula = ocbi ~ presc * study + szsb + nfs + sdo + dom +
## prest + cond_high, data = pooled)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.74334 -0.65360 0.03586 0.64733 2.27157
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.100e-16 4.793e-02 0.000 1.00000
## presc 2.423e-01 5.200e-02 4.659 4.13e-06 ***
## studyStudy 3 pilot -1.990e-01 1.466e-01 -1.357 0.17544
## szsb 6.713e-02 4.720e-02 1.422 0.15560
## nfs 1.111e-01 7.115e-02 1.561 0.11920
## sdo 1.102e-02 4.989e-02 0.221 0.82521
## dom -1.638e-01 5.270e-02 -3.109 0.00199 **
## prest 9.536e-02 6.889e-02 1.384 0.16694
## cond_high 4.020e-01 2.036e-01 1.975 0.04888 *
## presc:studyStudy 3 pilot -6.693e-02 1.125e-01 -0.595 0.55207
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.9466 on 479 degrees of freedom
## Multiple R-squared: 0.1187, Adjusted R-squared: 0.1022
## F-statistic: 7.17 on 9 and 479 DF, p-value: 8.704e-10
sessionInfo()
## R version 4.6.0 (2026-04-24)
## Platform: aarch64-apple-darwin23
## Running under: macOS Ventura 13.3
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## time zone: America/New_York
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] kableExtra_1.4.0 knitr_1.51 lavaan_0.7-2 car_3.1-5
## [5] carData_3.0-6 psych_2.6.5 lmerTest_3.2-1 lme4_2.0-1
## [9] Matrix_1.7-5 qualtRics_3.3.0 lubridate_1.9.5 forcats_1.0.1
## [13] stringr_1.6.0 dplyr_1.2.1 purrr_1.2.2 readr_2.2.0
## [17] tidyr_1.3.2 tibble_3.3.1 ggplot2_4.0.3 tidyverse_2.0.0
##
## loaded via a namespace (and not attached):
## [1] sjlabelled_1.2.0 tidyselect_1.2.1 viridisLite_0.4.3
## [4] farver_2.1.2 S7_0.2.2 fastmap_1.2.0
## [7] digest_0.6.39 timechange_0.4.0 lifecycle_1.0.5
## [10] magrittr_2.0.5 compiler_4.6.0 rlang_1.2.0
## [13] sass_0.4.10 tools_4.6.0 yaml_2.3.12
## [16] labeling_0.4.3 bit_4.6.0 mnormt_2.1.2
## [19] xml2_1.5.2 RColorBrewer_1.1-3 abind_1.4-8
## [22] withr_3.0.2 numDeriv_2016.8-1.1 grid_4.6.0
## [25] stats4_4.6.0 scales_1.4.0 MASS_7.3-66
## [28] insight_1.5.1 cli_3.6.6 rmarkdown_2.31
## [31] crayon_1.5.3 reformulas_0.4.4 generics_0.1.4
## [34] otel_0.2.0 rstudioapi_0.19.0 tzdb_0.5.0
## [37] minqa_1.2.8 cachem_1.1.0 splines_4.6.0
## [40] parallel_4.6.0 vctrs_0.7.3 boot_1.3-32
## [43] jsonlite_2.0.0 hms_1.1.4 bit64_4.8.2
## [46] Formula_1.2-5 systemfonts_1.3.2 jquerylib_0.1.4
## [49] glue_1.8.1 nloptr_2.2.1 stringi_1.8.7
## [52] gtable_0.3.6 quadprog_1.5-8 pillar_1.11.1
## [55] htmltools_0.5.9 R6_2.6.1 textshaping_1.0.5
## [58] Rdpack_2.6.6 vroom_1.7.1 evaluate_1.0.5
## [61] pbivnorm_0.6.0 lattice_0.22-9 rbibutils_2.4.1
## [64] bslib_0.11.0 Rcpp_1.1.1-1.1 svglite_2.2.2
## [67] nlme_3.1-169 xfun_0.58 pkgconfig_2.0.3