7. Mediation-analyse

Het verhaal van dit thema

Een slak zat onder een blad en keek naar drie andere slakken die kwamen aanlopen.

De eerste droeg iets op zijn rug. Hij gaf het door aan de tweede. De tweede droeg het verder, en legde het bij de derde af.

“Mooi,” dacht de slak, “het pakje gaat van de eerste naar de derde — maar nooit rechtstreeks. Altijd via die tussen-slak.”

Hij dacht er nog een tijd over door, want zo werkte zijn eigen leven ook. Iemand zei iets, en het effect kwam pas later — via een gedachte die hij eerst nog moest verwerken. Niet rechtstreeks. Niet als bevel. Als doorgegeven stokje.

Een statisticus die dit had gezien zou hebben geknikt en mediation hebben gezegd. Een effect dat niet direct loopt, maar via een tussenpersoon.

Negentig slakken doen mee in dit thema. Bij elk is genoteerd hoe vaak hij in eerdere ontmoetingen werd weggetrokken (eerdere_afwijzing, XX), hoe sociaal voorzichtig hij in zijn binnenste is geworden (sociale_voorzichtigheid, MM), en hoe traag hij naar een nieuwe slak toe kruipt (ontmoetingstraagheid, YY). De vraag is niet of XX samenhangt met YY — dat doet het waarschijnlijk wel. De vraag is of XX zijn werk doet via MM, of ook buiten MM om.

De techniek heet mediation-analyse. Bij mediation stel je drie vragen aan je gegevens:

  1. Loopt het effect via MM? — schat het indirecte effect âb̂\hat{a}\hat{b} en toets het met de Aroian-toets.
  2. Hoeveel blijft er over zonder MM? — schat het direct-effect ĉ′\hat{c}' door XX en MM samen op YY te regresseren. Bij volledige mediation: ĉ′≈0\hat{c}' \approx 0.
  3. Klopt het allemaal wel? — temporele volgorde (XX vóór MM vóór YY), geen vergeten verstoorder die de samenhang kunstmatig opklopt, en lineaire patronen.
TipWat je na dit thema moet kunnen

Na dit thema kun je:

  1. herkennen wanneer mediation de juiste techniek is;
  2. uit drie regressies het totale, het directe en het indirecte effect van XX op YY halen, en ze in een pad-diagram zetten;
  3. nagaan of aa en bb allebei significant zijn;
  4. de proportie mediated uitrekenen, en het indirecte effect toetsen met de Aroian-toets;
  5. suppressie herkennen aan de tekens van de paden;
  6. uitleggen hoe een pijl de andere kant op kan wijzen, of hoe een verstoorder het verband tussen twee variabelen kan maken.

In R doe je dat met lm(), summary() en pnorm().

Drie dingen horen er ook bij, al oefent dit hoofdstuk ze niet: de effecten ook gestandaardiseerd uitrekenen (in β’s; hoe je van bb naar β komt, staat in thema 1), suppressie herkennen in een rij correlaties (ook thema 1, onder Suppressie — waarom het gedeelde stuk negatief kan worden), en een schijncorrelatie herkennen: een correlatie tussen twee variabelen die verdwijnt zodra je voor een derde corrigeert.

MacKinnon, Fairchild en Fritz (2007) beschrijven kort een rij uitbreidingen, zoals bootstrap en meerdere mediators. Het idee erachter is goed om te kennen; rekenen doe je er in dit oefenboek niet mee. Ze staan op een rij in Uitbreidingen uit MacKinnon, Fairchild en Fritz (2007), aan het eind.

Pas wat daarna komt, onder Wat blijft liggen, is extra: leesvoer voor wie verder wil.

OpmerkingA. Wat is mediation? — een estafette

Stel je voor: een estafetteloop met drie lopers. Loper-1 (XX) krijgt het stokje en geeft het aan loper-2 (MM). Loper-2 geeft het aan loper-3 (YY). Het stokje legt de hele afstand af, maar telkens via de tussenstap.

Dat is wat mediation modelleert. Drie paden:

  • aa-pad: X→MX \to M. Hoe groot is de stoot van loper-1 op loper-2? Geschat met lm(M ~ X).
  • bb-pad: M→YM \to Y, controlerend voor XX. Hoe groot is de stoot van loper-2 op loper-3, los van wat loper-1 ook nog rechtstreeks doet? Geschat met lm(Y ~ X + M), bb is de coëfficiënt op MM.
  • c′c'-pad: X→YX \to Y, controlerend voor MM. Heeft loper-1 nog een eigen sprint naar loper-3, naast de estafette? Dezelfde regressie, c′c' is de coëfficiënt op XX.

Het totaal-effect cc is de gewone bivariate samenhang van XX op YY, zonder MM in het model. Geschat met lm(Y ~ X). Dat is wat een buitenstaander zou meten als hij niet weet dat MM tussenin zit.

De decompositie van het totaal-effect:

c=c′+a⋅b c = c' + a \cdot b

In woorden: het totaal-effect is wat XX rechtstreeks aan YY levert (c′c') plus wat XX via MM aan YY levert (aa keer bb, het indirect-effect). Bij volledige mediation is c′≈0c' \approx 0 en doet XX zijn werk volledig via MM. Bij partiële mediation blijft c′c' staan en is er ook een directe route. Bij suppressie zijn a⋅ba \cdot b en c′c' tegengesteld in teken — de tussen-loper draagt het stokje tegen loper-3 in. Dan kan |c|<|c′||c| < |c'|. Daarover meer bij Suppressie, verderop.

OpmerkingB. De vier stappen van Baron en Kenny (1986) — en welke echt nodig zijn

De klassieke aanpak heet de causal steps: vier stappen, met drie regressies. Bij elke stap hoort de vraag of hij nodig is om van mediation te spreken. Het antwoord verschilt per stap:

Stap Regressie Wat je toetst Nodig voor mediation?
1 lm(Y ~ X) het totale effect cc van XX op YY nee
2 lm(M ~ X) het pad aa van XX naar MM ja
3 lm(Y ~ X + M) het pad bb van MM naar YY, gecontroleerd voor XX ja
4 dezelfde als stap 3 het directe effect c′c' van XX op YY, gecontroleerd voor MM nee

Waarom stap 1 niet nodig is. Het directe effect en het indirecte effect van XX op YY kunnen een tegengesteld teken hebben en elkaar opheffen. Dat heet inconsistente mediation. Het totale effect cc is dan klein of nul, terwijl er wél een effect van XX op YY via MM loopt. Wie stap 1 als poortwachter gebruikt, stuurt precies dat geval ten onrechte weg. Verderop, bij suppressie, zie je met echte getallen hoe het indirecte effect tegen het directe in werkt, waardoor het totale effect veel kleiner uitvalt dan het directe.

Waarom stap 4 niet nodig is. Stap 4 vertelt je of er naast de weg via MM nog een directe weg van XX naar YY loopt: c′≈0c' \approx 0 heet volledige mediation, een c′c' die duidelijk van nul verschilt heet partiële mediation. Dat onderscheid zegt iets over de vorm van de mediation, niet over de vraag óf er mediation is.

Niet nodig betekent: geen voorwaarde om van mediation te spreken. Uitrekenen doe je stap 1 en 4 wél, want zonder cc en c′c' heb je geen proportie mediated en geen onderscheid tussen volledig en partieel.

Stap 2 en 3 zijn dus de kern: zijn aa en bb allebei significant, dan wijst dat op mediation. Maar dat zijn twee losse toetsen, en het indirecte effect a⋅ba \cdot b is één ding. Daarom toets je dat daarna in één keer, met de Aroian-toets (zie De Aroian-toets verderop).

OpmerkingC. Slak-frame — wat onderzoeken we?

De slak ervaart iets sociaals — vroege afwijzing, kleine missers, weggetrokken voelers. Hij ontwikkelt daaruit een innerlijke voorzichtigheid: een soort sociale buffer voor toekomstige ontmoetingen. En in nieuwe ontmoetingen vertalen zich beide samen in zijn waargenomen gedrag: traag of vlot naar een nieuwe slak toe.

  • XX = eerdere_afwijzing — sociale geschiedenis (00-100100).
  • MM = sociale_voorzichtigheid — innerlijke buffer (00-100100).
  • YY = ontmoetingstraagheid — observeerbaar gedrag (00-100100).

De vraag van dit thema: gaat het effect van eerdere afwijzing op huidige ontmoetingstraagheid grotendeels via de sociale voorzichtigheid, of klimt afwijzing rechtstreeks in het gedrag?

OpmerkingHoe dit hoofdstuk leest

Dit hoofdstuk volgt dezelfde drie-laagse structuur als thema 1 t/m 6:

  1. Verhaal-frame — wat de slak doet of denkt.
  2. Algemene vorm — abstract, statistiek-Latijn met X, M, Y en mijn_data.
  3. Voor onze dieren — uitvoerend, met # hekjes en concrete namen.

Plus de antwoorden in een dichtgeklapt kader: die open je pas ná je eigen poging. T-vragen vlechten zich tussen de hoofdvragen door om je rekenintuïtie te oefenen.

Werkmaterialen — R-pakketten en functies

De slak pakt zijn gereedschap

Gereedschap Waar het voor is Pakket
lm(Y ~ X) Totaal-effect cc base
lm(M ~ X) aa-pad — X→MX \to M base
lm(Y ~ X + M) bb-pad en c′c'-pad samen base
summary(lm_obj)$coefficients Coëfficiënten + SESE + tt + pp base
pnorm() pp-waarde bij de zz van de Aroian-toets base
bda::mediation.test() Aroian-toets als controle (kolom Aroian) bda
OpmerkingWaarom drie aparte regressies en geen pakket-wrapper?

R kent geen mediation()-functie in base; pakketten als mediation, lavaan en bda doen het wrapper-werk. De route met de hand volstaat: drie OLS-regressies en daarna één Aroian-toets, met pnorm() voor de pp-waarde. Dat zie je hieronder. Het pakket bda::mediation.test() is een snelle controle achteraf — niet de hoofdtechniek.

Notatie — symbolen voor mediation

OpmerkingSleutelsymbolen in dit hoofdstuk

In dit oefenboek zie je telkens dezelfde notatie:

  • XX — de onafhankelijke variabele (predictor). Hier: eerdere_afwijzing.
  • MM — de mediator. Hier: sociale_voorzichtigheid.
  • YY — de afhankelijke variabele (outcome). Hier: ontmoetingstraagheid.
  • aa — geschatte regressiecoëfficiënt van MM op XX (uit lm(M ~ X)).
  • bb — geschatte regressiecoëfficiënt van YY op MM, controlerend voor XX (uit lm(Y ~ X + M)).
  • cc — geschat totaal-effect van XX op YY (uit lm(Y ~ X)).
  • c′c' — geschat direct-effect van XX op YY, controlerend voor MM (uit lm(Y ~ X + M)).
  • a⋅ba \cdot b — geschat indirect-effect via MM.
  • 𝑆𝐸a\mathit{SE}_a, 𝑆𝐸b\mathit{SE}_b — standaardfouten van â\hat{a} en b̂\hat{b}.
  • zz — de toetsgrootheid van de Aroian-toets op âb̂\hat{a}\hat{b}.

Voor inferentie spreek je over de populatie-parameters a*a^*, b*b^*, c*c^*, c′*c'^* (asterisk-notatie); voor rapportage over de geschatte â\hat{a}, b̂\hat{b}, ĉ\hat{c}, ĉ′\hat{c}'. Statistische symbolen staan cursief, zoals in APA: aa, bb, cc, XX, MM, YY, rr, tt, pp, zz, NN, nn, en ook SESE, dat uit twee letters bestaat. Dat geldt in een formule net zo goed als in een APA-zin.

TipWat moet je echt uit je hoofd kennen?

Stampen is een vies woord buiten de toetsweek, maar daar binnen helpt het écht. Voor mediation zijn er vijf dingen die je zonder spiekblad moet kunnen oproepen — herhaal ze hardop tot ze blijven plakken:

  1. Decompositie-identity: c=c′+a⋅bc = c' + a \cdot b — het totaal-effect splitst in een direct stuk en een indirect stuk. Geen toeval, een algebraïsche noodzakelijkheid bij OLS.
  2. Het kruis in de Aroian-formule: 𝑆𝐸ab=b2⋅𝑆𝐸a2+a2⋅𝑆𝐸b2+𝑆𝐸a2⋅𝑆𝐸b2\mathit{SE}_{ab} = \sqrt{b^2 \cdot \mathit{SE}_a^2 + a^2 \cdot \mathit{SE}_b^2 + \mathit{SE}_a^2 \cdot \mathit{SE}_b^2}. Krijg je de formule erbij, dan is wat je zelf meebrengt dat je hem goed invult: bb hoort bij 𝑆𝐸a\mathit{SE}_a, en aa bij 𝑆𝐸b\mathit{SE}_b. Dat kruis draai je onder tijdsdruk makkelijk om.
  3. De Aroian-zz: z=a⋅b𝑆𝐸abz = \dfrac{a \cdot b}{\mathit{SE}_{ab}}. Dit is gewoon “geschat effect gedeeld door zijn standaardfout” — net als bij elke andere tt- of zz-toets.
  4. De heilige z=1.96z = 1.96 voor tweezijdig α=.05\alpha = .05. Geen zz-tabel meer nodig — vanaf |z|≥1.96|z| \geq 1.96 verwerp je H0H_0.
  5. Decompositie van het totaal: propmed=a⋅bc\text{prop}_{\text{med}} = \dfrac{a \cdot b}{c} en propdirect=c′c\text{prop}_{\text{direct}} = \dfrac{c'}{c}. Samen moeten ze (op afrondingsfouten na) optellen tot 1. Elk apart hoeft níét tussen 0 en 1 te liggen: bij suppressie wordt de proportie mediated negatief of groter dan 1 — dat zie je bij Suppressie, verderop. En het is géén percentage verklaarde variantie: je verdeelt het totale effect cc in een direct en een indirect stuk, niet de variantie van YY.

Deze vijf zijn samen het skelet van de Aroian-route. Als ze in je hoofd staan, hoef je tijdens het tentamen alleen nog netjes de cijfers te combineren — niet meer na te denken wat-precies-waar.

Vuistregels zijn afspraken, geen wetten

De drempels in dit oefenboek zijn breed gangbare conventies — niet universeel:

  • Welke toets: de Aroian-toets. Hij heeft twee buren met een net andere standaardfout: de klassieke Sobel-toets en de Goodman-toets. De Aroian-toets neemt alle drie de termen onder de wortel mee, en krijgt zo van de drie de grootste standaardfout. Hij noemt een indirect effect dus het minst snel significant: van de drie is hij de voorzichtigste. De buren staan in het dichtgeklapte kader Voor wie verder wil — de twee buren van de Aroian-toets.
  • Volledige vs partiële mediation: c′c' niet-significant na correctie voor MM → volledige mediation. c′c' wel significant maar duidelijk kleiner dan cc → partiële. Beide aannames over de causale structuur — geen wiskundig bewijs. Dat onderscheid werkt in de praktijk slecht. Eén reden: of ĉ′\hat{c}' significant is, hangt ook af van de grootte van je steekproef. In een grote steekproef is bijna elke ĉ′\hat{c}' significant, en heet dus bijna elke mediation partieel.
  • Decompositie-controle: c≈c′+a⋅bc \approx c' + a \cdot b moet exact uitkomen op de getallen (afgezien van afrondings-ruis). Klopt dat niet, dan zit er een fout in je code of je data — vermoedelijk verschillende NN tussen de drie regressies door missing-cases-deletie.
  • Causale aannames: temporele volgorde (XX vóór MM vóór YY), geen ongemeten verstoorder die MM en YY allebei beïnvloedt, lineaire paden. Mediation toetst niet de causaliteit — die nemen we aan.

Met deze regels rekent dit oefenboek. Een ander handboek trekt een grens soms net anders; daarom zijn het afspraken en geen natuurwetten.

OpmerkingCode in dit hoofdstuk — wat moet je kunnen typen?

Code is standaard open als je hem zelf moet kunnen typen: lm(Y ~ X), lm(M ~ X), lm(Y ~ X + M), summary(.)$coefficients, de Aroian-formule met de hand, en pnorm() voor de pp-waarde. Code die alleen een plaatje of een tabel maakt — Venn-diagrammen, pad-diagrammen, gt-tabellen — staat ingeklapt met een knopje “Toon code”. Klap hem open als je nieuwsgierig bent.

7.0 Project- en datavoorbereiding

Aantekeningen netjes, paden kloppen

Download de bron van dit oefenboek (de zip op de voorpagina), pak hem uit en dubbelklik op mvda_werkboek.Rproj — één project voor alle thema’s. Open daarna 07_mediatie/07_mediatie.qmd en draai de code vanuit dat bestand: RStudio voert een chunk uit in de map van het hoofdstuk, dus de paden kloppen. De data van dit thema ligt in 07_mediatie/data/, de helper-functies in common/R/. Niets te installeren als de pakketten (tidyverse, bda, eulerr) op je computer staan; anders één keer:

install.packages(c("tidyverse", "bda", "eulerr"))
  1. Open de hoofd-dataset.
load("data/slak_ontmoetingen.RData")
str(slak_ontmoetingen)
'data.frame':   90 obs. of  4 variables:
 $ slak_id                : Factor w/ 90 levels "s01","s02","s03",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ eerdere_afwijzing      : num  61.4 59.4 58.3 57.1 63.8 ...
 $ sociale_voorzichtigheid: num  58.1 58.4 62.5 49.3 62.1 ...
 $ ontmoetingstraagheid   : num  44.6 48.6 52.9 37.9 63.8 ...

Per slak vier waarden: een slak_id plus drie continue scores op de schaal 00-100100. De drie variabelen vormen het voorgestelde mediation-pad: eerdere_afwijzing (XX) → sociale_voorzichtigheid (MM) → ontmoetingstraagheid (YY).

OpmerkingWat zit nog meer in slak_ontmoetingen.RData?

Naast slak_ontmoetingen (n=90n = 90) bevat het bestand een tweede object: slak_suppressie (n=80n = 80 andere slakken, een aparte studie naar bouwvaardigheid en perfectionisme). Dat tweede object gebruiken we pas verderop, bij Suppressie. Tot dan is slak_ontmoetingen genoeg.

7.1 Het mediation-model fitten en interpreteren

Drie regressies, één estafette

“Eerst kijken of het pakje überhaupt aankomt,” zei de slak. “Daarna of de tussen-slak het krijgt. Dan of de tussen-slak het doorgeeft. En tot slot: blijft er nog wat over voor de directe weg?”

OpmerkingVoor je gaat rekenen — vijf vragen aan jezelf

Het stappenplan, opnieuw, met de techniek-keuze als laatste stap.

  1. Wie of wat wordt er gemeten? De slak heeft 9090 slakken genoteerd, elk drie keer (één XX, één MM, één YY).

  2. Wat wordt er gemeten? Drie variabelen: eerdere_afwijzing, sociale_voorzichtigheid, ontmoetingstraagheid. Allemaal continu op een 00-100100 schaal.

  3. Onafhankelijk of afhankelijk? De onderzoeksvraag stelt een causaal pad voor: XX (→M\to M) →Y\to Y. Dus XX = eerdere_afwijzing, MM = sociale_voorzichtigheid, YY = ontmoetingstraagheid. De rol van MM is bemiddelend, niet zomaar een tweede predictor.

  4. Meetniveau van elke variabele? Alle drie interval (00-100100).

  5. Welke techniek? Doorloop de beslisboom:

flowchart TD
    A[Stel je een<br/>causaal pad voor?] -->|nee, alleen samenhang| B[gewone regressie<br/><i>thema 1</i>]
    A -->|ja, $X \to Y$ via $M$| C[Welke variabelen?]
    C -->|alle drie continu| Z[Mediation-analyse<br/><i>dit thema</i>]
    C -->|$M$ binair| D[Logistieke mediation]
    C -->|herhaalde metingen op M| E[Multilevel mediation]
    A -->|alleen interactie| F[Moderation-analyse<br/><i>geen mediation</i>]
    style Z fill:#faf3e2,stroke:#c9a05a,stroke-width:2px
OpmerkingPijltjes-overzicht — alle MVDA-technieken in één tabel

Dezelfde keuze, anders genoteerd. Lees als predictor(en) (meetniveau) → DV(s) (meetniveau):

# Predictor(en) DV(s) Techniek
dich |X| |Y| int tt-toets
nom 3+lvl |X| |Y| int éénweg ANOVA
1 int |X X …| |Y| int MRA — thema 1
2 nom |X X| |Y| int factorial ANOVA — thema 2
3 nom + int |X C| |Y| int ANCOVA — thema 3
4 bo(in) |X| |Y| bin LRA — thema 4
5 nom |X| |Y₁ Y₂ …| int MANOVA — thema 5
6 within-subject momenten |Y₁ Y₂ Y₃ Y₄| int RMA — thema 6
7 indirect via MM X→M→YX \to M \to Y pad Mediation — thema 7

Drie continue variabelen, één voorgesteld causaal pad. Antwoord: mediation-analyse via de stappen van Baron en Kenny plus de Aroian-toets.

BelangrijkMediatie ≠ moderatie — wees scherp op tentamen-stellingen

Bij mediatie loopt het effect via een tussenstap: X→M→YX \rightarrow M \rightarrow Y. Eén pad, doorgegeven als estafette. Het kernwoord in tentamen-stellingen is meestal “via” of “omdat” of “door middel van”.

Bij moderatie verschilt het effect van X op Y afhankelijk van het niveau van een derde variabele ZZ. Geen pad, maar een interactie (zoals in tweeweg-ANOVA, thema 2 — hoofdeffect A, hoofdeffect B, en de interactie A × B). Het kernwoord is meestal “sterker bij”, “alleen bij” of “hangt af van”.

In tentamen-stellingen kan een vraag over mediatie misleidend moderatie-taal bevatten en omgekeerd. Tentamen-test: lees de stelling letterlijk over en vraag jezelf: “gaat het hier om iets dat via iets anders loopt, of om iets dat anders sterk is bij verschillende niveaus?”

Probeer die twee dingen nooit door elkaar te halen — ze toetsen wezenlijk andere modellen.

T1 — Techniek-keuze: mediation, moderation, gewone regressie of pad-analyse?

OpmerkingVraag T1 — Pen-en-papier

Voor elk vignet: kies tussen mediation, moderation, gewone regressie of pad-analyse.

a) Een onderzoeker vermoedt dat eenzaamheid (XX) leidt tot minder slaap (MM), wat weer leidt tot meer prikkelbaarheid (YY).

b) Een onderzoeker vermoedt dat het effect van een training (XX) op prestatie (YY) sterker is bij mannen dan vrouwen (ZZ).

