This tutorial uses data and reproduces a subset of analyses reported in the following manuscript:
In these analyses, we test whether self and social relevance are causally related to sharing intentions in a preregistered experiment. Self and social relevance were experimentally manipulated by having participants explicitly reflect on the self or social relevance of messages.
Participants were randomly assigned to either the self (n = 200) or social (n = 197) condition. We used a mixed design in which all participants saw a set of 5 messages in the control condition and a set of 5 messages either in the self condition or the social condition. Therefore, relationships between the experimental condition (self or social) and the control condition were assessed within-person, whereas the difference between experimental conditions was assessed between-person. We manipulated self relevance by asking participants to write about why the article matters to them personally (self condition), and social relevance by asking them to write about why the article matters to people they know (social condition). In the control condition, participants did not reflect on relevance and instead were asked to write what the article is about. Messages consisted of a news headline and brief abstract from the New York Times about general health or climate change—two important societal issues that could benefit from individual and collective action.
if (!require(pacman)) {
install.packages('pacman')
}::p_load(devtools, report, tidyverse, lmerTest, usmap, knitr, kableExtra, reactable, performance, wesanderson, install = TRUE)
pacman::install_github("hadley/emo") devtools
= c("#3B9AB2", "#EBCC2A", "#F21A00")
palette_map = c("#ee9b00", "#bb3e03", "#005f73")
palette_condition
= theme_minimal() +
plot_aes theme(legend.position = "top",
legend.text = element_text(size = 12),
text = element_text(size = 16, family = "Futura Medium"),
axis.text = element_text(color = "black"),
axis.line = element_line(colour = "black"),
axis.ticks.y = element_blank())
# MLM results table function
= function(model_data, reference = "control") {
table_model %>%
model_data ::tidy(conf.int = TRUE) %>%
broom.mixedfilter(effect == "fixed") %>%
rename("SE" = std.error,
"t" = statistic,
"p" = p.value) %>%
select(-group, -effect) %>%
mutate_at(vars(-contains("term"), -contains("p.value")), round, 2) %>%
mutate(term = gsub("article_cond", "", term),
term = gsub("\\(Intercept\\)", !!reference, term),
term = gsub("sharing_typemsg_sharing_narrow", "sharing type", term),
term = gsub("msg_rel_self_between", "self-relevance", term),
term = gsub("msg_rel_social_between", "social relevance", term),
term = gsub(":", " x ", term),
p = ifelse(p < .001, "< .001",
ifelse(p == 1, "1.000", gsub("0.(.*)", ".\\1", sprintf("%.3f", p)))),
`b [95% CI]` = sprintf("%.2f [%0.2f, %.2f]", estimate, conf.low, conf.high)) %>%
select(term, `b [95% CI]`, df, t, p) %>%
kable() %>%
::kable_styling()
kableExtra
}
# source raincloud plot function
source("https://gist.githubusercontent.com/benmarwick/2a1bb0133ff568cbe28d/raw/fb53bd97121f7f9ce947837ef1a4c65a73bffb3f/geom_flat_violin.R")
= read.csv("data/study6_clean_long.csv", stringsAsFactors = FALSE)
data_raw = read.csv("data/study6_demo.csv", stringsAsFactors = FALSE) demo
Data transformations
Exclusions
# get condition information
= data_raw %>%
cond_order filter(grepl("cond_order", survey_name)) %>%
select(SID, value) %>%
mutate(article_cond = strsplit(value, "\\|")) %>%
unnest(article_cond) %>%
select(-value) %>%
bind_cols(., data.frame(item = rep(1:10, length(unique(data_raw$SID))))) %>%
mutate(item = as.character(item),
article_cond = gsub("other", "social", article_cond))
# isolate message ratings and merge with condition information
= data_raw %>%
messages filter(grepl("sharing|relevance_self|relevance_social", survey_name)) %>%
extract(item, "item", "([0-9]+)_.*") %>%
mutate(value = as.numeric(value),
survey_name = gsub("relevance", "rel", survey_name),
survey_name = sprintf("msg_%s", survey_name),
cond = gsub("other", "social", cond)) %>%
left_join(., cond_order)
# prepare dataframe for modeling; keep sharing type and article condition long, but pivot the relevance variables wide
= messages %>%
messages_mod group_by(survey_name, SID) %>%
spread(survey_name, value) %>%
gather(sharing_type, msg_share, contains("sharing")) %>%
mutate(group = cond) %>%
select(group, SID, item, article_cond, sharing_type, msg_share, contains("rel_"))
# summarize the demographic information
= demo %>%
demo_summary mutate(value = ifelse(value == "Would rather not say", "Prefer not to say", value),
value = ifelse(is.na(value), "Not reported", value)) %>%
group_by(item, value) %>%
summarize(n = n()) %>%
ungroup() %>%
filter(!item %in% c("gender_4_TEXT", "race_self")) %>%
rename(" " = item)
For this tutorial, these are made up demographics to illustrate how to summarize and present different characteristics
%>%
messages select(cond, SID) %>%
unique() %>%
group_by(cond) %>%
summarize(n = n()) %>%
::reactable(striped = TRUE) reactable
= demo %>%
states filter(grepl("state", item)) %>%
spread(item, value) %>%
group_by(state) %>%
summarize(n = n())
%>%
states ::plot_usmap(data = ., values = "n", color = "grey50") +
usmapscale_fill_gradient2(low = palette_map[1], mid = palette_map[2], midpoint = max(states$n) / 2, high = palette_map[3],
name = "", na.value = NA, limits = c(0, max(states$n)), breaks = seq(0, max(states$n), 10)) +
theme(text = element_text(size = 12, family = "Futura Medium"),
legend.position = "right")
%>%
demo filter(item == "age") %>%
mutate(value = as.numeric(value)) %>%
summarize(`age range` = sprintf("%s - %s", min(value, na.rm = TRUE), max(value, na.rm = TRUE)),
`mean age` = round(mean(value, na.rm = TRUE), 0),
`sd age` = round(sd(value, na.rm = TRUE), 0)) %>%
::reactable(striped = TRUE) reactable
%>%
demo filter(item == "age") %>%
mutate(value = as.numeric(value)) %>%
ggplot(aes(value)) +
geom_density(fill = "#3B9AB2", color = NA) +
labs(x = "") +
+
plot_aes theme(legend.position = "right")
%>%
demo_summary filter(` ` == "gender") %>%
mutate(total = sum(n),
percent = sprintf("%.0f%s", (n / total) * 100, "%")) %>%
select(-total, -` `) %>%
bind_rows(data.frame(value = c("Non-binary / third gender", "Prefer to self-describe"), n = rep(0, 2), percent = rep("0%", 2))) %>%
arrange(value) %>%
rename("gender" = value) %>%
::reactable(striped = TRUE) reactable
%>%
demo_summary filter(` ` == "gender") %>%
mutate(total = sum(n),
percent = (n / total) * 100) %>%
select(-total, -` `) %>%
bind_rows(data.frame(value = c("Non-binary / third gender", "Prefer to self-describe"), n = rep(0, 2), percent = rep(0, 2))) %>%
ggplot(aes("", percent, fill = reorder(value, percent))) +
geom_bar(stat = "identity") +
coord_flip() +
scale_fill_manual(name = "", values = wesanderson::wes_palette("Zissou1", n = 5, type = "continuous")) +
labs(x = "") +
+
plot_aes theme(legend.position = "right")
= demo_summary %>%
hispanic_latinx filter(` ` == "Hispanic or Latinx") %>%
mutate(total = sum(n),
percent = sprintf("%.1f%s", (n / total) * 100, "%")) %>%
select(-total) %>%
spread(value, percent) %>%
select(-No, - ` `) %>%
rename("percent" = Yes) %>%
mutate(`race / ethnicity` = "Hispanic or Latinx")
%>%
demo_summary filter(` ` == "race") %>%
filter(!value %in% c("Hispanic", "Latino")) %>% #counted already in the hispanic_latinx item
mutate(total = sum(n),
percent = sprintf("%.1f%s", (n / total) * 100, "%"),
value = ifelse(is.na(value), "Not reported", value)) %>%
select(value, n, percent) %>%
bind_rows(data.frame(value = c("American Indian or Alaskan Native", "Native Hawaiian or Other Pacific Islander"), n = rep(0, 2), percent = rep("0%", 2))) %>%
rename("race & ethnicity" = value) %>%
bind_rows(., hispanic_latinx) %>%
arrange(`race / ethnicity`) %>%
::reactable(striped = TRUE) reactable
%>%
demo_summary filter(` ` == "race") %>%
filter(!value %in% c("Hispanic", "Latino")) %>% #counted already in the hispanic_latinx item
mutate(total = sum(n),
percent = (n / total) * 100,
value = ifelse(is.na(value), "Not reported", value)) %>%
select(value, n, percent) %>%
bind_rows(data.frame(value = c("American Indian or Alaskan Native", "Native Hawaiian or Other Pacific Islander"), n = rep(0, 2), percent = rep(0, 2))) %>%
ggplot(aes("", percent, fill = reorder(value, percent))) +
geom_bar(stat = "identity") +
coord_flip() +
scale_fill_manual(name = "", values = wesanderson::wes_palette("Zissou1", n = 7, type = "continuous")) +
labs(x = "") +
+
plot_aes theme(legend.position = "right")
%>%
demo_summary filter(` ` == "household income") %>%
group_by(value) %>%
summarize(n = sum(n)) %>%
mutate(total = sum(n),
percent = sprintf("%.1f%s", (n / total) * 100, "%"),
value = ifelse(is.na(value), "Not reported", value),
value = factor(value, levels = c("Less than $5,000", "$5,000 through $11,999", "$12,000 through $15,999", "$16,000 through $24,999",
"$25,000 through $34,999", "$35,000 through $49,999", "$50,000 through $74,999", "$75,000 through $99,999",
"$100,000 and greater", "Not reported"))) %>%
arrange(value) %>%
select(value, n, percent) %>%
rename("household income" = value) %>%
mutate_if(is.character, funs(ifelse(is.na(.), "—", .))) %>%
::reactable(striped = TRUE) reactable
%>%
demo_summary filter(` ` == "household income") %>%
group_by(value) %>%
summarize(n = sum(n)) %>%
mutate(total = sum(n),
percent = (n / total) * 100,
value = ifelse(is.na(value), "Not reported", value),
value = factor(value, levels = c("Less than $5,000", "$5,000 through $11,999", "$12,000 through $15,999", "$16,000 through $24,999",
"$25,000 through $34,999", "$35,000 through $49,999", "$50,000 through $74,999", "$75,000 through $99,999",
"$100,000 and greater", "Not reported"))) %>%
arrange(value) %>%
select(value, n, percent) %>%
ggplot(aes(value, percent, fill = value)) +
geom_histogram(stat = "identity") +
geom_text(aes(label = sprintf("%.1f%s", percent, "%")), nudge_y = 2) +
coord_flip() +
scale_fill_manual(name = "", values = wesanderson::wes_palette("Zissou1", n = 9, type = "continuous")) +
labs(x = "") +
+
plot_aes theme(legend.position = "none")
%>%
demo_summary filter(` ` == "highest degree completed") %>%
group_by(value) %>%
summarize(n = sum(n)) %>%
mutate(total = sum(n),
percent = sprintf("%.1f%s", (n / total) * 100, "%")) %>%
bind_rows(data.frame(value = "Less than high school", n = 0, percent = "0%")) %>%
mutate(value = factor(value, levels = c("Less than high school", "High school graduate (diploma)", "High school graduate (GED)",
"Some college (1-4 years, no degree)", "Associate's degree (including occupational or academic degrees)",
"Bachelor's degree (BA, BS, etc)", "Master's degree (MA, MS, MENG, MSW, etc)",
"Professional school degree (MD, DDC, JD, etc)", "Doctorate degree (PhD, EdD, etc)"))) %>%
arrange(value) %>%
select(value, n, percent) %>%
rename("highest degree completed" = value) %>%
mutate_if(is.character, funs(ifelse(is.na(.), "—", .))) %>%
::reactable(striped = TRUE) reactable
%>%
demo_summary filter(` ` == "highest degree completed") %>%
group_by(value) %>%
summarize(n = sum(n)) %>%
mutate(total = sum(n),
percent = (n / total) * 100) %>%
bind_rows(data.frame(value = "Less than high school", n = 0, percent = 0)) %>%
mutate(value = factor(value, levels = c("Less than high school", "High school graduate (diploma)", "High school graduate (GED)",
"Some college (1-4 years, no degree)", "Associate's degree (including occupational or academic degrees)",
"Bachelor's degree (BA, BS, etc)", "Master's degree (MA, MS, MENG, MSW, etc)",
"Professional school degree (MD, DDC, JD, etc)", "Doctorate degree (PhD, EdD, etc)"))) %>%
arrange(value) %>%
select(value, n, percent) %>%
ggplot(aes(value, percent, fill = value)) +
geom_histogram(stat = "identity") +
geom_text(aes(label = sprintf("%.1f%s", percent, "%")), nudge_y = 3) +
coord_flip() +
scale_fill_manual(name = "", values = wesanderson::wes_palette("Zissou1", n = 8, type = "continuous")) +
labs(x = "") +
+
plot_aes theme(legend.position = "none")
Only a single rating (or 0.01%) is missing
%>%
messages filter(is.na(value)) %>%
group_by(SID, survey_name) %>%
summarize(n = n()) %>%
arrange(-n)
There do not appear to be obvious outliers
%>%
messages ggplot(aes(survey_name, value, fill = survey_name)) +
geom_flat_violin(position = position_nudge(x = .1, y = 0), color = FALSE) +
geom_point(aes(color = survey_name), position = position_jitter(width = .05), size = .1, alpha = .1) +
geom_boxplot(width = .1, outlier.shape = NA, fill = NA) +
scale_fill_manual(values = wesanderson::wes_palette("Zissou1", n = 4, type = "continuous")) +
scale_color_manual(values = wesanderson::wes_palette("Zissou1", n = 4, type = "continuous")) +
labs(x = "") +
coord_flip() +
+
plot_aes theme(legend.position = "none")
Self-relevance (1 = strongly disagree, 100 = strongly agree)
This message is relevant to me.
Social relevance (1 = strongly disagree, 100 = strongly agree)
This message is relevant to people I know.
Broadcast sharing intention (1 = strongly disagree, 100 = strongly agree)
I would share this article by posting on social media (on Facebook, Twitter, etc).
Narrowcast sharing intention (1 = strongly disagree, 100 = strongly agree)
I would share this article directly with someone I know (via email, direct message, etc).
# means
= messages %>%
means group_by(survey_name) %>%
filter(!is.na(value)) %>%
summarize(N = n(),
`M (SD)` = sprintf("%s (%s)", round(mean(value, na.rm = TRUE), 2), round(sd(value, na.rm = TRUE), 2))) %>%
mutate(`scale range` = "0-100") %>%
select(`scale range`, everything()) %>%
rename("variable" = survey_name) %>%
mutate(variable = recode(variable, "msg_rel_social" = "social relevance",
"msg_rel_self" = "self-relevance",
"msg_sharing_broad" = "broadcast sharing intention",
"msg_sharing_narrow" = "narrowcast sharing intention"))
# repeated measures correlations
= messages %>%
corrs spread(survey_name, value) %>%
nest() %>%
mutate(self_social = map(data, ~ rmcorr::rmcorr(as.factor(SID), msg_rel_self, msg_rel_social, .)),
self_broad = map(data, ~ rmcorr::rmcorr(as.factor(SID), msg_rel_self, msg_sharing_broad, .)),
social_broad = map(data, ~ rmcorr::rmcorr(as.factor(SID), msg_rel_social, msg_sharing_broad, .)),
broad_narrow = map(data, ~ rmcorr::rmcorr(as.factor(SID), msg_sharing_broad, msg_sharing_narrow, .)),
self_narrow = map(data, ~ rmcorr::rmcorr(as.factor(SID), msg_rel_self, msg_sharing_narrow, .)),
social_narrow = map(data, ~ rmcorr::rmcorr(as.factor(SID), msg_rel_social, msg_sharing_narrow, .))) %>%
select(-data) %>%
gather(test, model) %>%
group_by(test) %>%
filter(!is.null(model)) %>%
mutate(r = sprintf("%.2f [%.2f, %.2f]", model[[1]][[1]], model[[1]][[4]][1], model[[1]][[4]][2]),
df = model[[1]][[2]],
p = round(model[[1]][[3]], 3),
p = ifelse(p == 0, "< .001", as.character(p))) %>%
ungroup() %>%
select(test, r) %>%
extract(test, c("var1", "var2"), "(.*)_(.*)") %>%
spread(var2, r) %>%
select(var1, everything()) %>%
group_by(var1) %>%
mutate_if(is.character, ~ ifelse(is.na(.), "--", .)) %>%
mutate(var1 = ifelse(var1 == "social", "social relevance",
ifelse(var1 == "self", "self-relevance",
ifelse(var1 == "broad", "broadcast sharing intention", "narrowcast sharing intention")))) %>%
rename("variable" = var1,
"broadcast sharing intention" = broad,
"narrowcast sharing intention" = narrow,
"social relevance" = social) %>%
select(variable, `narrowcast sharing intention`, `broadcast sharing intention`, `social relevance`)
# merge descriptors and correlations to generate manuscript table
%>%
means left_join(., corrs)%>%
mutate_if(is.character, ~ ifelse(is.na(.), "--", .)) %>%
::reactable(striped = TRUE) reactable
The following plots visualize the raw data and do not take into account repeated measures within-participant
%>%
messages ggplot(aes(survey_name, value, color = article_cond)) +
stat_summary(fun.data = "mean_cl_boot", geom = "pointrange", size = 1) +
scale_color_manual(values = palette_condition) +
plot_aes
%>%
messages ggplot(aes(survey_name, value, color = article_cond)) +
geom_jitter(alpha = .05) +
stat_summary(fun.data = "mean_cl_boot", geom = "pointrange") +
scale_color_manual(values = palette_condition) +
plot_aes
%>%
messages spread(survey_name, value) %>%
gather(sharing, share_value, msg_sharing_broad, msg_sharing_narrow) %>%
gather(relevance, rel_value, msg_rel_self, msg_rel_social) %>%
ggplot(aes(rel_value, share_value, color = article_cond, fill = article_cond)) +
geom_point(alpha = .05) +
geom_smooth(method = "lm") +
facet_grid(sharing ~ relevance) +
scale_color_manual(values = palette_condition) +
scale_fill_manual(values = palette_condition) +
plot_aes
The following hypotheses are preregistered. The preregistration is available on OSF.
H1: Messages in the experimental conditions will evoke higher broad- and narrowcast sharing intentions than messages in the control condition.
Results
✅ These data are consistent with the hypothesis that thinking about the self-relevance of a message increases its perceived self-relevance
= lmer(msg_rel_self ~ 1 + article_cond + (1 + article_cond | SID),
mod_h1 data = messages_mod,
control = lmerControl(optimizer = "bobyqa"))
::ggpredict(mod_h1, c("article_cond")) %>%
ggeffectsdata.frame() %>%
mutate(x = factor(x, levels = c("self", "control", "social"))) %>%
ggplot(aes(x = x, y = predicted, fill = x)) +
geom_bar(stat = "identity", position = position_dodge(.9)) +
geom_errorbar(aes(ymin = conf.low, ymax = conf.high), position = position_dodge(.9), width = 0, size = 1) +
scale_fill_manual(name = "", values = palette_condition) +
labs(x = "", y = "mean predicted rating\n") +
+
plot_aes theme(legend.position = "none")
table_model(mod_h1)
term | b [95% CI] | df | t | p |
---|---|---|---|---|
control | 52.85 [50.55, 55.15] | 396.00 | 45.13 | < .001 |
self | 12.41 [10.01, 14.81] | 225.44 | 10.19 | < .001 |
social | 5.12 [2.96, 7.28] | 212.74 | 4.67 | < .001 |
summary(mod_h1)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: msg_rel_self ~ 1 + article_cond + (1 + article_cond | SID)
## Data: messages_mod
## Control: lmerControl(optimizer = "bobyqa")
##
## REML criterion at convergence: 74144.5
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.3486 -0.5966 0.0850 0.5823 3.3875
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## SID (Intercept) 489.1 22.12
## article_condself 222.4 14.91 -0.44
## article_condsocial 145.9 12.08 -0.34 0.06
## Residual 552.3 23.50
## Number of obs: 7940, groups: SID, 397
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 52.849 1.171 396.000 45.132 < 0.0000000000000002 ***
## article_condself 12.408 1.218 225.445 10.189 < 0.0000000000000002 ***
## article_condsocial 5.118 1.096 212.745 4.671 0.00000532 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) artcl_cndsl
## artcl_cndsl -0.352
## artcl_cndsc -0.287 0.101
Check model assumptions using the {performance}
package
::check_model(mod_h1) performance
H1: Messages in the social condition will be rated as more socially relevant than messages in the control condition.
Results
✅ These data are consistent with the hypothesis that thinking about the social relevance of a message increases its perceived social relevance
= lmer(msg_rel_social ~ 1 + article_cond + (1 + article_cond | SID),
mod_h2 data = messages_mod,
control = lmerControl(optimizer = "bobyqa"))
::ggpredict(mod_h2, c("article_cond")) %>%
ggeffectsdata.frame() %>%
mutate(x = factor(x, levels = c("self", "control", "social"))) %>%
ggplot(aes(x = x, y = predicted, fill = x)) +
geom_bar(stat = "identity", position = position_dodge(.9)) +
geom_errorbar(aes(ymin = conf.low, ymax = conf.high), position = position_dodge(.9), width = 0, size = 1) +
scale_fill_manual(name = "", values = palette_condition) +
labs(x = "", y = "mean predicted rating\n") +
+
plot_aes theme(legend.position = "none")
table_model(mod_h2)
term | b [95% CI] | df | t | p |
---|---|---|---|---|
control | 58.44 [56.18, 60.69] | 396.00 | 50.88 | < .001 |
self | 8.66 [6.61, 10.71] | 228.12 | 8.32 | < .001 |
social | 8.90 [6.81, 11.00] | 220.99 | 8.38 | < .001 |
summary(mod_h2)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: msg_rel_social ~ 1 + article_cond + (1 + article_cond | SID)
## Data: messages_mod
## Control: lmerControl(optimizer = "bobyqa")
##
## REML criterion at convergence: 72201.7
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.8896 -0.4633 0.0913 0.5490 3.4932
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## SID (Intercept) 481.0 21.93
## article_condself 158.1 12.57 -0.46
## article_condsocial 167.1 12.93 -0.47 0.27
## Residual 426.8 20.66
## Number of obs: 7940, groups: SID, 397
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 58.436 1.149 396.000 50.88 < 0.0000000000000002 ***
## article_condself 8.656 1.040 228.124 8.32 0.00000000000000804 ***
## article_condsocial 8.904 1.062 220.989 8.38 0.00000000000000616 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) artcl_cndsl
## artcl_cndsl -0.356
## artcl_cndsc -0.365 0.130
Check model assumptions using the {performance}
package
::check_model(mod_h2) performance
H3: Messages in the experimental conditions will evoke higher broad- and narrowcast sharing intentions than messages in the control condition.
H4: We will test whether the experimental conditions differ in their effects on broadcast and narrowcast sharing intentions. We expect that the social relevance manipulation will have a stronger effect on narrowcast than broadcast sharing intentions, whereas the self-relevance manipulation will have a stronger effect on broadcast than narrowcast sharing intentions.
Results
✅ These data are consistent with the hypothesis that the self and social conditions increase sharing intentions
✅ These data are consistent with the hypothesis that the social condition more strongly increases narrowcast than broadcast sharing intentions
❌ These data are inconsistent with the hypothesis that the self condition more strongly increases broadcast than narrowcast sharing intentions
= lmer(msg_share ~ 1 + article_cond*sharing_type + (1 + sharing_type | SID),
mod_h3_h4 data = messages_mod,
control = lmerControl(optimizer = "bobyqa"))
::ggpredict(mod_h3_h4, c("article_cond", "sharing_type")) %>%
ggeffectsdata.frame() %>%
mutate(x = factor(x, levels = c("self", "control", "social")),
group = ifelse(group == "msg_sharing_broad", "broadcast sharing", "narrowcast sharing")) %>%
ggplot(aes(x = x, y = predicted, color = x)) +
geom_pointrange(aes(ymin = conf.low, ymax = conf.high, alpha = group), position = position_dodge(.5), size = 2) +
coord_flip() +
scale_color_manual(name = "", values = palette_condition, guide = "none") +
scale_alpha_manual(name = "", values = c(1, .5)) +
labs(x = "", y = "\nmean predicted sharing intention rating") +
scale_y_continuous(limits = c(40, 60)) +
+
plot_aes theme(legend.position = "top")
table_model(mod_h3_h4)
term | b [95% CI] | df | t | p |
---|---|---|---|---|
control | 45.04 [42.04, 48.04] | 431.34 | 29.54 | < .001 |
self | 5.23 [3.57, 6.89] | 7536.07 | 6.16 | < .001 |
social | 3.37 [1.70, 5.05] | 7535.21 | 3.95 | < .001 |
sharing type | 0.16 [-1.50, 1.82] | 743.49 | 0.19 | .850 |
self x sharing type | 2.08 [-0.18, 4.35] | 6961.88 | 1.81 | .070 |
social x sharing type | 3.53 [1.25, 5.80] | 6926.66 | 3.04 | < .001 |
summary(mod_h3_h4)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: msg_share ~ 1 + article_cond * sharing_type + (1 + sharing_type |
## SID)
## Data: messages_mod
## Control: lmerControl(optimizer = "bobyqa")
##
## REML criterion at convergence: 71638.9
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -4.0176 -0.4887 -0.0143 0.4899 4.3824
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## SID (Intercept) 845.7 29.08
## sharing_typemsg_sharing_narrow 128.1 11.32 -0.44
## Residual 386.8 19.67
## Number of obs: 7939, groups: SID, 397
##
## Fixed effects:
## Estimate Std. Error
## (Intercept) 45.0383 1.5249
## article_condself 5.2305 0.8489
## article_condsocial 3.3742 0.8546
## sharing_typemsg_sharing_narrow 0.1607 0.8440
## article_condself:sharing_typemsg_sharing_narrow 2.0847 1.1538
## article_condsocial:sharing_typemsg_sharing_narrow 3.5251 1.1609
## df t value
## (Intercept) 431.3357 29.536
## article_condself 7536.0749 6.162
## article_condsocial 7535.2126 3.948
## sharing_typemsg_sharing_narrow 743.4852 0.190
## article_condself:sharing_typemsg_sharing_narrow 6961.8849 1.807
## article_condsocial:sharing_typemsg_sharing_narrow 6926.6611 3.036
## Pr(>|t|)
## (Intercept) < 0.0000000000000002 ***
## article_condself 0.000000000756 ***
## article_condsocial 0.000079372297 ***
## sharing_typemsg_sharing_narrow 0.8490
## article_condself:sharing_typemsg_sharing_narrow 0.0708 .
## article_condsocial:sharing_typemsg_sharing_narrow 0.0024 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) artcl_cndsl artcl_cndsc shr___ artcl_cndsl:___
## artcl_cndsl -0.151
## artcl_cndsc -0.150 0.075
## shrng_typ__ -0.433 0.272 0.270
## artcl_cndsl:___ 0.111 -0.686 -0.106 -0.400
## artcl_cndsc:___ 0.110 -0.106 -0.685 -0.398 0.164
Check model assumptions using the {performance}
package
::check_model(mod_h3_h4) performance
We will also explore the degree to which the effects of the experimental manipulations are specific to their relevance target. Does the self condition increase self-relevance more strongly than the social condition?
Results
✅ These data are consistent with the hypothesis that the self condition increases self-relevance more strongly than the social condition
= lmer(msg_rel_self ~ 1 + article_cond + (1 + article_cond | SID),
mod_e1 data = filter(messages_mod, !article_cond == "control"),
control = lmerControl(optimizer = "bobyqa"))
::ggpredict(mod_e1, c("article_cond")) %>%
ggeffectsdata.frame() %>%
mutate(x = factor(x, levels = c("self", "social"))) %>%
ggplot(aes(x = x, y = predicted, fill = x)) +
geom_bar(stat = "identity", position = position_dodge(.9)) +
geom_errorbar(aes(ymin = conf.low, ymax = conf.high), position = position_dodge(.9), width = 0, size = 1) +
scale_fill_manual(name = "", values = c(palette_condition[1], palette_condition[3])) +
labs(x = "", y = "mean predicted rating\n") +
+
plot_aes theme(legend.position = "none")
table_model(mod_e1, reference = "self")
term | b [95% CI] | df | t | p |
---|---|---|---|---|
self | 64.93 [61.87, 67.99] | 199.00 | 41.83 | < .001 |
social | -6.57 [-10.96, -2.19] | 394.43 | -2.95 | < .001 |
summary(mod_e1)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: msg_rel_self ~ 1 + article_cond + (1 + article_cond | SID)
## Data: filter(messages_mod, !article_cond == "control")
## Control: lmerControl(optimizer = "bobyqa")
##
## REML criterion at convergence: 36758.3
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.5494 -0.5313 0.1243 0.5669 3.2953
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## SID (Intercept) 433.0 20.81
## article_condsocial 287.2 16.95 -0.38
## Residual 488.8 22.11
## Number of obs: 3970, groups: SID, 397
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 64.927 1.552 199.000 41.827 < 0.0000000000000002 ***
## article_condsocial -6.573 2.229 394.428 -2.948 0.00339 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr)
## artcl_cndsc -0.696
## optimizer (bobyqa) convergence code: 0 (OK)
## unable to evaluate scaled gradient
## Model failed to converge: degenerate Hessian with 1 negative eigenvalues
Check model assumptions using the {performance}
package
::check_model(mod_e1) performance
We will also explore the degree to which the effects of the experimental manipulations are specific to their relevance target. Does the social condition increase social relevance more strongly than the self condition?
Results
❌ These data are inconsistent with the hypothesis that the social condition increases social relevance more strongly than the self condition
= lmer(msg_rel_social ~ 1 + article_cond + (1 + article_cond | SID),
mod_e2 data = filter(messages_mod, !article_cond == "control"),
control = lmerControl(optimizer = "bobyqa"))
::ggpredict(mod_e2, c("article_cond")) %>%
ggeffectsdata.frame() %>%
mutate(x = factor(x, levels = c("self", "social"))) %>%
ggplot(aes(x = x, y = predicted, fill = x)) +
geom_bar(stat = "identity", position = position_dodge(.9)) +
geom_errorbar(aes(ymin = conf.low, ymax = conf.high), position = position_dodge(.9), width = 0, size = 1) +
scale_fill_manual(name = "", values = c(palette_condition[1], palette_condition[3])) +
labs(x = "", y = "mean predicted rating\n") +
+
plot_aes theme(legend.position = "none")
table_model(mod_e2, reference = "self")
term | b [95% CI] | df | t | p |
---|---|---|---|---|
self | 66.47 [63.51, 69.44] | 199.00 | 44.18 | < .001 |
social | 1.48 [-2.60, 5.55] | 394.16 | 0.71 | .480 |
summary(mod_e2)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: msg_rel_social ~ 1 + article_cond + (1 + article_cond | SID)
## Data: filter(messages_mod, !article_cond == "control")
## Control: lmerControl(optimizer = "bobyqa")
##
## REML criterion at convergence: 35666.2
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -4.1246 -0.4177 0.1240 0.5330 3.8295
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## SID (Intercept) 416.1 20.40
## article_condsocial 246.5 15.70 -0.47
## Residual 365.9 19.13
## Number of obs: 3970, groups: SID, 397
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 66.474 1.504 199.000 44.184 <0.0000000000000002 ***
## article_condsocial 1.479 2.073 394.161 0.714 0.476
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr)
## artcl_cndsc -0.726
Check model assumptions using the {performance}
package
::check_model(mod_e2) performance
::cite_packages() report
## - Douglas Bates and Martin Maechler (2021). Matrix: Sparse and Dense Matrix Classes and Methods. R package version 1.3-4. https://CRAN.R-project.org/package=Matrix
## - Douglas Bates, Martin Maechler, Ben Bolker, Steve Walker (2015). Fitting Linear Mixed-Effects Models Using lme4. Journal of Statistical Software, 67(1), 1-48. doi:10.18637/jss.v067.i01.
## - Greg Lin (2020). reactable: Interactive Data Tables Based on 'React Table'. R package version 0.2.3. https://CRAN.R-project.org/package=reactable
## - H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2016.
## - Hadley Wickham (2019). stringr: Simple, Consistent Wrappers for Common String Operations. R package version 1.4.0. https://CRAN.R-project.org/package=stringr
## - Hadley Wickham (2021). forcats: Tools for Working with Categorical Variables (Factors). R package version 0.5.1. https://CRAN.R-project.org/package=forcats
## - Hadley Wickham and Maximilian Girlich (2022). tidyr: Tidy Messy Data. R package version 1.2.0. https://CRAN.R-project.org/package=tidyr
## - Hadley Wickham, Jennifer Bryan and Malcolm Barrett (2021). usethis: Automate Package and Project Setup. R package version 2.1.5. https://CRAN.R-project.org/package=usethis
## - Hadley Wickham, Jim Hester and Jennifer Bryan (2022). readr: Read Rectangular Text Data. R package version 2.1.2. https://CRAN.R-project.org/package=readr
## - Hadley Wickham, Jim Hester, Winston Chang and Jennifer Bryan (2021). devtools: Tools to Make Developing R Packages Easier. R package version 2.4.3. https://CRAN.R-project.org/package=devtools
## - Hadley Wickham, Romain François, Lionel Henry and Kirill Müller (2022). dplyr: A Grammar of Data Manipulation. R package version 1.0.8. https://CRAN.R-project.org/package=dplyr
## - Hao Zhu (2021). kableExtra: Construct Complex Table with 'kable' and Pipe Syntax. R package version 1.3.4. https://CRAN.R-project.org/package=kableExtra
## - Karthik Ram and Hadley Wickham (2018). wesanderson: A Wes Anderson Palette Generator. R package version 0.3.6. https://CRAN.R-project.org/package=wesanderson
## - Kirill Müller and Hadley Wickham (2021). tibble: Simple Data Frames. R package version 3.1.6. https://CRAN.R-project.org/package=tibble
## - Kuznetsova A, Brockhoff PB, Christensen RHB (2017). "lmerTest Package:Tests in Linear Mixed Effects Models." _Journal of StatisticalSoftware_, *82*(13), 1-26. doi: 10.18637/jss.v082.i13 (URL:https://doi.org/10.18637/jss.v082.i13).
## - Lionel Henry and Hadley Wickham (2020). purrr: Functional Programming Tools. R package version 0.3.4. https://CRAN.R-project.org/package=purrr
## - Lüdecke et al., (2021). performance: An R Package for Assessment, Comparison and Testing of Statistical Models. Journal of Open Source Software, 6(60), 3139. https://doi.org/10.21105/joss.03139
## - Makowski, D., Ben-Shachar, M.S., Patil, I. & Lüdecke, D. (2020). Automated Results Reporting as a Practical Tool to Improve Reproducibility and Methodological Best Practices Adoption. CRAN. Available from https://github.com/easystats/report. doi: .
## - Paolo Di Lorenzo (2021). usmap: US Maps Including Alaska and Hawaii. R package version 0.5.2. https://CRAN.R-project.org/package=usmap
## - R Core Team (2021). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. URL https://www.R-project.org/.
## - Rinker, T. W. & Kurkiewicz, D. (2017). pacman: Package Management for R. version 0.5.0. Buffalo, New York. http://github.com/trinker/pacman
## - Wickham et al., (2019). Welcome to the tidyverse. Journal of Open Source Software, 4(43), 1686, https://doi.org/10.21105/joss.01686
## - Yihui Xie (2021). knitr: A General-Purpose Package for Dynamic Report Generation in R. R package version 1.37.