lm(y ~ x + w + x:w)
Einführung
Moderatoranalysen können mittels Strukturgleichungsmodell (SEM, späterer Post) berechnet werden, wobei allgemein von Kausalmodellen bzw. der Kausalanalyse die Rede ist (obgleich damit keine Kausalität nachgewiesen wird). Gleiches gilt für Mediatoranalysen (späterer Post). Da für Mediatoren mehrere Regressionen notwendig sind, werden insbesondere sie mittels SEM analysiert, wohingegen für Moderatoren eine simple multiple Regression ausreichend ist. Entsprechend widmen wir uns zunächst dieser.
Strenggenommen sind Moderatoren bereits aus der Varianzanalyse (ANOVA) bekannt, wobei dort von Interaktion(seffekten) die Rede ist – sprich: zwei (oder mehr) unabhängige Variablen (UV) haben nicht ausschließlich einen Haupeffekt, sondern interagieren miteinander. Im hießigen Kontext der Regression wird bei zwei UVs einer dieser als Moderator festgelegt, dies ist also kein Ergebnis der Analyse. Im Vergleich zur ANOVA kann dieser Moderator zwar (poly-)chotom sein (dummycodierte Regression), dies stellt jedoch keine notwendige Voraussetzung dar, d.h. auch kontinuierliche Variablen können als Moderatoren dienen1. Für die übrige(n) UV gilt dasselbe, d.h. auch sie können metrisch oder (poly-)chotom sein. Sind sowohl Moderator als auch UV polychotom, so ist die multiple Regression äquivalent zur ANOVA. Das einfachse Design einer \(2\times2\) ANOVA bedeutet auf die Regression übertragen, dass eine der unabhängigen Variablen die Rolle des (dichotomen) Moderators einnimmt, die andere die der (dichotomen) UV. Die Rollen lassen sich in diesem Fall und auch für alle anderen symmetrischen Designs tauschen, sofern inhaltlich logisch und sinnvoll.
Formale Schreibweise und Syntax der MMR
Moderierte Multiple Regression
Das Hinzufügen einer Moderatorvariablen \(w\) bedeutet für die Regression, dass eine weitere Variable (Interaktionsterm \(x\times w\)) zur Regression hinzugefügt werden muss. Dieser Produktterm erhält ebenso einen eigenen Steigungskoeffinienten2, wobei der neue Produktterm die Interpretation der bisherigen Steigungskoeffizienten verändert. Dies wird in der formalen Schreibweise (für den einfachsten Fall einer UV und eines Moderators) deutlich:
\[\hat{y} = b_0 + xb_1 + wb_2 + xwb_3\]
Die formale Schreibweise gleicht der in R verwendeten (bereits bekannten) Syntax:
Dabei meint x:w
ausschließlich den Interaktionsterm. Diese lange Schreibweise lässt sich zu lm(y~x*w)
verkürzen, ist innhaltlich jedoch gleichbedeutetend. Nur für diesen Post verwenden wir explizit die lange Schreibweise, um auf den “neuen” Produktterm hinzuweisen.
Konzeptionell wird das Moderationsmodell wie in folgendem Diagramm dargestellt:
Registered S3 methods overwritten by 'broom':
method from
tidy.glht jtools
tidy.summary.glht jtools
Pakete
Übungsaufgaben
Aufgabe 1
Daten
Teilaufgabe a
df_dstr %>% column_to_rownames(var = "id") %>%
group_by(frame) %>%
summarise_all(list(M = mean, SD = sd))
frame | M | SD | M | SD | M | SD |
---|---|---|---|---|---|---|
Natural causes | 4.56 | 1.36 | 2.80 | 0.85 | 3.34 | 2.04 |
Climate change | 4.65 | 1.27 | 2.94 | 1.01 | 3.42 | 2.03 |
Teilaufgabe b
Die Versuchspersonen erhalten einen Bericht über eine Hungersnot, in dem als Ursache der Klimawandel oder eine andere nicht näher erläuterte natürliche Ursache aufgeführt ist. Es wird angenommen, dass dieses Framing (frame
) einen Einfluss darauf hat, wie stark Menschen helfen bzw. hier nicht helfen, gemessen als Akzeptanz Hilfe zu unterlassen (justify
). Vor der eigenltichen MMR betrachten wir dieses einfache Modell:
term | b | SE | t | p |
---|---|---|---|---|
(Intercept) | 2.80 | 0.09 | 31.62 | <.001 |
frameClimate change | 0.13 | 0.13 | 1.05 | .3 |
Die Rahmenbedingungen leisten hier keinen signifikanten Einfluss zur Erklärung der abhängigen Variablen, das Modell erklärt nur 0.5% an Varianz. Wir nehmen nun also an, dass dieser Zusammenhang nur deswegen nicht gezeigt werden kann, weil die individuelle Vorstellung, ob der Klimawandel überhaupt real ist, diesen Zusammenhang moderiert. Wird der Klimawandel als ebenso natürlich wie eine tatsächlich natürliche Dürre eingeschätzt, so gibt es keinen Unterschied zwischen den beiden Bedingungen (beide natürlich). Nur wenn überhaupt diskriminiert wird, kann ein Einfluss vorhanden sein. skeptic
wird numerischer Index dafür ermittelt, ob der Klimawandel als real eingeschätzt wird.
term | b | SE | t | p |
---|---|---|---|---|
(Intercept) | 2.45 | 0.15 | 16.45 | <.001 |
frameClimate change | -0.56 | 0.22 | -2.58 | .011 |
skeptic | 0.11 | 0.04 | 2.76 | .006 |
frameClimate change:skeptic | 0.20 | 0.06 | 3.64 | <.001 |
Dieses Modell klärt knapp 25% an Varianz auf.
Teilaufgabe c
Alle Steigungskoeffizienten sind signifikant von null verschieden (alle \(p<.05\)) und somit theoretisch bedeutsam, wieso für alle eine theoretische Interpretation in Anlehnung an Hayes (2022, S. 255) betrachtet wird:
\(b_1=-0.562\) kann für jene Gruppe interpretiert werden, für die die Skepsis gegenüber dem Klimawandel null Punkte beträgt (d. h. \(w=0\)). Für genau diese Gruppe ist \(b_1\) der (geschätzte) Unterschied in der Stärke der rechtfertigten unterlassenen Hilfe zwischen der Gruppe, der gesagt wurde, der Klimawandel sei für die Dürre verantwortlich vs. jener Gruppe, der dies nicht gesagt wurde.
Der Koeffizient ist negativ, was bedeutet, dass diejenigen, denen gesagt wurde, der Klimawandel sei für die Dürre verantwortlich (X = 1
), eine schwächere Rechtfertigung für die unterlassene Hilfleistung aufweisen, als all jene, denen nichts über den Klimawandel als Ursache gesagt wurde (X = 0
). Obwohl diese Interpretation mathematisch korrekt ist, ist sie inhaltlich unsinnig. Das Skala auf der die Skepsis gegenüber dem Klimawandel gemessen wurde, kann nur Werte zwischen 1 und 9 annehmen. Die Schätzung des Effekts der Manipulation (Rahmen) ist abhängig von dem Wert der Skepsis und kann nur interpretiert werden, wenn die Skepsis null wäre, was aber unmöglich ist, da es diese Personen gar nicht geben kann, auf die dieser Effekt zutreffen würde, weil die Skala dies gar nicht zulässt. Insofern kann \(b_1\) nicht inhaltlich sinnvoll interpretiert werden.
\(b_2=0.11\) für die die Gruppe interpretiert werden, für die die Rahmenbedingungen null sind (X=0
). Anders als eben gibt es diese Gruppe, nämlich jene Gruppe, der nichts über den Klimawandel als Ursache gesagt wurde. Für diese Gruppe gilt: \(b_2\) ist der der (geschätzte) Unterschied in der Stärke der Rechtfertigung unterlassener Hilfe zwischen zwei Personen, die sich in ihrer Skepsis gegenüber dem Klimawandel um eine Einheit unterscheiden. Dies ist also der bedingte Effekt der Klimawandelskepsis auf die Stärke der Rechtfertigung unterlassener Hilfeleisung in jener Gruppe, der eine natürlichen Ursache für die Hungersnot genannt worden war. Das Vorzeichen ist positiv, was bedeutet, dass unter den Teilnehmern (ohne Klimawandel als genannte Ursache) diejenigen, die dem Klimawandel skeptischer gegenüberstanden, stärkere Begründungen für die Verweigerung der Hilfe für die Opfer hatten. Im Gegensatz zu \(b_1\) ist dies inhaltlich bedeutsam.
\(b_3=0.20\) ist der Regressionskoeffizient für das Produkt X und W. Dieser Koeffizient gibt an, wie sich der Effekt von X auf Y verändert, wenn sich W um eine Einheit ändert. In diesem Fall ist \(b_3\) statistisch von Null verschieden, was bedeutet, dass die Auswirkung des Framings der Dürreursache auf die Stärke der Rechtfertigung für die Zurückhaltung der Hilfe von der Skepsis gegenüber dem Klimawandel abhängt. Genauer gesagt, wenn die Skepsis gegenüber dem Klimawandel um eine Einheit zunimmt, steigt der Unterschied in der Stärke der Rechtfertigungen zwischen denjenigen, denen gesagt wurde, dass der Klimawandel die Ursache sei, und denjenigen, denen dies nicht gesagt wurde, um 0.2 Einheiten. \(b_3\) quantifiziert also einen Unterschied zwischen Unterschieden.
Teilaufgabe d
df_dstr %>% ggplot(aes(x = skeptic, y = justify, color = frame)) +
geom_point() +
geom_smooth(method = "lm", formula = 'y ~ x', se = FALSE) +
# labs(x = "Climate Change Skepticism (W)",
# y = "Strength of Justifications for Withholding Aid") +
theme_bw()
Teilaufgabe e
mdl_zent <- df_dstr %>%
mutate(skeptic_1 = skeptic-4) %>%
lm(data = ., justify ~ frame + skeptic_1 + frame:skeptic_1) #%>%
summary(mdl_zent)
Call:
lm(formula = justify ~ frame + skeptic_1 + frame:skeptic_1, data = .)
Residuals:
Min 1Q Median 3Q Max
-2.1267 -0.5864 -0.0117 0.5084 2.5484
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.87186 0.08151 35.233 < 2e-16 ***
frameClimate change 0.24226 0.11715 2.068 0.039887 *
skeptic_1 0.10508 0.03813 2.756 0.006375 **
frameClimate change:skeptic_1 0.20118 0.05527 3.640 0.000344 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.8129 on 207 degrees of freedom
Multiple R-squared: 0.2463, Adjusted R-squared: 0.2353
F-statistic: 22.54 on 3 and 207 DF, p-value: 1.138e-12
The reparameterization caused by centering W has affected \(b_1\). Remember that \(b_1\) is a conditional effect when XW′ is in the model. It estimates the effect of X on Y when \(W′= 0\). So two cases that differ by one unit on X are estimated to differ by 0.117 units on Y when W′ = 0. But notice that \(W′=0\) when \(W = -0.378\), so \(b_1\) now estimates the difference in strength of justifications for withholding aid between those told climate change caused the drought and those not so told among those with average climate change skepticism. Among such people with average skepticism about climate change, those told climate change was the cause of the drought were 0.117 units higher, on average, in the strength of their justifications for withholding aid to the victims than those not told climate change was responsible. But this difference between the conditions is not statistically significant (p = :297). This is substantively meaningful, unlike when the model was estimated with W in its original metric. [S. 257]
Anmerkung. Hayes (2022, S. 255–257) geht bei der Zentrierung des Moderators um dessen Mittelwert aus, \(\bar{M}=3.38\). Es kann angenommen werden, dass auf einer Skala von 1 bis 9 gemessen wird (vgl. summary(df_dstr$skeptic)
). Wieso hier mit -4
zentriert wird, ist unklar.
Teilaufgabe f
Aufgabe 2
Hier findet sich eine mögliche Lösung mit PROCESS.
Alternativ können die Daten mit dem 📦 brms
-Paket analysiert werden:
Das Modell wird mit der brm()
-Funktion analog zu lm()
spezifiziert:
mdl_brm <- brm(justify ~ frame*skeptic, data = df_dstr)
Compiling Stan program...
Start sampling
SAMPLING FOR MODEL 'anon_model' NOW (CHAIN 1).
Chain 1:
Chain 1: Gradient evaluation took 4.4e-05 seconds
Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.44 seconds.
Chain 1: Adjust your expectations accordingly!
Chain 1:
Chain 1:
Chain 1: Iteration: 1 / 2000 [ 0%] (Warmup)
Chain 1: Iteration: 200 / 2000 [ 10%] (Warmup)
Chain 1: Iteration: 400 / 2000 [ 20%] (Warmup)
Chain 1: Iteration: 600 / 2000 [ 30%] (Warmup)
Chain 1: Iteration: 800 / 2000 [ 40%] (Warmup)
Chain 1: Iteration: 1000 / 2000 [ 50%] (Warmup)
Chain 1: Iteration: 1001 / 2000 [ 50%] (Sampling)
Chain 1: Iteration: 1200 / 2000 [ 60%] (Sampling)
Chain 1: Iteration: 1400 / 2000 [ 70%] (Sampling)
Chain 1: Iteration: 1600 / 2000 [ 80%] (Sampling)
Chain 1: Iteration: 1800 / 2000 [ 90%] (Sampling)
Chain 1: Iteration: 2000 / 2000 [100%] (Sampling)
Chain 1:
Chain 1: Elapsed Time: 0.073 seconds (Warm-up)
Chain 1: 0.07 seconds (Sampling)
Chain 1: 0.143 seconds (Total)
Chain 1:
SAMPLING FOR MODEL 'anon_model' NOW (CHAIN 2).
Chain 2:
Chain 2: Gradient evaluation took 9e-06 seconds
Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.09 seconds.
Chain 2: Adjust your expectations accordingly!
Chain 2:
Chain 2:
Chain 2: Iteration: 1 / 2000 [ 0%] (Warmup)
Chain 2: Iteration: 200 / 2000 [ 10%] (Warmup)
Chain 2: Iteration: 400 / 2000 [ 20%] (Warmup)
Chain 2: Iteration: 600 / 2000 [ 30%] (Warmup)
Chain 2: Iteration: 800 / 2000 [ 40%] (Warmup)
Chain 2: Iteration: 1000 / 2000 [ 50%] (Warmup)
Chain 2: Iteration: 1001 / 2000 [ 50%] (Sampling)
Chain 2: Iteration: 1200 / 2000 [ 60%] (Sampling)
Chain 2: Iteration: 1400 / 2000 [ 70%] (Sampling)
Chain 2: Iteration: 1600 / 2000 [ 80%] (Sampling)
Chain 2: Iteration: 1800 / 2000 [ 90%] (Sampling)
Chain 2: Iteration: 2000 / 2000 [100%] (Sampling)
Chain 2:
Chain 2: Elapsed Time: 0.07 seconds (Warm-up)
Chain 2: 0.067 seconds (Sampling)
Chain 2: 0.137 seconds (Total)
Chain 2:
SAMPLING FOR MODEL 'anon_model' NOW (CHAIN 3).
Chain 3:
Chain 3: Gradient evaluation took 1e-05 seconds
Chain 3: 1000 transitions using 10 leapfrog steps per transition would take 0.1 seconds.
Chain 3: Adjust your expectations accordingly!
Chain 3:
Chain 3:
Chain 3: Iteration: 1 / 2000 [ 0%] (Warmup)
Chain 3: Iteration: 200 / 2000 [ 10%] (Warmup)
Chain 3: Iteration: 400 / 2000 [ 20%] (Warmup)
Chain 3: Iteration: 600 / 2000 [ 30%] (Warmup)
Chain 3: Iteration: 800 / 2000 [ 40%] (Warmup)
Chain 3: Iteration: 1000 / 2000 [ 50%] (Warmup)
Chain 3: Iteration: 1001 / 2000 [ 50%] (Sampling)
Chain 3: Iteration: 1200 / 2000 [ 60%] (Sampling)
Chain 3: Iteration: 1400 / 2000 [ 70%] (Sampling)
Chain 3: Iteration: 1600 / 2000 [ 80%] (Sampling)
Chain 3: Iteration: 1800 / 2000 [ 90%] (Sampling)
Chain 3: Iteration: 2000 / 2000 [100%] (Sampling)
Chain 3:
Chain 3: Elapsed Time: 0.065 seconds (Warm-up)
Chain 3: 0.072 seconds (Sampling)
Chain 3: 0.137 seconds (Total)
Chain 3:
SAMPLING FOR MODEL 'anon_model' NOW (CHAIN 4).
Chain 4:
Chain 4: Gradient evaluation took 1e-05 seconds
Chain 4: 1000 transitions using 10 leapfrog steps per transition would take 0.1 seconds.
Chain 4: Adjust your expectations accordingly!
Chain 4:
Chain 4:
Chain 4: Iteration: 1 / 2000 [ 0%] (Warmup)
Chain 4: Iteration: 200 / 2000 [ 10%] (Warmup)
Chain 4: Iteration: 400 / 2000 [ 20%] (Warmup)
Chain 4: Iteration: 600 / 2000 [ 30%] (Warmup)
Chain 4: Iteration: 800 / 2000 [ 40%] (Warmup)
Chain 4: Iteration: 1000 / 2000 [ 50%] (Warmup)
Chain 4: Iteration: 1001 / 2000 [ 50%] (Sampling)
Chain 4: Iteration: 1200 / 2000 [ 60%] (Sampling)
Chain 4: Iteration: 1400 / 2000 [ 70%] (Sampling)
Chain 4: Iteration: 1600 / 2000 [ 80%] (Sampling)
Chain 4: Iteration: 1800 / 2000 [ 90%] (Sampling)
Chain 4: Iteration: 2000 / 2000 [100%] (Sampling)
Chain 4:
Chain 4: Elapsed Time: 0.065 seconds (Warm-up)
Chain 4: 0.071 seconds (Sampling)
Chain 4: 0.136 seconds (Total)
Chain 4:
summary(mdl_brm)
Family: gaussian
Links: mu = identity; sigma = identity
Formula: justify ~ frame * skeptic
Data: df_dstr (Number of observations: 211)
Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup draws = 4000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
Intercept 2.44 0.15 2.16 2.74 1.00 2516
frameClimatechange -0.55 0.22 -0.98 -0.13 1.00 2325
skeptic 0.11 0.04 0.03 0.18 1.00 2519
frameClimatechange:skeptic 0.20 0.06 0.09 0.31 1.00 2160
Tail_ESS
Intercept 3082
frameClimatechange 2595
skeptic 2731
frameClimatechange:skeptic 2598
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 0.82 0.04 0.75 0.90 1.00 3121 2635
Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Eine Visualisierung ist mittels conditional_effects()
möglich
conditional_effects(mdl_brm)
Literaturverzeichnis
Fußnoten
Für eine einfache Interpretation bietet es sich an, zumindest eine der beiden Variablen als dichotom zu wählen, was sich in Lehrbüchern widerspiegelt und entsprechend auch hier. Schuster schreibt dazu: “Leicht verständlich ist Moderierte Multiple Regression (MMR) dann, wenn der Moderator metrisch und die UV dichotom ist”↩︎
statt Interaktion sprechen wir von Produkt, da erstere der ANOVA zugeordnet wird↩︎