c) Een onderzoeker wil weten of leeftijd, opleiding en inkomen samen prestatie voorspellen, zonder een causaal pad te veronderstellen.

d) Een onderzoeker vermoedt een keten: pestervaring (XX) → zelfbeeld (M1M_1) → vermijding (M2M_2) → eenzaamheid (YY). Twee mediators in serie.

a) Een keten met één mediator ⇒\Rightarrow mediation-analyse. Drie regressies plus de Aroian-toets — het hoofdspoor van dit thema.

b) Een interactie tussen voorspellers (training ×\times geslacht) ⇒\Rightarrow moderation-analyse. Mediation onderzoekt het pad; moderation het verschil-in-effect. Wezenlijk andere vraag.

c) Geen voorgesteld causaal pad, alleen samenhang ⇒\Rightarrow gewone regressie (thema 1). Mediation vereist een vooraf-veronderstelde keten — anders is het data-fishing achteraf.

d) Twee mediators in serie ⇒\Rightarrow pad-analyse (sequential mediation). Strikt genomen mediation met meerdere mediators; in R met het pakket lavaan of mediation. Kort beschreven onder Multiple mediators verderop.

Vuistregel. Causaal pad via een tussenpersoon = mediation. Verschil-in-effect tussen groepen of niveaus = moderation. Samenhang zonder pad = gewone regressie. Meer dan één tussenpersoon = pad-analyse / SEM.

7.1.a Verkenning — gemiddelden, correlaties en scatter

Voordat de slak fit, kijkt hij eerst.

Algemene vorm.

# Gemiddelden + SD's per variabele.
sapply(mijn_data[, c("X", "M", "Y")], mean)
sapply(mijn_data[, c("X", "M", "Y")], sd)

# Correlatiematrix tussen $X$, $M$, $Y$ — patroon afkijken.
cor(mijn_data[, c("X", "M", "Y")])

# Scatter-matrix.
pairs(mijn_data[, c("X", "M", "Y")])

Voor onze dieren. Deze verkenning staat in twee schrijfwijzen naast elkaar, in tabbladen. Base R staat vooraan en is wat je nodig hebt; dplyr is er om te kijken.

# Gemiddelden + SD's.
round(sapply(slak_ontmoetingen[, c("eerdere_afwijzing",
                                   "sociale_voorzichtigheid",
                                   "ontmoetingstraagheid")], mean), 2)
      eerdere_afwijzing sociale_voorzichtigheid    ontmoetingstraagheid 
                  49.59                   51.95                   39.63 
round(sapply(slak_ontmoetingen[, c("eerdere_afwijzing",
                                   "sociale_voorzichtigheid",
                                   "ontmoetingstraagheid")], sd),   2)
      eerdere_afwijzing sociale_voorzichtigheid    ontmoetingstraagheid 
                  15.67                   12.67                   13.45 
# Correlatiematrix.
round(cor(slak_ontmoetingen[, c("eerdere_afwijzing",
                                "sociale_voorzichtigheid",
                                "ontmoetingstraagheid")]), 3)
                        eerdere_afwijzing sociale_voorzichtigheid
eerdere_afwijzing                   1.000                   0.616
sociale_voorzichtigheid             0.616                   1.000
ontmoetingstraagheid                0.402                   0.642
                        ontmoetingstraagheid
eerdere_afwijzing                      0.402
sociale_voorzichtigheid                0.642
ontmoetingstraagheid                   1.000
library(dplyr)   # één keer per R-sessie; library(tidyverse) laadt hem ook

# Het pijpje |> geeft door wat links staat aan de functie rechts.
# summarise() perst de tabel samen tot één regel; across() zegt: doe dat
# voor elk van deze drie kolommen.
slak_ontmoetingen |>
  summarise(across(c(eerdere_afwijzing, sociale_voorzichtigheid,
                     ontmoetingstraagheid), mean)) |>
  round(2)
  eerdere_afwijzing sociale_voorzichtigheid ontmoetingstraagheid
1             49.59                   51.95                39.63
slak_ontmoetingen |>
  summarise(across(c(eerdere_afwijzing, sociale_voorzichtigheid,
                     ontmoetingstraagheid), sd)) |>
  round(2)
  eerdere_afwijzing sociale_voorzichtigheid ontmoetingstraagheid
1             15.67                   12.67                13.45
# select() kiest de kolommen; cor() doet de rest.
slak_ontmoetingen |>
  select(eerdere_afwijzing, sociale_voorzichtigheid, ontmoetingstraagheid) |>
  cor() |>
  round(3)
                        eerdere_afwijzing sociale_voorzichtigheid
eerdere_afwijzing                   1.000                   0.616
sociale_voorzichtigheid             0.616                   1.000
ontmoetingstraagheid                0.402                   0.642
                        ontmoetingstraagheid
eerdere_afwijzing                      0.402
sociale_voorzichtigheid                0.642
ontmoetingstraagheid                   1.000
Toon code (scatter-matrix met paden geannoteerd)
pairs(slak_ontmoetingen[, c("eerdere_afwijzing",
                            "sociale_voorzichtigheid",
                            "ontmoetingstraagheid")],
      pch    = 16,
      col    = adjustcolor("#4477AA", alpha.f = 0.5),
      cex    = 0.9,
      labels = c("Eerdere afwijzing\n(X)",
                 "Sociale voorzichtigheid\n(M)",
                 "Ontmoetingstraagheid\n(Y)"),
      main   = "Slak — drie variabelen, drie scatter-paren")

Means-tabel — variabele-overzicht met gt

Toon code (gt-tabel met means + SD per variabele)
vars <- c("eerdere_afwijzing", "sociale_voorzichtigheid", "ontmoetingstraagheid")
means_v <- sapply(slak_ontmoetingen[, vars], mean)
sds_v   <- sapply(slak_ontmoetingen[, vars], sd)

tab_df <- data.frame(
  variabele = c("Eerdere afwijzing (X)",
                "Sociale voorzichtigheid (M)",
                "Ontmoetingstraagheid (Y)"),
  n  = nrow(slak_ontmoetingen),
  M  = means_v,
  SD = sds_v
)

tab_df |>
  gt() |>
  tab_header(title = "Slak — drie variabelen voor mediation") |>
  fmt_number(columns = c(M, SD), decimals = 2) |>
  cols_label(
    variabele = "Variabele",
    n  = md("*n*"),
    M  = md("*M*"),
    SD = md("*SD*")
  ) |>
  tab_options(table.font.size = px(12),
              table.border.top.style    = "none",
              table.border.bottom.style = "none")
Slak — drie variabelen voor mediation
Variabele n M SD
Eerdere afwijzing (X) 90 49.59 15.67
Sociale voorzichtigheid (M) 90 51.95 12.67
Ontmoetingstraagheid (Y) 90 39.63 13.45
OpmerkingVragen 7.1.a

a) Hoeveel slakken heeft de slak genoteerd?

b) Welke twee variabelen hangen het sterkst samen? Welke het zwakst?

c) Past het patroon bij een mediation-keten? Zou je rXMr_{XM} en rMYr_{MY} allebei groot verwachten?

d) Wat zegt rXYr_{XY} in het licht van rXMr_{XM} en rMYr_{MY}? Kunnen ze allemaal positief?

e) Wat zou je in de scatter-matrix willen zien dat een mediation-patroon ondersteunt?

In gewone woorden.

  1. n=90n = 90 slakken.

  2. De sterkste samenhang is tussen sociale_voorzichtigheid en ontmoetingstraagheid (rMY=.642r_{MY} = .642); de zwakste tussen eerdere_afwijzing en ontmoetingstraagheid (rXY=.402r_{XY} = .402). rXM=.616r_{XM} = .616 ligt daar tussenin.

  3. Bij een mediation-keten verwacht je rXMr_{XM} en rMYr_{MY} allebei stevig en niet-nul (anders is er geen pad om langs te lopen).

  4. rXYr_{XY} kan in principe alle waarden aannemen — bij volledige mediation hangt XX alleen via MM samen met YY, en is rXY≈rXM⋅rMY=.616⋅.642≈.395r_{XY} \approx r_{XM} \cdot r_{MY} = .616 \cdot .642 \approx .395, vergelijkbaar met de waargenomen .402.402. Klopt dus.

  5. In de scatter-matrix wil je drie positieve en lineaire clouds zien, geen kromming en geen extreme outliers.

APA-stijl.

Bij n=90n = 90 slakken bedroegen de gemiddelden MX=49.59M_X = 49.59 (SD=15.67SD = 15.67) voor eerdere afwijzing, MM=51.95M_M = 51.95 (SD=12.67SD = 12.67) voor sociale voorzichtigheid en MY=39.63M_Y = 39.63 (SD=13.45SD = 13.45) voor ontmoetingstraagheid. De correlaties waren positief en in lijn met een mediation-patroon (rXM=.62r_{XM} = .62, rMY=.64r_{MY} = .64, rXY=.40r_{XY} = .40).

T2 — Decompositie c=c′+abc = c' + ab — handrekenen

OpmerkingVraag T2 — Pen-en-papier

Een onderzoeker vond bij een mediation-analyse: â=0.40\hat{a} = 0.40, b̂=0.50\hat{b} = 0.50, ĉ′=0.10\hat{c}' = 0.10.

a) Bereken het indirect-effect âb̂\hat{a}\hat{b}.

b) Bereken het totaal-effect ĉ\hat{c} via de decompositie.

c) Welk percentage van het totaal-effect loopt via MM? (proportie mediated)

d) Bij welke waarden van ĉ′\hat{c}' zou je van volledige mediation spreken? Bij welke van partiële?

a) âb̂=0.40⋅0.50=0.20\hat{a}\hat{b} = 0.40 \cdot 0.50 = 0.20 — het indirect-effect via MM.

b) ĉ=ĉ′+âb̂=0.10+0.20=0.30\hat{c} = \hat{c}' + \hat{a}\hat{b} = 0.10 + 0.20 = 0.30.

c) Proportie mediated =âb̂/ĉ=0.20/0.30≈67%= \hat{a}\hat{b} / \hat{c} = 0.20 / 0.30 \approx 67\%. Tweederde van het totaal-effect loopt via MM.

d) Volledige mediation: ĉ′≈0\hat{c}' \approx 0 en niet-significant na controle voor MM. Partiële: ĉ′\hat{c}' blijft significant maar is kleiner dan ĉ\hat{c}. De grens is een conventie — sommige onderzoekers eisen ĉ′\hat{c}' niet-significant en |ĉ′/ĉ|<0.10|\hat{c}'/\hat{c}| < 0.10 voor “volledig”; anderen alleen het eerste.

Inzicht. De decompositie c=c′+abc = c' + ab is geen toevallige eigenschap maar een algebraïsche identiteit van OLS-regressie. Klopt het op de getallen niet, dan is er iets mis (verschillende NN, missende cases, of een coderingsfout). Het is je eigen sanity-check.

7.1.b De drie regressies — totaal, aa-pad, bb+c′c'-pad

Algemene vorm.

# Stap 1: totaal-effect $c$ — Y op X zonder M.
fit_total <- lm(Y ~ X, data = mijn_data)
summary(fit_total)$coefficients

# Stap 2: a-pad — M op X.
fit_a <- lm(M ~ X, data = mijn_data)
summary(fit_a)$coefficients

# Stap 3: b-pad en c'-pad — Y op X en M samen.
fit_bc <- lm(Y ~ X + M, data = mijn_data)
summary(fit_bc)$coefficients

Voor onze dieren.

# Stap 1: totaal-effect c.
fit_total <- lm(ontmoetingstraagheid ~ eerdere_afwijzing,
                data = slak_ontmoetingen)
summary(fit_total)$coefficients
                    Estimate Std. Error  t value      Pr(>|t|)
(Intercept)       22.5359085  4.3546800 5.175101 0.00000142130
eerdere_afwijzing  0.3446958  0.0837763 4.114479 0.00008713281
# Stap 2: a-pad.
fit_a <- lm(sociale_voorzichtigheid ~ eerdere_afwijzing,
            data = slak_ontmoetingen)
summary(fit_a)$coefficients
                   Estimate Std. Error  t value            Pr(>|t|)
(Intercept)       27.250832 3.52944675 7.720993 0.00000000001714578
eerdere_afwijzing  0.498054 0.06790028 7.335081 0.00000000010336100
# Stap 3: b-pad en c'-pad samen.
fit_bc <- lm(ontmoetingstraagheid ~ eerdere_afwijzing + sociale_voorzichtigheid,
             data = slak_ontmoetingen)
summary(fit_bc)$coefficients
                           Estimate Std. Error   t value         Pr(>|t|)
(Intercept)             4.162324729 4.75044767 0.8761963 0.38333617995605
eerdere_afwijzing       0.008888206 0.08957348 0.0992281 0.92118544885866
sociale_voorzichtigheid 0.674239358 0.11078081 6.0862469 0.00000003029358
OpmerkingVragen 7.1.b

a) Wat is ĉ\hat{c}, het totaal-effect? Is het significant?

b) Wat is â\hat{a}? Is het significant?

c) Wat zijn b̂\hat{b} en ĉ′\hat{c}'? Zijn ze significant? Wat is hun teken?

d) Vergelijk ĉ\hat{c} met ĉ′\hat{c}'. Wat is er gebeurd? Wijst dat op volledige of partiële mediation?

a) ĉ=0.345\hat{c} = 0.345, t(88)=4.11t(88) = 4.11, p<.001p < .001 — totaal-effect sterk significant. Eén punt extra eerdere afwijzing gaat samen met 0.340.34 punt extra ontmoetingstraagheid.

b) â=0.498\hat{a} = 0.498, t(88)=7.34t(88) = 7.34, p<.001p < .001 — aa-pad sterk significant. Eerdere afwijzing voorspelt sociale voorzichtigheid stevig.

c) b̂=0.674\hat{b} = 0.674, t(87)=6.09t(87) = 6.09, p<.001p < .001 — bb-pad sterk significant. ĉ′=0.009\hat{c}' = 0.009, t(87)=0.10t(87) = 0.10, p=.92p = .92 — direct-effect verwaarloosbaar en niet-significant na controle voor MM. Beide tekens positief; ĉ′\hat{c}' vrijwel nul.

d) ĉ=0.345\hat{c} = 0.345 kromp tot ĉ′=0.009\hat{c}' = 0.009 — bijna helemaal verdwenen na controle voor sociale voorzichtigheid. Dat wijst op (bijna) volledige mediation: het effect van eerdere afwijzing op ontmoetingstraagheid loopt nagenoeg helemaal via de sociale voorzichtigheid. Geen meetbare directe weg.

Inzicht. Een ĉ′\hat{c}' die instort tot bijna nul is het meest overtuigende mediation-signaal dat je kunt krijgen. Bij partiële mediation zou ĉ′\hat{c}' kleiner zijn dan ĉ\hat{c}, maar nog steeds nul-significant.

7.1.c Decompositie-controle — klopt c=c′+abc = c' + ab?

a_hat   <- coef(fit_a)["eerdere_afwijzing"]
b_hat   <- coef(fit_bc)["sociale_voorzichtigheid"]
c_prime <- coef(fit_bc)["eerdere_afwijzing"]
c_total <- coef(fit_total)["eerdere_afwijzing"]
ab_hat  <- a_hat * b_hat

c(a       = round(a_hat,   3),
  b       = round(b_hat,   3),
  ab      = round(ab_hat,  3),
  c_prime = round(c_prime, 3),
  c       = round(c_total, 3),
  c_check = round(c_prime + ab_hat, 3))
      a.eerdere_afwijzing b.sociale_voorzichtigheid      ab.eerdere_afwijzing 
                    0.498                     0.674                     0.336 
c_prime.eerdere_afwijzing       c.eerdere_afwijzing c_check.eerdere_afwijzing 
                    0.009                     0.345                     0.345 
OpmerkingWat staat hier?

Op de getallen: âb̂=0.498⋅0.674=0.336\hat{a}\hat{b} = 0.498 \cdot 0.674 = 0.336, plus ĉ′=0.009\hat{c}' = 0.009, samen 0.3450.345 — wat exact gelijk is aan ĉ=0.345\hat{c} = 0.345. De algebra van OLS klopt: het totaal-effect is per constructie de som van direct- en indirect-effect. Geen wonder, geen toeval; gewoon rekenen.

De proportie mediated is âb̂/ĉ=0.336/0.345\hat{a}\hat{b} / \hat{c} = 0.336 / 0.345, ongeveer 97%. Vrijwel alles loopt via MM.

Een Venn-diagram tekent verklaarde variantie, en die past slecht bij mediation. Toch kan zo’n plaatje laten zien wat ĉ′≈0\hat{c}' \approx 0 betekent — zolang je weet waar het ophoudt.

Toon code (Venn-diagram)
library(eulerr)

# Approximatieve gedeelde variantie-proporties op basis van r^2's
# en de mediation-decompositie. Niet exact-area-proportional in
# strikte zin — didactische illustratie.
fit <- euler(c(
  X         = 6,
  M         = 6,
  Y         = 6,
  "X&M"     = 4,
  "X&Y"     = 0.2,
  "M&Y"     = 4,
  "X&M&Y"   = 3.8
))

plot(fit,
     fills  = list(fill = c("#88CCEE", "#DDCC77", "#CC6677"), alpha = 0.55),
     labels = list(col = "black", cex = 1.1),
     edges  = list(col = "white", lwd = 2),
     main   = "Variantie-decompositie X, M, Y bij (bijna-)volledige mediation")

Wat zie je? De overlap X∩YX \cap Y ligt vrijwel volledig binnen MM: de drie cirkels overlappen in een groot gezamenlijk stuk, en er blijft maar een klein stuk X∩YX \cap Y buiten MM over. (De tekening is schematisch, niet op schaal.) Dat is de visuele weergave van ĉ′≈0\hat{c}' \approx 0: nadat je MM uit de overlap haalt (statistisch controleren), blijft er bijna geen rechtstreekse XX-YY-samenhang over. Bij partiële mediation zou dat stuk buiten MM duidelijk groter zijn.

Waar het plaatje ophoudt. Een Venn-diagram tekent gedeelde variantie. Mediation is strikt genomen een causaal pad-model met regressie-paden, niet een variantie-decompositie. De twee zijn alleen onder strenge voorwaarden verwisselbaar (alle paden positief, geen suppressie, geen ongemeten verstoorder). Een Venn kan bijvoorbeeld niet laten zien wanneer a⋅ba \cdot b negatief is en c′c' positief: cirkels overlappen geen “negatieve” oppervlakte. Voor inconsistente mediation, verderop bij Suppressie, gebruik je daarom een pad-diagram met pijlen en getekende coëfficiënten.

De Venn werkt dus als intuïtief plaatje voor consistente mediation. Niet als bewijs, niet als rapportage-figuur: in een artikel zet je het pad-diagram uit de APA-rapportage, verderop, met de geschatte coëfficiënten op de pijlen.

BelangrijkDon’t: causale taal bij mediation op cross-sectionele data

“XX heeft via MM een effect op YY.” Klinkt mooi. Op cross-sectionele data — alle drie tegelijk gemeten, geen randomisatie — is die zin ronduit overdreven. Mediation-coëfficiënten zijn dan niets meer dan voorwaardelijke samenhangen. “XX hangt samen met MM, en MM hangt samen met YY, controlerend voor XX” — punt. Geen “veroorzaakt”, geen “wordt verklaard door”. Het woordje via mag wél in de vaste naam het indirecte effect via MM: zo heet a⋅ba \cdot b nu eenmaal, ook in de APA-zinnen hieronder. Wat je niet doet, is er een oorzaak van maken — niet “XX veroorzaakt YY via MM”.

Causaal spreken mag pas als het design het draagt: XX gemanipuleerd, of de drie metingen in de tijd na elkaar. Dat oefen je in T8.

Wie in een artikel de causale taal toch gebruikt, kan dat best doen — maar dan met een DAG, een causaal diagram met pijlen van oorzaak naar gevolg (Pearl, 2009; VanderWeele, 2015), expliciete identificatie-aannames, en in de discussie verplicht een zin als deze:

These conclusions rest on the assumption of no unmeasured confounders and on the temporal ordering X→M→YX \to M \to Y.

Doe je dat niet, dan rapporteer je een keten van regressies en noem je dat hopelijk-causale-mediation. Reviewers houden niet van “hopelijk”.

7.1.d APA-rapportage van de drie regressies

Toon code (gt-tabel met drie regressies)
ct  <- summary(fit_total)$coefficients
ca  <- summary(fit_a)$coefficients
cbc <- summary(fit_bc)$coefficients

tab <- data.frame(
  Pad   = c("c (totaal: Y ~ X)",
            "a (M ~ X)",
            "b (Y ~ X + M, op M)",
            "c' (Y ~ X + M, op X)"),
  Est   = c(ct["eerdere_afwijzing", "Estimate"],
            ca["eerdere_afwijzing", "Estimate"],
            cbc["sociale_voorzichtigheid", "Estimate"],
            cbc["eerdere_afwijzing", "Estimate"]),
  SE    = c(ct["eerdere_afwijzing", "Std. Error"],
            ca["eerdere_afwijzing", "Std. Error"],
            cbc["sociale_voorzichtigheid", "Std. Error"],
            cbc["eerdere_afwijzing", "Std. Error"]),
  t     = c(ct["eerdere_afwijzing", "t value"],
            ca["eerdere_afwijzing", "t value"],
            cbc["sociale_voorzichtigheid", "t value"],
            cbc["eerdere_afwijzing", "t value"]),
  p     = c(ct["eerdere_afwijzing", "Pr(>|t|)"],
            ca["eerdere_afwijzing", "Pr(>|t|)"],
            cbc["sociale_voorzichtigheid", "Pr(>|t|)"],
            cbc["eerdere_afwijzing", "Pr(>|t|)"])
)

tab |>
  gt() |>
  tab_header(title = "Slak-mediation — drie regressies, vier paden") |>
  fmt_number(columns = c(Est, SE), decimals = 3) |>
  fmt_number(columns = t, decimals = 2) |>
  fmt(columns = p,
      fns = function(x) vapply(x, function(p) sub("^= ", "", pw(p)), "")) |>
  cols_label(
    Pad = "Pad",
    Est = md("*B*"),
    SE  = md("*SE*"),
    t   = md("*t*"),
    p   = md("*p*")
  ) |>
  tab_options(table.font.size = px(12),
              table.border.top.style    = "none",
              table.border.bottom.style = "none")
Slak-mediation — drie regressies, vier paden
Pad B SE t p
c (totaal: Y ~ X) 0.345 0.084 4.11 < .001
a (M ~ X) 0.498 0.068 7.34 < .001
b (Y ~ X + M, op M) 0.674 0.111 6.09 < .001
c' (Y ~ X + M, op X) 0.009 0.090 0.10 .92
OpmerkingPad-diagram — de estafette in beeld
Toon code (pad-diagram)
# Eenvoudige driehoek X — M — Y met de geschatte paden op de pijlen.
plot(NA, xlim = c(0, 10), ylim = c(0, 6),
     xlab = "", ylab = "", axes = FALSE,
     main = "Slak-mediation — geschatte paden")

# Knopen (boxen).
rect(0.5, 0.7, 2.5, 1.7, col = "#E0EAF5", border = "#4477AA", lwd = 2)
rect(4.5, 4.5, 6.5, 5.5, col = "#F5EAE0", border = "#CC6677", lwd = 2)
rect(8.5, 0.7, 10, 1.7, col = "#EAF5E0", border = "#117733", lwd = 2)

text(1.5, 1.2, "X\neerdere\nafwijzing", cex = 0.9)
text(5.5, 5.0, "M\nsociale\nvoorzichtigheid", cex = 0.9)
text(9.25, 1.2, "Y\nontmoetings-\ntraagheid", cex = 0.9)

# Pijlen.
arrows(2.5, 1.5, 4.5, 4.5, length = 0.15, lwd = 2)   # X -> M (a)
arrows(6.5, 4.5, 8.5, 1.5, length = 0.15, lwd = 2)   # M -> Y (b)
arrows(2.5, 1.2, 8.5, 1.2, length = 0.15, lwd = 2)   # X -> Y (c')

# Pad-labels, uitgerekend uit de drie regressies (a_hat, b_hat, c_prime en
# c_total komen uit 7.1.c) -- niet overtikken.
p_van   <- function(fit, term) summary(fit)$coefficients[term, "Pr(>|t|)"]
sterren <- function(p) if (p < .001) "***" else if (p < .01) "**" else if (p < .05) "*" else " (n.s.)"
label   <- function(naam, est, p) paste0(naam, " = ", sprintf("%.2f", est), sterren(p))

text(3.0, 3.4, label("a", a_hat, p_van(fit_a, "eerdere_afwijzing")),
     cex = 0.95, font = 3, col = "#222222")
text(8.0, 3.4, label("b", b_hat, p_van(fit_bc, "sociale_voorzichtigheid")),
     cex = 0.95, font = 3, col = "#222222")
text(5.5, 1.5, label("c'", c_prime, p_van(fit_bc, "eerdere_afwijzing")),
     cex = 0.95, font = 3, col = "#888888")

# Footer.
text(5, 0.2, paste0("(", label("c", c_total, p_van(fit_total, "eerdere_afwijzing")),
                    ";  a*b = ", sprintf("%.2f", a_hat * b_hat),
                    ";  c' = ", sprintf("%.2f", c_prime), ")"),
     cex = 0.85, col = "#444444")

Het pad-diagram is wat je in een artikel zet, niet een Venn-diagram. Coëfficiënten op de pijlen, pp-waarden via sterren of expliciet in legenda. Dit is APA-conform voor mediation.

TipAPA-rapportage — drie regressies in lopende tekst

Een mediation-analyse onderzocht of het effect van eerdere afwijzing (XX) op ontmoetingstraagheid (YY) verloopt via sociale voorzichtigheid (MM). Het totaal-effect was significant, ĉ=0.345\hat{c} = 0.345, SE=0.084SE = 0.084, t(88)=4.11t(88) = 4.11, p<.001p < .001. Het aa-pad was significant, â=0.498\hat{a} = 0.498, SE=0.068SE = 0.068, t(88)=7.34t(88) = 7.34, p<.001p < .001. Na opname van MM in het model was het bb-pad significant, b̂=0.674\hat{b} = 0.674, SE=0.111SE = 0.111, t(87)=6.09t(87) = 6.09, p<.001p < .001, terwijl het direct-effect ĉ′=0.009\hat{c}' = 0.009, SE=0.090SE = 0.090, t(87)=0.10t(87) = 0.10, p=.92p = .92, niet meer afweek van nul. De decompositie ĉ=ĉ′+âb̂\hat{c} = \hat{c}' + \hat{a}\hat{b} kwam exact uit (0.009+0.336=0.3450.009 + 0.336 = 0.345). Dit patroon wijst op (bijna) volledige mediation door sociale voorzichtigheid.

Nog geen toets op het indirecte effect zelf — die volgt hieronder, in De Aroian-toets.

T3 — Wat als cc niet significant is — geen mediation?

OpmerkingVraag T3 — Pen-en-papier

In het oorspronkelijke stappenplan van Baron en Kenny (1986) moest cc significant zijn voordat je mocht doortoetsen. Hierboven, bij De vier stappen van Baron en Kenny, staat bij stap 1: niet nodig voor mediation.

a) Welke logica zat er achter de oude eis?

b) Waarom is stap 1 toch niet nodig? (Hayes, 2018, en MacKinnon, Krull en Lockwood, 2000, geven dit argument.)

c) Bedenk een hypothetisch geval waarin cc klein-en-niet-significant is terwijl âb̂\hat{a}\hat{b} duidelijk significant is. Hoe kan dat?

d) Wat toets je dan in plaats van stap 1?

a) De logica achter de oude eis: als er überhaupt geen samenhang is tussen XX en YY, valt er niks te bemiddelen. Mediation moet iets mediëren.

b) Omdat inconsistente mediation (suppressie) precies dit oplevert: ĉ′\hat{c}' en âb̂\hat{a}\hat{b} tegengesteld in teken, samen klein. Het totaal-effect kan dan klein-en-niet-significant zijn, terwijl er wel degelijk een indirect pad loopt — het wordt alleen door het direct-pad geneutraliseerd.

c) Voorbeeld: â=+0.6\hat{a} = +0.6, b̂=−0.5\hat{b} = -0.5, âb̂=−0.3\hat{a}\hat{b} = -0.3, ĉ′=+0.3\hat{c}' = +0.3. Dan ĉ=0.0\hat{c} = 0.0. Het totaal-effect lijkt nul — maar er bestaat wel degelijk een effect via MM (negatief) én een direct effect (positief), die elkaar perfect opheffen. Mediation-output zonder stap-1-poortwachter zou dit zien; mét stap 1 zou de analyse al na stap 1 stoppen.

d) De paden aa en bb (stap 2 en 3), en het indirecte effect âb̂\hat{a}\hat{b} in één keer met de Aroian-toets. Zo toets je de mediation-hypothese rechtstreeks, zonder cc als poortwachter.

Inzicht. De vier klassieke stappen blijven een handige kapstok, maar per stap verschilt of hij nodig is — en bij stap 1 is dat antwoord nee. Voor het gevoel is stap 1 fijn om te doen; nodig heb je hem niet. Bij gewone consistente mediation maakt het geen verschil; bij suppressie wel. Dat zie je verderop, bij suppressie, met echte getallen.

7.2 De Aroian-toets — formele toets op het indirecte effect

Eén product, één standaardfout

Een baby-slak vroeg of âb̂\hat{a}\hat{b} vanzelf significant zou zijn. De oude slak zei: “Soms wel. Vaker krijg je het bewijs door een aparte toets, omdat het product van twee schattingen een eigen onzekerheid heeft.”

“Een zz-waarde voor het stokje,” mompelde de slak. “Niet voor de eerste loper, niet voor de tweede, maar voor het product van wat ze samen overdragen.”

Je hebt net gecheckt: is pad aa significant? Ja. Is pad bb significant? Ja. Maar is het pad abab significant? Dat zijn twee losse dingen, en je wilt ze als één geheel toetsen. Daarvoor is de Aroian-toets. Zijn nulhypothese zegt dat het indirecte effect a⋅ba \cdot b — het effect van XX op YY via MM — in de populatie nul is. De alternatieve hypothese zegt dat het van nul afwijkt.

OpmerkingDe Aroian-toets

z=âb̂𝑆𝐸abmet𝑆𝐸ab=b̂2𝑆𝐸a2+â2𝑆𝐸b2+𝑆𝐸a2𝑆𝐸b2 z = \dfrac{\hat{a}\hat{b}}{\mathit{SE}_{ab}} \qquad \text{met} \qquad \mathit{SE}_{ab} = \sqrt{\hat{b}^2\,\mathit{SE}_a^2 + \hat{a}^2\,\mathit{SE}_b^2 + \mathit{SE}_a^2\,\mathit{SE}_b^2}

Je ziet hem ook onder de naam Sobel test (Aroian version), en bda::mediation.test() drukt hem af in de kolom Aroian. Het is één en dezelfde toets: Sobel is de naam van de familie, Aroian de versie met drie termen onder de wortel. Vraagt een opgave kaal naar de Sobel-toets, kijk dan welke versie er bedoeld is; in dit oefenboek is dat altijd deze.

Waarom drie termen? â\hat{a} is een schatting: in een andere steekproef was hij net anders uitgevallen, en hoeveel hij zo schommelt, is zijn standaardfout 𝑆𝐸a\mathit{SE}_a. Voor b̂\hat{b} geldt hetzelfde. Zie het product âb̂\hat{a}\hat{b} als de oppervlakte van een rechthoek met zijden â\hat{a} en b̂\hat{b}:

Toon code (de rechthoek)
# Schematisch: geen data, alleen de vorm. Kleuren zonder rood-groenpaar; de
# labels dragen de betekenis, niet de kleur.
a <- 6; b <- 3.4; da <- 1.1; db <- 0.9
par(mar = c(0.5, 0.5, 0.5, 0.5))
plot(NA, xlim = c(-0.9, a + da + 0.2), ylim = c(-0.8, b + db + 0.2), asp = 1,
     axes = FALSE, xlab = "", ylab = "")
rect(0, 0, a, b,           col = "#E0EAF5", border = "#4477AA", lwd = 2)
rect(a, 0, a + da, b,      col = "#F8DDC0", border = "#EE7733", lwd = 2)
rect(0, b, a, b + db,      col = "#E6DDF0", border = "#AA4499", lwd = 2)
rect(a, b, a + da, b + db, col = "#DDDDDD", border = "#555555", lwd = 2)
text(a / 2, b / 2, expression(hat(a) %.% hat(b)), cex = 1.5)
text(a + da / 2, b / 2, expression(hat(a) ~ "schommelt"), srt = 90, cex = 0.95)
text(a / 2, b + db / 2, expression(hat(b) ~ "schommelt"), cex = 0.95)
text(a + da / 2, b + db / 2, "allebei", cex = 0.8)
text(a / 2, -0.4, expression("zijde" ~ hat(a)), cex = 1)
text(-0.45, b / 2, expression("zijde" ~ hat(b)), srt = 90, cex = 1)

Een rechthoek met onderaan de zijde a-dakje en links de zijde b-dakje; in het midden staat a-dakje maal b-dakje. Rechts ertegenaan een smalle staande strook, even hoog als de rechthoek, met het label 'a-dakje schommelt'. Bovenop een liggende strook, even breed als de rechthoek, met het label 'b-dakje schommelt'. Rechtsboven, waar de twee stroken elkaar raken, een klein hoekje met het label 'allebei'. De tekening is niet op schaal.

De stroken laten zien hoe gróót een schommeling is, niet welke kant op.

  • Schommelt â\hat{a}, dan groeit er rechts een strook bij: b̂\hat{b} lang en 𝑆𝐸a\mathit{SE}_a breed. In het kwadraat is dat de term b̂2𝑆𝐸a2\hat{b}^2\,\mathit{SE}_a^2.
  • Schommelt b̂\hat{b}, dan groeit er bovenop een strook bij: â\hat{a} lang en 𝑆𝐸b\mathit{SE}_b breed. In het kwadraat: â2𝑆𝐸b2\hat{a}^2\,\mathit{SE}_b^2.
  • Schommelen ze allebei, dan komt er ook nog het hoekje bij: 𝑆𝐸a\mathit{SE}_a bij 𝑆𝐸b\mathit{SE}_b. In het kwadraat: 𝑆𝐸a2𝑆𝐸b2\mathit{SE}_a^2\,\mathit{SE}_b^2.

Elke term onder de wortel is dus zo’n stuk in het kwadraat. Waarom in het kwadraat? Losse schommelingen tel je niet gewoon bij elkaar op: je telt hun kwadraten op en trekt aan het eind de wortel. Zo gaat het bij elke standaardfout. De tekening is niet op schaal: het hoekje is het product van twee kleine schommelingen, en daarom bijna altijd het kleinste stuk. Bij de slak is het ongeveer 1% van wat er onder de wortel staat.

Let op het kruis: b̂\hat{b} hoort bij 𝑆𝐸a\mathit{SE}_a, en â\hat{a} bij 𝑆𝐸b\mathit{SE}_b — kruiselings. De rechthoek laat zien waarom: de strook die ontstaat als â\hat{a} schommelt, heeft de lengte van b̂\hat{b}. Draai je die twee om, dan krijg je een getal dat er heel gewoon uitziet en toch fout is.

De toets behandelt zz als standaardnormaal. Bij |z|≥1.96|z| \geq 1.96 is p≤.05p \leq .05 (tweezijdig), en verwerp je de nulhypothese dat het indirecte effect van XX op YY via MM in de populatie nul is.

7.2.a De Aroian-toets met de hand

TipDe heilige z=1.96z = 1.96 — uit je hoofd

Eén zz-waarde die je gewoon uit je hoofd moet kennen voor toetsen tegen α=.05\alpha = .05 tweezijdig: z=1.96z = 1.96. Bij die waarde ligt in de twee staarten van een standaardnormale verdeling samen een kans van .05.05, dus .025.025 per staart. Vanaf |z|≥1.96|z| \geq 1.96 verwerp je H0H_0.

Voor de Aroian-toets betekent dat:

|z|≥1.96⇔p≤.05⇔H0 verwerpen |z| \geq 1.96 \;\Leftrightarrow\; p \leq .05 \;\Leftrightarrow\; H_0\text{ verwerpen}

Bij |z|=4.66|z| = 4.66 — zoals in dit voorbeeld — zit je ver buiten de tabel. Géén zz-tabel meer nodig: gewoon noteren p<.001p < .001 en doorgaan. Dezelfde 1.961.96 keert terug bij betrouwbaarheidsintervallen en bij standaardgebruik in LRA (thema 4).

Algemene vorm.

# Haal de coëfficiënten + standaardfouten op.
a_hat <- coef(fit_a)[["X"]]
b_hat <- coef(fit_bc)[["M"]]
se_a  <- summary(fit_a)$coefficients["X", "Std. Error"]
se_b  <- summary(fit_bc)$coefficients["M", "Std. Error"]

# Aroian: drie termen onder de wortel, in dezelfde volgorde als de formule.
se_ab    <- sqrt(b_hat^2 * se_a^2 + a_hat^2 * se_b^2 + se_a^2 * se_b^2)
z_aroian <- (a_hat * b_hat) / se_ab
p_aroian <- 2 * (1 - pnorm(abs(z_aroian)))
c(z = z_aroian, p = p_aroian)

Voor onze dieren.

a_hat <- coef(fit_a)[["eerdere_afwijzing"]]
b_hat <- coef(fit_bc)[["sociale_voorzichtigheid"]]
se_a  <- summary(fit_a)$coefficients["eerdere_afwijzing", "Std. Error"]
se_b  <- summary(fit_bc)$coefficients["sociale_voorzichtigheid", "Std. Error"]

se_ab    <- sqrt(b_hat^2 * se_a^2 + a_hat^2 * se_b^2 + se_a^2 * se_b^2)
z_aroian <- (a_hat * b_hat) / se_ab
p_aroian <- 2 * (1 - pnorm(abs(z_aroian)))
round(c(ab = a_hat * b_hat, se_ab = se_ab, z = z_aroian), 4)
    ab  se_ab      z 
0.3358 0.0721 4.6583 
p_aroian
[1] 0.000003188755
OpmerkingVragen 7.2.a

a) Neem â\hat{a}, 𝑆𝐸a\mathit{SE}_a, b̂\hat{b} en 𝑆𝐸b\mathit{SE}_b uit de R-uitvoer van 7.1.b, afgerond op vier decimalen. Wat is âb̂\hat{a}\hat{b}? Reken de drie termen onder de wortel uit, en daarmee de standaardfout van het indirecte effect, 𝑆𝐸ab\mathit{SE}_{ab}.

b) Wat is de Aroian-zz? Significant tegen α=.05\alpha = .05?

c) Zou je dezelfde conclusie krijgen op basis van de causal-steps-redenering uit 7.1.b?

a) Uit de uitvoer van 7.1.b, afgerond op vier decimalen: â=0.4981\hat{a} = 0.4981 met 𝑆𝐸a=0.0679\mathit{SE}_a = 0.0679, en b̂=0.6742\hat{b} = 0.6742 met 𝑆𝐸b=0.1108\mathit{SE}_b = 0.1108. Dan is âb̂=0.4981⋅0.6742=0.3358\hat{a}\hat{b} = 0.4981 \cdot 0.6742 = 0.3358. De drie termen onder de wortel:

b̂2𝑆𝐸a2=0.67422⋅0.06792=0.002096â2𝑆𝐸b2=0.49812⋅0.11082=0.003046𝑆𝐸a2𝑆𝐸b2=0.06792⋅0.11082=0.000057 \begin{aligned} \hat{b}^2\,\mathit{SE}_a^2 &= 0.6742^2 \cdot 0.0679^2 = 0.002096 \\ \hat{a}^2\,\mathit{SE}_b^2 &= 0.4981^2 \cdot 0.1108^2 = 0.003046 \\ \mathit{SE}_a^2\,\mathit{SE}_b^2 &= 0.0679^2 \cdot 0.1108^2 = 0.000057 \end{aligned}

Samen 0.0051990.005199, en de wortel daarvan is 𝑆𝐸ab=0.07210\mathit{SE}_{ab} = 0.07210.

b) z=0.3358/0.07210=4.66z = 0.3358 / 0.07210 = 4.66, p<.001p < .001 — sterk significant. Het indirecte effect van eerdere afwijzing op ontmoetingstraagheid, via sociale voorzichtigheid, is duidelijk niet nul.

c) Ja. De causal-steps-redenering (ĉ\hat{c} groot, ĉ′\hat{c}' klein) wees al op (bijna) volledige mediation; de Aroian-toets bevestigt formeel dat het verschil ĉ−ĉ′=âb̂\hat{c} - \hat{c}' = \hat{a}\hat{b} significant van nul verschilt.

Inzicht. De Aroian-formule lijkt mysterieus, maar is gewoon de standaardfout van een product van twee schattingen: de drie stukken van de rechthoek, bij elkaar opgeteld.

Bij elke zz-toets hoort een 95%95\%-betrouwbaarheidsinterval. Vanaf de schatting wandel je 1.961.96 standaardfouten naar links en 1.961.96 naar rechts. Voor het indirecte effect van XX op YY via MM:

âb̂±1.96⋅𝑆𝐸ab \hat{a}\hat{b} \pm 1.96 \cdot \mathit{SE}_{ab}

Bij de slak, met de getallen van de handberekening hierboven:

0.3358±1.96⋅0.07210=0.3358±0.1413=[0.1945,0.4771] \begin{aligned} 0.3358 \pm 1.96 \cdot 0.07210 &= 0.3358 \pm 0.1413 \\ &= [0.1945,\ 0.4771] \end{aligned}

Het interval bevat geen nul, en dat past bij p<.001p < .001: toets en interval leiden tot dezelfde conclusie. Dat is geen toeval. De Aroian-zz zegt hoeveel standaardfouten âb̂\hat{a}\hat{b} van nul af ligt, hier 4.664.66. Het interval reikt maar 1.961.96 standaardfouten ver. Ligt âb̂\hat{a}\hat{b} verder dan 1.961.96 standaardfouten van nul, dan haalt het interval de nul niet. Dat is dezelfde grens als bij de toets.

Wie het interval rapporteert, zet het achter de pp-waarde:

âb̂=0.336\hat{a}\hat{b} = 0.336, SE=0.072SE = 0.072, z=4.66z = 4.66, p<.001p < .001, 95%95\%-CI [0.195,0.477][0.195, 0.477].

Het interval ligt symmetrisch rond âb̂\hat{a}\hat{b}, en dat is zijn zwakke plek: het product van twee schattingen is zelf vaak scheef verdeeld. Daarom raden MacKinnon, Fairchild en Fritz (2007) liever een interval aan dat scheef mag zijn. Hoe je zo’n interval maakt, staat onder En bootstrap?, in het kader over de buren van de Aroian-toets.

7.2.b De Aroian-toets via een pakket — als controle

# install.packages("bda") indien nog niet aanwezig.
library(bda)

# mediation.test() geeft zijn uitkomst stil terug: bewaar hem, en vraag hem op.
uitvoer_bda <- bda::mediation.test(
  mv = slak_ontmoetingen$sociale_voorzichtigheid,
  iv = slak_ontmoetingen$eerdere_afwijzing,
  dv = slak_ontmoetingen$ontmoetingstraagheid
)
uitvoer_bda
                 Sobel         Aroian        Goodman
z.value 4.683839692289 4.658271522989 4.709833549968
p.value 0.000002815502 0.000003188755 0.000002479192
# Lees de kolom Aroian: z.value en p.value.
OpmerkingWat geeft bda::mediation.test() precies?

Het pakket drukt drie kolommen naast elkaar af: Sobel, Aroian en Goodman. Jij leest de kolom Aroian: daar staat dezelfde zz die je net met de hand uitrekende, z=4.66z = 4.66. De kolom Sobel is de klassieke versie met twee termen onder de wortel — níét de toets van dit hoofdstuk; die staat onder Aroian. De andere twee kolommen zijn buren van de Aroian-toets; ze staan in het kader Voor wie verder wil hieronder.

Dit oefenboek oefent de handmatige route (formule kennen, getallen invullen); het pakket is een controle achteraf. In een artikel rapporteer je de toets die je vooraf hebt gekozen — niet de gunstigste uit drie.

TipAPA-rapportage — de Aroian-toets in lopende tekst

Een Aroian-toets op het indirecte effect bevestigde dat sociale voorzichtigheid een significante mediator was, âb̂=0.336\hat{a}\hat{b} = 0.336, SE=0.072SE = 0.072, z=4.66z = 4.66, p<.001p < .001. Aangezien ĉ′\hat{c}' niet meer significant verschilde van nul, t(87)=0.10t(87) = 0.10, p=.92p = .92, wijst dit op (bijna) volledige mediation: het effect van eerdere afwijzing op ontmoetingstraagheid loopt nagenoeg geheel via de sociale voorzichtigheid.

De Aroian-toets heeft twee buren. Alle drie delen ze de teller âb̂\hat{a}\hat{b}; ze verschillen alleen in wat ze met de derde term onder de wortel doen:

Toets Standaardfout van âb̂\hat{a}\hat{b} De derde term 𝑆𝐸a2𝑆𝐸b2\mathit{SE}_a^2\,\mathit{SE}_b^2
Sobel (1982) b̂2𝑆𝐸a2+â2𝑆𝐸b2\sqrt{\hat{b}^2\,\mathit{SE}_a^2 + \hat{a}^2\,\mathit{SE}_b^2} weggelaten
Aroian (1944) b̂2𝑆𝐸a2+â2𝑆𝐸b2+𝑆𝐸a2𝑆𝐸b2\sqrt{\hat{b}^2\,\mathit{SE}_a^2 + \hat{a}^2\,\mathit{SE}_b^2 + \mathit{SE}_a^2\,\mathit{SE}_b^2} opgeteld
Goodman (1960) b̂2𝑆𝐸a2+â2𝑆𝐸b2−𝑆𝐸a2𝑆𝐸b2\sqrt{\hat{b}^2\,\mathit{SE}_a^2 + \hat{a}^2\,\mathit{SE}_b^2 - \mathit{SE}_a^2\,\mathit{SE}_b^2} afgetrokken

Een aanname onder alle drie. Ze gaan ervan uit dat â\hat{a} en b̂\hat{b} niet met elkaar samenhangen. Bij de drie regressies van een mediation-analyse klopt dat bij benadering: â\hat{a} komt uit de ene regressie, b̂\hat{b} uit een andere.

Waar het verschil vandaan komt. Sobel benadert de standaardfout van een product met alleen de eerste twee termen. Die benadering heet de delta-methode, en ze laat het stukje “allebei tegelijk” weg omdat het klein is. Aroian telt het mee: zijn formule is de exacte variantie van een product van twee schattingen die niet met elkaar samenhangen. Goodman trekt het juist af. Dat lijkt vreemd, maar de geschatte â2\hat{a}^2 en b̂2\hat{b}^2 in de eerste twee termen vallen gemiddeld zelf al een fractie te groot uit, en die aftrek corrigeert dat.

Op de slak. Met de objecten uit 7.2.a:

derde     <- se_a^2 * se_b^2
z_sobel   <- (a_hat * b_hat) / sqrt(b_hat^2 * se_a^2 + a_hat^2 * se_b^2)
z_goodman <- (a_hat * b_hat) / sqrt(b_hat^2 * se_a^2 + a_hat^2 * se_b^2 - derde)

round(c(Sobel = z_sobel, Aroian = z_aroian, Goodman = z_goodman), 3)
  Sobel  Aroian Goodman 
  4.684   4.658   4.710 

Sobel geeft z=4.68z = 4.68, Aroian 4.664.66 en Goodman 4.714.71: dezelfde conclusie, en ze liggen hooguit een paar honderdsten uit elkaar.

Wanneer het uitmaakt. De derde term is klein naast de andere twee zodra â\hat{a} en b̂\hat{b} veel groter zijn dan hun standaardfouten — en dat is precies wanneer ze duidelijk significant zijn. Het verschil telt dus alleen in een grensgeval rond |z|≈1.96|z| \approx 1.96, en vooral bij kleine steekproeven. Omdat Aroian de grootste noemer heeft, is hij van de drie de voorzichtigste: zit de klassieke Sobel nét boven 1.961.96, dan kan Aroian er nét onder zitten.

Verwarrende namen. De versie met drie termen heet ook wel Sobel test (Aroian version), en soms kortweg Sobel test. In artikelen bedoelt men met Sobel test vaak de versie met twee termen; staat er geen formule bij, dan weet je niet welke van de twee er gebruikt is. Daarom vermeld je zelf altijd welke versie je rapporteert.

En bootstrap? Alle drie behandelen âb̂\hat{a}\hat{b} alsof het normaal verdeeld is, en geven dus een symmetrisch interval. Een product van twee schattingen is in werkelijkheid vaak scheef verdeeld, zeker bij een kleine steekproef. Daarom raadt Hayes (2018) een bootstrap-interval aan: je trekt duizenden keren een nieuwe steekproef uit je eigen data, rekent telkens âb̂\hat{a}\hat{b} uit, en neemt de middelste 95%95\% van die uitkomsten. Dit oefenboek oefent dat niet; in R kan het met mediation::mediate() en boot = TRUE, of met Hayes’ PROCESS-macro.

T4 — De Aroian-toets met de hand, en een minteken dat je erin luist

OpmerkingVraag T4 — Pen-en-papier (rekenmachine mag)

Een onderzoeker vond â=−0.40\hat{a} = -0.40 met 𝑆𝐸a=0.10\mathit{SE}_a = 0.10, en b̂=0.50\hat{b} = 0.50 met 𝑆𝐸b=0.05\mathit{SE}_b = 0.05.

a) Bereken het indirecte effect âb̂\hat{a}\hat{b}.

b) Bereken de drie termen onder de wortel, en daarmee 𝑆𝐸ab\mathit{SE}_{ab}.

c) Bereken de Aroian-zz. Is het indirecte effect significant bij α=.05\alpha = .05, tweezijdig?

d) Een medestudent tikt â2\hat{a}^2 in als -0.40^2, in R of zo op zijn rekenmachine. Wat komt er dan uit, en wat gebeurt er met zijn zz?

a) âb̂=(−0.40)⋅0.50=−0.20\hat{a}\hat{b} = (-0.40) \cdot 0.50 = -0.20. Negatief: het indirecte effect gaat de andere kant op dan b̂\hat{b}.

b) De drie termen:

b̂2𝑆𝐸a2=0.502⋅0.102=0.0025â2𝑆𝐸b2=(−0.40)2⋅0.052=0.0004𝑆𝐸a2𝑆𝐸b2=0.102⋅0.052=0.000025 \begin{aligned} \hat{b}^2\,\mathit{SE}_a^2 &= 0.50^2 \cdot 0.10^2 = 0.0025 \\ \hat{a}^2\,\mathit{SE}_b^2 &= (-0.40)^2 \cdot 0.05^2 = 0.0004 \\ \mathit{SE}_a^2\,\mathit{SE}_b^2 &= 0.10^2 \cdot 0.05^2 = 0.000025 \end{aligned}

Samen 0.0029250.002925, dus 𝑆𝐸ab=0.002925=0.0541\mathit{SE}_{ab} = \sqrt{0.002925} = 0.0541.

c) z=−0.20/0.0541=−3.70z = -0.20 / 0.0541 = -3.70. Omdat |z|≥1.96|z| \geq 1.96, is het indirecte effect significant (p<.001p < .001). Het minteken van zz zegt alleen welke kant het effect op gaat; je kijkt naar |z||z|.

d) R rekent eerst het kwadraat uit en zet het minteken er daarna pas voor: -0.40^2 geeft −0.16-0.16 in plaats van 0.160.16. Op veel rekenmachines gaat het net zo. Dan loopt het zo mis:

  • de tweede term wordt −0.0004-0.0004 in plaats van 0.00040.0004;
  • de som onder de wortel zakt van 0.0029250.002925 naar 0.0021250.002125;
  • en de zz wordt −4.34-4.34 in plaats van −3.70-3.70.

Te groot, en je ziet niets: geen foutmelding, geen vreemd getal.

Tik daarom haakjes: (-0.40)^2. Of onthoud dat een kwadraat nooit negatief is en reken met het getal zonder minteken.

Inzicht. Deze fout is klassiek. In R ontloop je hem door met de objecten te rekenen (a_hat^2), zoals in 7.2.a, in plaats van de getallen over te tikken.

7.3 Suppressie — inconsistente mediation

Het stokje wordt tegen de eindloper in gedragen

“Soms,” zei de oude slak, “draagt de tussen-loper het stokje precies de andere kant op dan loper-1 wil. En dan komt het stokje toch bij loper-3 aan, maar met een ander teken erop.”

OpmerkingWat is suppressie in mediation-context?

In klassieke mediation-analyse veronderstellen we dat â\hat{a}, b̂\hat{b}, ĉ′\hat{c}' allemaal hetzelfde teken hebben. Dan is âb̂\hat{a}\hat{b} ook in dat teken, en het totaal-effect ĉ=ĉ′+âb̂\hat{c} = \hat{c}' + \hat{a}\hat{b} is groter (in absolute waarde) dan ĉ′\hat{c}' alleen.

Bij inconsistente mediation (MacKinnon, Krull & Lockwood, 2000) hebben âb̂\hat{a}\hat{b} en ĉ′\hat{c}' tegengesteld teken. Het indirect-effect werkt tegen het direct-effect. Resultaat: |ĉ|<|ĉ′||\hat{c}| < |\hat{c}'|. Dat is een klassiek suppressor-symptoom (Conger, 1974).

Wanneer treedt dit op? Wanneer de mediator MM de samenhang tussen XX en YY kleiner maakt dan-de-directe-weg-zou-doen — bijvoorbeeld als XX de mediator opwekt en de mediator vervolgens YY remt, terwijl XX zelf YY aanjaagt. De mediator gedraagt zich dan als een interne rem.

De termen in deze sectie komen uit de methodologische literatuur: Conger (1974), Tzelgov en Henik (1991), MacKinnon, Krull en Lockwood (2000), en MacKinnon (2008).

7.3.a Een voorbeeld — bouwvaardigheid, perfectionisme en actie

We gebruiken hier de tweede dataset uit slak_ontmoetingen.RData, namelijk slak_suppressie (n=80n = 80 andere slakken). De variabelen:

  • XX = bouwvaardigheid — algemene competentie (00-100100).
  • MM = perfectionisme — innerlijke kritischheid (00-100100).
  • YY = actie_snelheid — observeerbaar tempo van handelen (00-100100).

Theorie: hoge bouwvaardigheid maakt slakken sneller (direct), maar werkt ook perfectionisme in de hand (je weet wat goed is, dus je bent kritischer), en perfectionisme remt de actie. De mediator gedraagt zich tegen het direct-effect in.

str(slak_suppressie)
'data.frame':   80 obs. of  4 variables:
 $ slak_id        : Factor w/ 80 levels "b01","b02","b03",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ bouwvaardigheid: num  57.7 46.1 62.9 69 51.3 ...
 $ perfectionisme : num  68.5 32.1 84.5 66.3 60 ...
 $ actie_snelheid : num  23.3 38.2 11.2 40.9 23.9 ...
round(sapply(slak_suppressie[, c("bouwvaardigheid",
                                 "perfectionisme",
                                 "actie_snelheid")], mean), 2)
bouwvaardigheid  perfectionisme  actie_snelheid 
          54.88           49.30           34.07 
round(sapply(slak_suppressie[, c("bouwvaardigheid",
                                 "perfectionisme",
                                 "actie_snelheid")], sd), 2)
bouwvaardigheid  perfectionisme  actie_snelheid 
          15.26           12.64            9.69 
round(cor(slak_suppressie[, c("bouwvaardigheid",
                              "perfectionisme",
                              "actie_snelheid")]), 3)
                bouwvaardigheid perfectionisme actie_snelheid
bouwvaardigheid           1.000          0.704          0.295
perfectionisme            0.704          1.000         -0.154
actie_snelheid            0.295         -0.154          1.000
slak_suppressie |>
  summarise(across(c(bouwvaardigheid, perfectionisme, actie_snelheid), mean)) |>
  round(2)
  bouwvaardigheid perfectionisme actie_snelheid
1           54.88           49.3          34.07
slak_suppressie |>
  summarise(across(c(bouwvaardigheid, perfectionisme, actie_snelheid), sd)) |>
  round(2)
  bouwvaardigheid perfectionisme actie_snelheid
1           15.26          12.64           9.69
slak_suppressie |>
  select(bouwvaardigheid, perfectionisme, actie_snelheid) |>
  cor() |>
  round(3)
                bouwvaardigheid perfectionisme actie_snelheid
bouwvaardigheid           1.000          0.704          0.295
perfectionisme            0.704          1.000         -0.154
actie_snelheid            0.295         -0.154          1.000

Klik je heen en weer, dan staat het gemiddelde van perfectionisme links als 49.30 en rechts als 49.3. Dat is hetzelfde getal: base R zet een rijtje op evenveel decimalen, en dplyr laat de nul aan het eind vallen.

fit_total_s <- lm(actie_snelheid ~ bouwvaardigheid,
                  data = slak_suppressie)
fit_a_s     <- lm(perfectionisme ~ bouwvaardigheid,
                  data = slak_suppressie)
fit_bc_s    <- lm(actie_snelheid ~ bouwvaardigheid + perfectionisme,
                  data = slak_suppressie)

cat("c (totaal):\n");      print(round(summary(fit_total_s)$coefficients, 4))
c (totaal):
                Estimate Std. Error t value Pr(>|t|)
(Intercept)      23.7891     3.9123  6.0806   0.0000
bouwvaardigheid   0.1873     0.0687  2.7258   0.0079
cat("\na-pad:\n");         print(round(summary(fit_a_s)$coefficients,    4))

a-pad:
                Estimate Std. Error t value Pr(>|t|)
(Intercept)      17.3270     3.7917  4.5697        0
bouwvaardigheid   0.5826     0.0666  8.7496        0
cat("\nb + c'-pad:\n");    print(round(summary(fit_bc_s)$coefficients,   4))

b + c'-pad:
                Estimate Std. Error t value Pr(>|t|)
(Intercept)      33.3212     3.7508  8.8838        0
bouwvaardigheid   0.5078     0.0824  6.1663        0
perfectionisme   -0.5501     0.0995 -5.5301        0
a_s   <- coef(fit_a_s)["bouwvaardigheid"]
b_s   <- coef(fit_bc_s)["perfectionisme"]
cp_s  <- coef(fit_bc_s)["bouwvaardigheid"]
c_s   <- coef(fit_total_s)["bouwvaardigheid"]
ab_s  <- a_s * b_s

c(a   = round(a_s, 3),
  b   = round(b_s, 3),
  ab  = round(ab_s, 3),
  c_p = round(cp_s, 3),
  c   = round(c_s, 3))
  a.bouwvaardigheid    b.perfectionisme  ab.bouwvaardigheid c_p.bouwvaardigheid 
              0.583              -0.550              -0.321               0.508 
  c.bouwvaardigheid 
              0.187 
OpmerkingVragen 7.3

a) Wat zijn de tekens van â\hat{a}, b̂\hat{b}, âb̂\hat{a}\hat{b}, ĉ′\hat{c}' en ĉ\hat{c}? Welk teken is “tegen de richting in”?

b) Vergelijk |ĉ||\hat{c}| met |ĉ′||\hat{c}'|. Wat valt op? Wat zegt dat?

c) Wat is de proportie mediated âb̂/ĉ\hat{a}\hat{b} / \hat{c}? Hoe zou je dit interpreteren — en had de oude eis van stap 1 (ĉ\hat{c} moet significant zijn) dit signaal gemist?

d) Schets in woorden hoe je dit als pad-diagram zou tekenen.

a) â=+0.583\hat{a} = +0.583 (positief — meer bouwvaardigheid → meer perfectionisme), b̂=−0.550\hat{b} = -0.550 (negatief — meer perfectionisme → minder snelheid), âb̂=−0.321\hat{a}\hat{b} = -0.321 (negatief — indirect-effect remt YY), ĉ′=+0.508\hat{c}' = +0.508 (positief — directe boost van bouwvaardigheid op snelheid), ĉ=+0.187\hat{c} = +0.187 (positief, maar klein). Het negatieve teken zit op b̂\hat{b} — perfectionisme remt actie.

b) |ĉ|=0.187<|ĉ′|=0.508|\hat{c}| = 0.187 < |\hat{c}'| = 0.508 — het totaal-effect is kleiner dan het direct-effect. Dat is precies het suppressor-symptoom: het indirect-effect via perfectionisme werkt tegen het direct-effect in en knaagt aan het totaal-effect.

c) Proportie mediated =âb̂/ĉ=−0.321/0.187= \hat{a}\hat{b} / \hat{c} = -0.321 / 0.187, ongeveer −171%. (Met de afgeronde getallen uit deze zin kom je op −172%; dat verschil is afronding.) Een negatief percentage, en in absolute waarde groter dan 100%100\%. Dat is het signaal van inconsistente mediation: het indirect-effect is groter dan het totaal-effect en heeft het tegenovergestelde teken.

De oude eis van stap 1 had dit hier nog gehaald: ĉ=0.187\hat{c} = 0.187, t(78)=2.73t(78) = 2.73, p=.008p = .008. Maar was de tegenkracht via perfectionisme iets sterker geweest, dan was ĉ\hat{c} in de buurt van nul gekomen en had stap 1 het signaal weggestuurd — terwijl er wel degelijk een mediation-pad loopt. Daarom is stap 1 geen voorwaarde voor mediation.

d) Drie pijlen: X→MX \to M met a=+0.58a = +0.58 (positief), M→YM \to Y met b=−0.55b = -0.55 (negatief, dunne stippellijn of expliciet “−”-teken), X→YX \to Y met c′=+0.51c' = +0.51 (positief). De negatieve bb markeer je expliciet — anders ziet de lezer hem niet.

Inzicht. Bij inconsistente mediation telt een Venn-diagram tegen je: je kunt geen “negatieve overlap” tekenen. Pad-diagrammen met tekens zijn de juiste rapportage-figuur — ze tonen de richting expliciet.

T5 — Suppressie herkennen aan tekens

OpmerkingVraag T5 — Pen-en-papier

Een onderzoeker rapporteert vier mediation-analyses met de volgende uitkomsten:

Analyse â\hat{a} b̂\hat{b} ĉ′\hat{c}' ĉ\hat{c}
1 +0.4+0.4 +0.5+0.5 +0.1+0.1 +0.3+0.3
2 +0.4+0.4 −0.5-0.5 +0.6+0.6 +0.4+0.4
3 +0.5+0.5 +0.6+0.6 0.00.0 +0.3+0.3
4 −0.4-0.4 +0.5+0.5 −0.4-0.4 −0.6-0.6

a) Welke analyse(s) tonen consistente mediation?

b) Welke tonen inconsistente mediation (suppressie)?

c) Welke tonen volledige mediation?

d) Bij welke is Baron-Kenny stap 1 problematisch?

Bereken eerst âb̂\hat{a}\hat{b} en check decompositie:

Analyse âb̂\hat{a}\hat{b} ĉ′+âb̂\hat{c}' + \hat{a}\hat{b} Type
1 +0.20+0.20 +0.30+0.30 ✓ consistent partieel
2 −0.20-0.20 +0.40+0.40 ✓ inconsistent (suppressie)
3 +0.30+0.30 +0.30+0.30 ✓ volledig (consistent, ĉ′=0\hat{c}' = 0)
4 −0.20-0.20 −0.60-0.60 ✓ consistent partieel (alle paden negatief)

a) Analyses 1, 3 en 4 — in alle drie hebben âb̂\hat{a}\hat{b} en ĉ′\hat{c}' hetzelfde teken (of ĉ′=0\hat{c}' = 0).

b) Analyse 2 — âb̂=−0.20\hat{a}\hat{b} = -0.20 tegenover ĉ′=+0.60\hat{c}' = +0.60. Verschillende tekens. |ĉ|=0.40<|ĉ′|=0.60|\hat{c}| = 0.40 < |\hat{c}'| = 0.60. Klassiek suppressor-symptoom.

c) Analyse 3 — ĉ′=0\hat{c}' = 0 en ĉ=âb̂\hat{c} = \hat{a}\hat{b}. Het hele effect loopt via MM.

d) Analyse 2 vooral. Als de suppressie iets sterker was geweest (âb̂\hat{a}\hat{b} groter, of ĉ′\hat{c}' kleiner), kan ĉ\hat{c} in de buurt van nul komen. Stap 1 zou dan ten onrechte concluderen “geen samenhang, geen mediation” — terwijl er wel een mediation-pad loopt.

Inzicht. Tekens checken duurt twee seconden en redt je van een misleidende stap 1.

T6 — Volledige vs partiële mediation — decisieregel en kritiek

OpmerkingVraag T6 — Pen-en-papier

a) Wat is de gangbare decisieregel voor volledige versus partiële mediation?

b) Dit onderscheid werkt in de praktijk slecht. Waarom? (Hayes, 2018, werkt dat argument uit.)

c) Hoe rapporteer je mediation als ĉ′\hat{c}' klein-maar-significant is bij N=1000N = 1000?

d) Is het verschil tussen “ĉ′\hat{c}' niet-significant” en “ĉ′\hat{c}' verwaarloosbaar klein” hetzelfde?

a) Gangbaar: volledig als ĉ′\hat{c}' niet meer significant verschilt van nul na controle voor MM; partieel als ĉ′\hat{c}' wel significant blijft maar duidelijk kleiner is dan ĉ\hat{c}.

b) Hayes (2018) wijst erop dat de termen “volledig” en “partieel” steekproef-grootte-afhankelijk zijn. Bij grote nn wordt zelfs een verwaarloosbaar klein ĉ′\hat{c}' significant; mediation lijkt dan altijd “partieel”. Bij kleine nn is bijna alles “volledig” omdat de toets te weinig power heeft. De labels zeggen meer over de power van je studie dan over de natuur van de mediation.

c) Bij N=1000N = 1000 is bijna elk niet-nul ĉ′\hat{c}' significant, ook als het klinisch betekenisloos is (ĉ′=0.005\hat{c}' = 0.005 bijvoorbeeld). Rapporteer dan effectgrootte (proportie mediated, of ĉ′/ĉ\hat{c}'/\hat{c}) in plaats van alleen pp-waarden. “Bij N=1000N = 1000 was ĉ′=0.005\hat{c}' = 0.005 formeel significant, maar de proportie mediated was 97%97\% — wat duidt op feitelijk volledige mediation.”

d) Nee. Niet-significant is een uitspraak over je toets-power; verwaarloosbaar klein een uitspraak over de effectgrootte. Bij grote nn kan iets significant zijn dat verwaarloosbaar is; bij kleine nn kan iets niet-significant zijn dat substantieel is.

Inzicht. Rapporteer voor mediation: ĉ\hat{c}, ĉ′\hat{c}', âb̂\hat{a}\hat{b} met SESE, plus proportie mediated. Laat de lezer zelf interpreteren of “volledig” of “partieel” passend is. De labels zijn handig in een zin, niet als formele conclusie.

Multiple mediators

Twee tussen-slakken in plaats van één

Hier gaat het om het idee: in dit oefenboek reken je alleen met één mediator.

In sommige onderzoeksvragen lopen meerdere mediators tegelijk:

  • Parallelle mediators: XX → M1M_1 → YY en XX → M2M_2 → YY, onafhankelijk van elkaar. Voorbeeld: stress → cortisol → slaap én stress → piekeren → slaap.
  • Seriële mediators: XX → M1M_1 → M2M_2 → YY, een keten. Voorbeeld: pestervaring → zelfbeeld → vermijding → eenzaamheid.

Bij twee of meer mediators wordt de route met de hand te omslachtig en grijpt de praktijk vaker naar path-analyse in pakket lavaan of bootstrap-mediation in mediation. De decompositie ĉ=ĉ′+∑âkb̂k\hat{c} = \hat{c}' + \sum \hat{a}_k \hat{b}_k blijft gelden — alleen het indirect-effect is nu een som van pad-producten.

Met twee parallelle mediators ziet dat er zo uit: vier regressies, twee indirecte effecten (â1b̂1\hat{a}_1\hat{b}_1 en â2b̂2\hat{a}_2\hat{b}_2), en ĉ=ĉ′+â1b̂1+â2b̂2\hat{c} = \hat{c}' + \hat{a}_1\hat{b}_1 + \hat{a}_2\hat{b}_2. Dat is het idee om vast te houden: het totale effect verdeelt zich over twee indirecte routes en een directe.

T7 — Parallel of serieel — wanneer welke?

OpmerkingVraag T7 — Pen-en-papier

Voor elk vignet: parallel (M1M_1 en M2M_2 naast elkaar), serieel (M1→M2M_1 \to M_2), of geen multiple mediator?

a) Stress (XX) verhoogt cortisol (M1M_1) én piekeren (M2M_2); beide verminderen slaap (YY).

b) Pestervaring (XX) verlaagt zelfbeeld (M1M_1); laag zelfbeeld leidt tot vermijding (M2M_2); vermijding leidt tot eenzaamheid (YY).

c) Training (XX) verhoogt prestatie (YY); we vermoeden dat motivatie de relatie modereert.

a) Parallel. Twee onafhankelijke mediators tussen XX en YY. Een Aroian-toets per indirect effect (of een bootstrap-CI).

b) Serieel. Drie schakels in een keten: X→M1→M2→YX \to M_1 \to M_2 \to Y. Pad-analyse in lavaan of mediation-bootstrap.

c) Geen multiple mediator — dit is moderation (motivatie modereert het effect, dus interactie). Ander techniek-spoor.

Vuistregel. Twee tussenstops onafhankelijk = parallel. Twee tussenstops in keten = serieel. Verandering-in-effect afhankelijk van een derde variabele = moderation, geen mediation.

Wat mediation-analyse niet bewijst

Wat de slak niet kan zien

T8 — Causale aannamen bij mediation

OpmerkingVraag T8 — Pen-en-papier

Mediation-analyse is een statistische techniek met causale interpretatie. Welke aannames moeten kloppen?

a) Wat betekent temporele volgorde in het mediation-model?

b) Wat is een ongemeten verstoorder en hoe maakt die mediation onbetrouwbaar?

c) Waarom is correlationele data zelden voldoende voor sterke mediation-claims?

d) Welk onderzoeksdesign maakt mediation-claims sterker?

a) Temporele volgorde: XX moet vóór MM zijn gemeten, MM vóór YY. Anders kan een correlatie even goed in omgekeerde richting werken (bv. Y→M→XY \to M \to X). Cross-sectionele data is in dat opzicht zwak — alle drie zijn op hetzelfde moment gemeten.

b) Een ongemeten verstoorder is een variabele die zowel MM als YY beïnvloedt en die niet in het model zit. Voorbeeld: persoonlijkheidstrek CC veroorzaakt zowel sociale voorzichtigheid als ontmoetingstraagheid. Dan is het b̂\hat{b}-pad (en daarmee âb̂\hat{a}\hat{b}) biased — een deel van de schijnbare mediation is verstoring.

c) Correlationele data laat alleen samenhang zien; mediation-coëfficiënten zijn dan voorwaardelijke samenhangen, geen causale effecten. Wie causale mediation claimt op basis van cross-sectionele correlationele data, doet aanmatigend werk.

d) Experimenteel design waarin XX wordt gemanipuleerd. Als XX random is toegewezen, kan geen ongemeten verstoorder XX-MM of XX-YY vertroebelen. Het bb-pad blijft kwetsbaar — daar is MM niet gerandomiseerd. Dubbele randomisatie (zowel XX als MM) is sterk maar vaak niet realistisch.

Inzicht. Mediation-output zonder design-onderbouwing is een statistisch kunststukje. De zwakke causaliteit blijft de zwakke causaliteit. Rapporteer expliciet of je correlationele of experimentele data hebt, en bij correlationeel: noem de aanname en de meest plausibele alternatieve verklaring.

Waarom de Aroian-toets een symmetrisch betrouwbaarheidsinterval om âb̂\hat{a}\hat{b} geeft. De Aroian-toets neemt aan dat âb̂\hat{a}\hat{b} normaalverdeeld is, en construeert het CI als âb̂±1.96⋅𝑆𝐸ab\hat{a}\hat{b} \pm 1.96 \cdot \mathit{SE}_{ab}. Symmetrisch om de schatting.

Waarom de werkelijke verdeling van âb̂\hat{a}\hat{b} niet symmetrisch is. Een product van twee normaal verdeelde schattingen is zelf niet normaal verdeeld. Liggen beide precies op nul, dan is het product wel symmetrisch, maar met veel dikkere staarten dan een normaalverdeling. Liggen ze er een eindje vanaf, dan wordt het scheef: één staart langer dan de andere — het sterkst als de schattingen niet veel groter zijn dan hun standaardfouten. Het symmetrische interval van de Aroian-toets mist die scheefheid.

Wat een bootstrap-CI doet dat de Aroian-toets niet doet. Bootstrap herhaalt de drie regressies BB keer (typisch B=5000B = 5000) op herbemonsterde data, berekent telkens âb̂\hat{a}\hat{b}, en pakt de 2.5%2.5\%- en 97.5%97.5\%-percentielen van de bootstrap-verdeling als CI. Dat is een percentile-based interval — asymmetrisch als de verdeling asymmetrisch is. Hayes’ PROCESS-macro doet dit standaard.

Waarom dit oefenboek toch de Aroian-toets volgt. De Aroian-toets is een didactische basis: één formule, met de hand uit te rekenen en na te rekenen. Bootstrap is statistisch krachtiger, maar vraagt duizenden herhalingen op de computer en laat zich niet met de hand narekenen. Wie publiceert: een scheef interval, zoals dat van de bootstrap, is de moderne aanbeveling — ook in MacKinnon, Fairchild en Fritz (2007).

Inzicht. De Aroian-toets leren = mediation conceptueel begrijpen. Bootstrap aanleren = mediation kunnen publiceren. Beide hebben hun plek; dit oefenboek pakt de eerste.

T9 — Wanneer is mediation niet zinnig?

OpmerkingVraag T9 — Pen-en-papier

In welke situaties is een mediation-analyse niet geschikt?

a) Twee variabelen, geen voorgestelde mediator.

b) Drie variabelen, maar de causale richting tussen MM en YY is onbekend.

c) Drie variabelen, allemaal binair gemeten.

d) Drie variabelen, gemeten op één moment in cross-sectioneel onderzoek met n=30n = 30.

a) Niet zinnig — mediation vereist drie variabelen. Twee variabelen = gewone regressie of correlatie.

b) Risicovol — als M→YM \to Y niet vaststaat, kan ook Y→MY \to M even goed kloppen, en dan klopt het hele decompositie-frame niet. Beslis eerst (theoretisch of via design) wat MM en wat YY is.

c) Mogelijk, maar niet met de route uit dit hoofdstuk — voor binaire YY gebruik je logistic mediation (zie Wat blijft liggen). De OLS-decompositie ĉ=ĉ′+âb̂\hat{c} = \hat{c}' + \hat{a}\hat{b} klopt dan niet meer in standaard zin (logit en lineaire schaal mengen niet). Voor binair XX kan het wel met OLS.

d) Twee problemen tegelijk: cross-sectioneel mist temporele volgorde (zwakke causaliteit), en n=30n = 30 is klein. Bij n=30n = 30 heb je amper power voor een aa-pad én een bb-pad — laat staan voor een product. Mediation hoort bij grotere studies met goed design.

Inzicht. Mediation is een dure techniek qua causale aannamen. Reserveer hem voor onderzoek waar je theoretisch een keten verwacht, je XX, MM, YY in tijd uit elkaar liggen, en je nn ruim genoeg is. Bij twijfel: beschrijvende statistiek + meervoudige regressie zonder mediation-pretentie.

Examen-stijl vragen

Vier kortere oefeningen plus één mini-practical

OpmerkingVraag E1 — Uitvoer van de Aroian-toets interpreteren

In een mediation-analyse rapporteert een onderzoeker:

$ab    = 0.42
$SE_ab = 0.12
$z     = 3.50
$p     = .0005

Welke conclusie volgt hieruit?

  1. Het indirect-effect via MM is significant. De mediator draagt aantoonbaar bij aan het pad van XX naar YY.
  2. De mediator verklaart 42%42\% van de variantie in YY.
  3. Het direct-effect is significant.
  4. De zz-toets is niet geldig omdat we niets weten over normaliteit van âb̂\hat{a}\hat{b}.

a) Aroian-toets significant (z=3.50z = 3.50, p<.001p < .001) → H0H_0: a⋅b=0a \cdot b = 0 verworpen. Indirect-effect via MM is groter dan nul. Wel of geen direct-effect zegt deze uitvoer niet — daarvoor heb je ĉ′\hat{c}' nodig.

Optie b is een misvatting (âb̂=0.42\hat{a}\hat{b} = 0.42 is een regressiecoëfficiënt-product, geen variantie-percentage). Optie c kan niet worden geconcludeerd uit deze uitvoer. Optie d klopt deels (de Aroian-toets is een normaal-benadering en bij scheve verdelingen onbetrouwbaar), maar bij z=3.50z = 3.50 en p<.001p < .001 is dat zorg-punt klein — de conclusie blijft houdbaar.

OpmerkingVraag E2 — Decompositie handrekenen

Een mediation-analyse geeft: â=0.30\hat{a} = 0.30, b̂=0.50\hat{b} = 0.50, ĉ=0.20\hat{c} = 0.20. Bereken ĉ′\hat{c}'.

  1. ĉ′=0.05\hat{c}' = 0.05
  2. ĉ′=0.15\hat{c}' = 0.15
  3. ĉ′=0.35\hat{c}' = 0.35
  4. ĉ′=−0.50\hat{c}' = -0.50

a) Decompositie: ĉ=ĉ′+âb̂\hat{c} = \hat{c}' + \hat{a}\hat{b}, dus ĉ′=ĉ−âb̂=0.20−(0.30⋅0.50)=0.20−0.15=0.05\hat{c}' = \hat{c} - \hat{a}\hat{b} = 0.20 - (0.30 \cdot 0.50) = 0.20 - 0.15 = 0.05.

Notabene: âb̂=0.15\hat{a}\hat{b} = 0.15, ĉ′=0.05\hat{c}' = 0.05, dus de proportie mediated =0.15/0.20=75%= 0.15 / 0.20 = 75\%. Substantiële mediation, hoewel niet volledig.

OpmerkingVraag E3 — Patroon herkennen

Een onderzoeker rapporteert: â=+0.50\hat{a} = +0.50, b̂=−0.40\hat{b} = -0.40, ĉ′=+0.40\hat{c}' = +0.40, ĉ=+0.20\hat{c} = +0.20. Welk patroon hoort hierbij?

  1. Consistente partiële mediation; alle paden in dezelfde richting.
  2. Volledige mediation; ĉ′≈0\hat{c}' \approx 0.
  3. Inconsistente mediation (suppressie); âb̂\hat{a}\hat{b} en ĉ′\hat{c}' tegengesteld in teken.
  4. Het patroon is wiskundig onmogelijk; ĉ\hat{c} moet groter zijn dan ĉ′\hat{c}'.

c) âb̂=0.50⋅(−0.40)=−0.20\hat{a}\hat{b} = 0.50 \cdot (-0.40) = -0.20 (negatief). ĉ′=+0.40\hat{c}' = +0.40 (positief). Tegengestelde tekens — inconsistente mediation. |ĉ|=0.20<|ĉ′|=0.40|\hat{c}| = 0.20 < |\hat{c}'| = 0.40 — klassiek suppressor-symptoom. De decompositie controleert: ĉ′+âb̂=0.40−0.20=0.20=ĉ\hat{c}' + \hat{a}\hat{b} = 0.40 - 0.20 = 0.20 = \hat{c}. ✓

Optie a is fout (tekens niet allemaal gelijk). Optie b is fout (ĉ′=+0.40\hat{c}' = +0.40 is niet bij nul). Optie d is fout (wiskundig kan ĉ\hat{c} kleiner zijn dan ĉ′\hat{c}' bij suppressie).

OpmerkingVraag E4 — Volledige of partiële?

Een onderzoeker vindt: ĉ=0.45\hat{c} = 0.45 (p<.001p < .001), ĉ′=0.05\hat{c}' = 0.05 (p=.54p = .54), âb̂=0.40\hat{a}\hat{b} = 0.40 met Aroian-z=4.20z = 4.20 (p<.001p < .001). Welk patroon?

  1. Volledige mediation — ĉ′\hat{c}' niet meer significant na controle voor MM, het hele effect loopt via MM.
  2. Partiële mediation — er is nog een direct-effect ĉ′=0.05\hat{c}' = 0.05.
  3. Suppressie — tekens van âb̂\hat{a}\hat{b} en ĉ′\hat{c}' verschillen.
  4. Geen mediation — ĉ′\hat{c}' is niet nul.

a) Klassiek volledig: ĉ′\hat{c}' klein én niet-significant, terwijl ĉ\hat{c} en âb̂\hat{a}\hat{b} wel significant zijn. Het hele effect loopt via MM. Decompositie: 0.05+0.40=0.450.05 + 0.40 = 0.45 ✓.

Optie b verwart “klein” met “significant”; bij p=.54p = .54 is ĉ′=0.05\hat{c}' = 0.05 niet onderscheidbaar van nul. Optie c is fout (tekens zijn beide positief). Optie d is fout (de praktische definitie van volledige mediation is precies dit patroon).

R-practical opdrachtje

De pissebed onder de steen

OpmerkingVraag E5 — Mini-mediation bij de pissebed

Een ecoloog onderzoekt 7070 pissebedden. Hypothese: hoeveel licht een pissebed ervaart (XX = licht_blootstelling, schaal 00-100100) wekt een innerlijk stress-signaal op (MM = stress_signaal, schaal 00-100100), wat de tijd dat de pissebed zich onder de steen verstopt verlengt (YY = verstoptijd, schaal 00-100100). De dataset staat in data/pissebed_keuzes.RData en bevat het object pissebed_keuzes met kolommen pissebed_id, licht_blootstelling, stress_signaal, verstoptijd. Sla je R-commando’s op in één scriptbestand: pissebed.R. Gebruik α=.05\alpha = .05.

a) Verken de data: gemiddelden, SD’s, correlaties tussen XX, MM, YY. Past het patroon bij een mediation-keten?

b) Schat de drie regressies (Y ~ X, M ~ X, Y ~ X + M). Geef ĉ\hat{c}, â\hat{a}, b̂\hat{b} en ĉ′\hat{c}' met SESE.

c) Voer de Aroian-toets met de hand uit. Wat is âb̂\hat{a}\hat{b}, wat is de Aroian-zz, en wat is pp?

d) Welke conclusie trek je: volledig, partieel, of suppressie? Schrijf één APA-zin met je conclusie.

load("data/pissebed_keuzes.RData")
str(pissebed_keuzes)
'data.frame':   70 obs. of  4 variables:
 $ pissebed_id        : Factor w/ 70 levels "p01","p02","p03",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ licht_blootstelling: num  19.6 42.9 53.3 38.7 48.7 ...
 $ stress_signaal     : num  45.3 66.4 41.4 21.9 39.3 ...
 $ verstoptijd        : num  25.9 43.6 36.8 38.3 51.8 ...
round(sapply(pissebed_keuzes[, c("licht_blootstelling",
                                  "stress_signaal",
                                  "verstoptijd")], mean), 2)
licht_blootstelling      stress_signaal         verstoptijd 
              49.74               41.49               37.84 
round(sapply(pissebed_keuzes[, c("licht_blootstelling",
                                  "stress_signaal",
                                  "verstoptijd")], sd),   2)
licht_blootstelling      stress_signaal         verstoptijd 
              15.14               13.38               12.27 
round(cor(pissebed_keuzes[, c("licht_blootstelling",
                              "stress_signaal",
                              "verstoptijd")]), 3)
                    licht_blootstelling stress_signaal verstoptijd
licht_blootstelling               1.000          0.455       0.433
stress_signaal                    0.455          1.000       0.519
verstoptijd                       0.433          0.519       1.000
pissebed_keuzes |>
  summarise(across(c(licht_blootstelling, stress_signaal, verstoptijd), mean)) |>
  round(2)
  licht_blootstelling stress_signaal verstoptijd
1               49.74          41.49       37.84
pissebed_keuzes |>
  summarise(across(c(licht_blootstelling, stress_signaal, verstoptijd), sd)) |>
  round(2)
  licht_blootstelling stress_signaal verstoptijd
1               15.14          13.38       12.27
pissebed_keuzes |>
  select(licht_blootstelling, stress_signaal, verstoptijd) |>
  cor() |>
  round(3)
                    licht_blootstelling stress_signaal verstoptijd
licht_blootstelling               1.000          0.455       0.433
stress_signaal                    0.455          1.000       0.519
verstoptijd                       0.433          0.519       1.000
fit_total_p <- lm(verstoptijd ~ licht_blootstelling,
                  data = pissebed_keuzes)
fit_a_p     <- lm(stress_signaal ~ licht_blootstelling,
                  data = pissebed_keuzes)
fit_bc_p    <- lm(verstoptijd ~ licht_blootstelling + stress_signaal,
                  data = pissebed_keuzes)

round(summary(fit_total_p)$coefficients, 4)
                    Estimate Std. Error t value Pr(>|t|)
(Intercept)          20.3898     4.6038  4.4289   0.0000
licht_blootstelling   0.3509     0.0886  3.9603   0.0002
round(summary(fit_a_p)$coefficients,    4)
                    Estimate Std. Error t value Pr(>|t|)
(Intercept)          21.4807     4.9579  4.3326   0.0000
licht_blootstelling   0.4023     0.0954  4.2165   0.0001
round(summary(fit_bc_p)$coefficients,   4)
                    Estimate Std. Error t value Pr(>|t|)
(Intercept)          12.3965     4.8001  2.5825   0.0120
licht_blootstelling   0.2012     0.0919  2.1902   0.0320
stress_signaal        0.3721     0.1039  3.5803   0.0006
a_p    <- coef(fit_a_p)[["licht_blootstelling"]]
b_p    <- coef(fit_bc_p)[["stress_signaal"]]
se_a_p <- summary(fit_a_p)$coefficients["licht_blootstelling", "Std. Error"]
se_b_p <- summary(fit_bc_p)$coefficients["stress_signaal",     "Std. Error"]

se_ab_p <- sqrt(b_p^2 * se_a_p^2 + a_p^2 * se_b_p^2 + se_a_p^2 * se_b_p^2)
z_p     <- (a_p * b_p) / se_ab_p
p_p     <- 2 * (1 - pnorm(abs(z_p)))

round(c(a = a_p, b = b_p, ab = a_p * b_p, se_ab = se_ab_p, z = z_p, p = p_p), 4)
     a      b     ab  se_ab      z      p 
0.4023 0.3721 0.1497 0.0557 2.6856 0.0072 

a) MX=49.74M_X = 49.74 (SD=15.14SD = 15.14), MM=41.49M_M = 41.49 (SD=13.38SD = 13.38), MY=37.84M_Y = 37.84 (SD=12.27SD = 12.27). Correlaties: rXM=.455r_{XM} = .455, rMY=.519r_{MY} = .519, rXY=.433r_{XY} = .433. Alle drie matig-positief — past bij een mediation-keten.

b) ĉ=0.351\hat{c} = 0.351, SE=0.089SE = 0.089, t(68)=3.96t(68) = 3.96, p<.001p < .001. â=0.402\hat{a} = 0.402, SE=0.095SE = 0.095, t(68)=4.22t(68) = 4.22, p<.001p < .001. b̂=0.372\hat{b} = 0.372, SE=0.104SE = 0.104, t(67)=3.58t(67) = 3.58, p<.001p < .001. ĉ′=0.201\hat{c}' = 0.201, SE=0.092SE = 0.092, t(67)=2.19t(67) = 2.19, p=.032p = .032.

c) Uit de uitvoer, afgerond op vier decimalen: â=0.4023\hat{a} = 0.4023 met 𝑆𝐸a=0.0954\mathit{SE}_a = 0.0954, en b̂=0.3721\hat{b} = 0.3721 met 𝑆𝐸b=0.1039\mathit{SE}_b = 0.1039. Dan is âb̂=0.4023⋅0.3721=0.1497\hat{a}\hat{b} = 0.4023 \cdot 0.3721 = 0.1497. De drie termen onder de wortel:

b̂2𝑆𝐸a2=0.37212⋅0.09542=0.001260â2𝑆𝐸b2=0.40232⋅0.10392=0.001747𝑆𝐸a2𝑆𝐸b2=0.09542⋅0.10392=0.000098 \begin{aligned} \hat{b}^2\,\mathit{SE}_a^2 &= 0.3721^2 \cdot 0.0954^2 = 0.001260 \\ \hat{a}^2\,\mathit{SE}_b^2 &= 0.4023^2 \cdot 0.1039^2 = 0.001747 \\ \mathit{SE}_a^2\,\mathit{SE}_b^2 &= 0.0954^2 \cdot 0.1039^2 = 0.000098 \end{aligned}

Samen 0.0031050.003105, dus 𝑆𝐸ab=0.05572\mathit{SE}_{ab} = 0.05572 en z=0.1497/0.05572=2.69z = 0.1497 / 0.05572 = 2.69, p=.007p = .007. Het indirecte effect is significant.

d) Partiële mediation: ĉ′\hat{c}' blijft significant (p=.032p = .032) maar is duidelijk gedaald van ĉ=0.351\hat{c} = 0.351 naar ĉ′=0.201\hat{c}' = 0.201. Decompositie: ĉ′+âb̂=0.201+0.150=0.351=ĉ\hat{c}' + \hat{a}\hat{b} = 0.201 + 0.150 = 0.351 = \hat{c} ✓. Proportie mediated: âb̂/ĉ=0.150/0.351\hat{a}\hat{b} / \hat{c} = 0.150 / 0.351, ongeveer 43%. Een deel loopt via stress, een deel rechtstreeks.

Een mediation-analyse op N=70N = 70 pissebedden onderzocht of het stresssignaal de relatie tussen lichtblootstelling en verstoptijd bemiddelt. Het totaal-effect was significant, ĉ=0.351\hat{c} = 0.351, SE=0.089SE = 0.089, t(68)=3.96t(68) = 3.96, p<.001p < .001. Na opname van de mediator was het direct-effect afgenomen maar nog steeds significant, ĉ′=0.201\hat{c}' = 0.201, SE=0.092SE = 0.092, t(67)=2.19t(67) = 2.19, p=.032p = .032. De Aroian-toets bevestigde een significant indirect effect, âb̂=0.150\hat{a}\hat{b} = 0.150, SE=0.056SE = 0.056, z=2.69z = 2.69, p=.007p = .007. Het patroon wijst op partiële mediation: ongeveer 43% van het effect van lichtblootstelling op verstoptijd loopt via het stresssignaal.

R-spiekblad — mediation in acht stappen

Achterop in de map, voor als je het kwijt bent

# 1. Pakketten + data laden ---------------------------------------------
library(tidyverse)
library(bda)        # Aroian-toets als controle
options(contrasts = c("contr.sum", "contr.poly"))

load("data/slak_ontmoetingen.RData")
str(slak_ontmoetingen)

# 2. Verkenning ---------------------------------------------------------
# Means + SD's per variabele.
sapply(slak_ontmoetingen[, c("eerdere_afwijzing",
                             "sociale_voorzichtigheid",
                             "ontmoetingstraagheid")], mean)
sapply(slak_ontmoetingen[, c("eerdere_afwijzing",
                             "sociale_voorzichtigheid",
                             "ontmoetingstraagheid")], sd)
cor(slak_ontmoetingen[, c("eerdere_afwijzing",
                          "sociale_voorzichtigheid",
                          "ontmoetingstraagheid")])

# Scatter-matrix.
pairs(slak_ontmoetingen[, c("eerdere_afwijzing",
                            "sociale_voorzichtigheid",
                            "ontmoetingstraagheid")])

# 3. Drie regressies — Baron-Kenny stappen ------------------------------
fit_total <- lm(ontmoetingstraagheid ~ eerdere_afwijzing,
                data = slak_ontmoetingen)
fit_a     <- lm(sociale_voorzichtigheid ~ eerdere_afwijzing,
                data = slak_ontmoetingen)
fit_bc    <- lm(ontmoetingstraagheid ~ eerdere_afwijzing + sociale_voorzichtigheid,
                data = slak_ontmoetingen)

summary(fit_total)$coefficients
summary(fit_a)$coefficients
summary(fit_bc)$coefficients

# 4. Decompositie-controle c = c' + a*b --------------------------------
a_hat   <- coef(fit_a)["eerdere_afwijzing"]
b_hat   <- coef(fit_bc)["sociale_voorzichtigheid"]
c_prime <- coef(fit_bc)["eerdere_afwijzing"]
c_total <- coef(fit_total)["eerdere_afwijzing"]

c_check <- c_prime + a_hat * b_hat
all.equal(c_check, c_total)   # TRUE bij dezelfde N en geen missings

# 5. Aroian-toets met de hand -------------------------------------------
se_a <- summary(fit_a)$coefficients["eerdere_afwijzing", "Std. Error"]
se_b <- summary(fit_bc)$coefficients["sociale_voorzichtigheid", "Std. Error"]

# Drie termen onder de wortel; let op het kruis: b bij se_a, a bij se_b.
se_ab    <- sqrt(b_hat^2 * se_a^2 + a_hat^2 * se_b^2 + se_a^2 * se_b^2)
z_aroian <- (a_hat * b_hat) / se_ab
p_aroian <- 2 * (1 - pnorm(abs(z_aroian)))
c(z = z_aroian, p = p_aroian)

# 6. Aroian-toets via pakket — controle (lees de kolom Aroian) ----------
# library(bda)
# bda::mediation.test(
#   mv = slak_ontmoetingen$sociale_voorzichtigheid,
#   iv = slak_ontmoetingen$eerdere_afwijzing,
#   dv = slak_ontmoetingen$ontmoetingstraagheid
# )

# 7. Suppressie / inconsistente mediation: tekens-check ----------------
# Bij a*b en c' tegengesteld in teken: inconsistente mediation.
sign(a_hat * b_hat) == sign(c_prime)  # TRUE = consistent, FALSE = suppressie

# 8. Visualisatie -------------------------------------------------------
# Pad-diagram: drie boxen (X, M, Y) met pijlen en geschatte coëfficiënten.
# Niet één base-R-functie; teken zelf met rect() + arrows() of via
# DiagrammeR / ggdag voor pakket-routes.

Uitbreidingen uit MacKinnon, Fairchild en Fritz (2007)

Het idee wel, het rekenen niet

MacKinnon, Fairchild en Fritz (2007) geven een overzicht van mediation-analyse. Naast het model met één mediator beschrijven ze kort een rij uitbreidingen, en de vraag wanneer je een indirect effect als oorzaak mag lezen. Het idee erachter is goed om te kennen; rekenen doe je in dit oefenboek alleen met één mediator en de Aroian-toets.

  • Bootstrap — trek uit je eigen data duizenden nieuwe steekproeven, reken in elke steekproef âb̂\hat{a}\hat{b} uit, en neem als interval het middelste stuk waar 95% van al die uitkomsten in valt. Zo’n interval mag scheef zijn, en dat past bij âb̂\hat{a}\hat{b}: het product van twee schattingen is zelf niet normaal verdeeld. Daarom raadt het artikel het aan boven het symmetrische interval van de Aroian-toets.
  • Meerdere mediators — het effect van XX op YY loopt via twee of meer tussenstappen tegelijk, elk met een eigen indirect effect. Zie Multiple mediators.
  • Moderated mediation — het indirecte effect van XX op YY verandert in grootte met het niveau van een vierde variabele, de moderator. Wat mediation van moderation onderscheidt, staat bij Mediatie ≠ moderatie.
  • Een categorische uitkomst — is YY binair, dan voorspel je YY met een logistische regressie, en dan is ĉ\hat{c} niet meer zomaar gelijk aan ĉ′+âb̂\hat{c}' + \hat{a}\hat{b}: de schaal van YY valt in elke logistische regressie een beetje anders uit.
  • Multilevel mediation — de metingen zijn genest: leerlingen in klassen, of herhaalde metingen binnen één persoon. Wie die nesting negeert, vindt te vaak een significant indirect effect van XX op YY dat in de populatie niet bestaat.
  • Causale interpretatie — wanneer mag je het indirecte effect van XX op YY als oorzaak lezen? Het artikel noemt daarvoor het causale model van Rubin: vergelijk wat er met dezelfde persoon gebeurt bij twee verschillende waarden van XX. Die vergelijking kun je nooit helemaal maken, want iedereen heeft maar één waarde van XX. Deze vraag hoort bij de aannames onder Wat mediation-analyse niet bewijst.

Wat blijft liggen

Waar je hierna verder kunt lezen

Mediation via de stappen van Baron en Kenny plus de Aroian-toets is de hoofdingang. Wat dit oefenboek je gaf is genoeg voor de gangbare onderzoeks-rapportage. Wat hieronder staat, is voor wie verder wil. Wie de uitbreidingen hierboven zelf wil doorrekenen, doet dat met een pakket:

  • Bootstrap-mediation — Hayes’ PROCESS-macro of mediation::mediate(boot = TRUE). Modern de aanbevolen route in publicaties.
  • Multiple mediators — pakket mediation of lavaan voor pad-analyse. De decompositie generaliseert: ĉ=ĉ′+∑kâkb̂k\hat{c} = \hat{c}' + \sum_k \hat{a}_k \hat{b}_k.
  • Moderated mediation — Hayes (2018, hoofdstukken 8–9); lavaan of PROCESS-modellen 7, 14, 15.
  • Logistic mediation — specifieke methoden (MacKinnon, 2008, hoofdstuk 11; logistic-mediation libraries).
  • Multilevel mediation — random-intercept-modellen via lme4 plus mediation-extensie. Pakket mediation ondersteunt dit.
  • Causal mediation in counterfactual frame — VanderWeele (2015) en Imai et al. (2010) werken het causale model uit tot een eigen schatting van het indirecte effect, met expliciete identificatie-aannames. Het methodologisch state-of-the-art.

Voor verdieping: Hayes (2018, Introduction to Mediation, Moderation, and Conditional Process Analysis); MacKinnon (2008, Introduction to Statistical Mediation Analysis); MacKinnon, Krull en Lockwood (2000, Equivalence of the Mediation, Confounding and Suppression Effect).

Aan het eind van de dag

Toen de zon onderging boven het blad, klapte de slak zijn schrift dicht.

“Drie variabelen, drie regressies, één product,” zei hij. “En het stokje liep van eerdere afwijzing via sociale voorzichtigheid naar ontmoetingstraagheid. Bijna helemaal via, nauwelijks rechtstreeks.”

“En als de tussen-slak het stokje de andere kant op had gedragen?” vroeg de pissebed, die zoals altijd langs kwam.

“Dan was het totaal-effect kleiner geweest dan het direct-effect,” zei de slak. “Dan had de tussen-slak gewerkt als een rem, niet als een boodschapper. Dat heet suppressie.” Hij wachtte even. “Of inconsistente mediation, als je het mooi wilt zeggen.”

“En de Aroian-toets?”

“Vier-komma-zes-zes,” zei de slak. “Sterk significant. Het indirect-effect is geen ruis.”

“En morgen?”

“Morgen tellen we weer,” zei de slak. “Misschien een andere mediator. Of dezelfde, maar op andere slakken. De estafette blijft.”

De pissebed knikte en kroop verder onder zijn steen. Boven het blad werd het donker, en de slak liet zijn voeler langzaam intrekken tot wat de schemer ervan maakte.

Verantwoording

Dit oefenboek is geschreven voor studenten die mediation-analyse leren via R. De didactische lijnen volgen de gangbare opbouw van Nederlandse universitaire MVDA-cursussen; alle voorbeelden, datasets, vragen en formuleringen in dit hoofdstuk zijn origineel. De gebruikte drempels en formules zijn standaard statistische conventies; verwijzingen naar Baron en Kenny (1986), Sobel (1982), Aroian (1944), Goodman (1960), Conger (1974), MacKinnon, Krull en Lockwood (2000), MacKinnon, Fairchild en Fritz (2007), MacKinnon (2008), Hayes (2018), Tzelgov en Henik (1991), Pearl (2009), VanderWeele (2015) en Imai et al. (2010) volgen de gebruikelijke citaatpraktijk in dit veld.

Versie: October 2026 — CountCamp Lab

Terug naar boven