Hoofdstuk 9 · De t-toets

Bestaat het verschil echt? · paired & independent t-test

De prikkel

Twee kleine raadsels, allebei over hetzelfde woord: verschil.

Het eerste is meer dan honderd jaar oud.1 Tien mensen krijgen twee nachten lang elk een ander slaapmiddel, en iemand meet hoeveel uur extra slaap ze ervan krijgen. Middel A levert gemiddeld 0.75 uur op, middel B 2.33 uur. Middel B wint dus met 1.58 uur. Maar het zijn er maar tien, en mensen slapen de ene nacht nu eenmaal anders dan de andere. Is die 1.58 uur een echt verschil tussen de middelen — of hadden we gewoon een paar goede nachten voor B?

Het tweede raadsel staat op een rots bij Antarctica.2 Gentoo-pinguïns wegen gemiddeld 5076 gram, Adélies 3701 gram. Dat is 1375 gram verschil — anderhalve kilo, een flink beest lichter. Maar we hebben niet álle pinguïns gewogen, alleen degene die we toevallig oppakten. Is die 1375 gram het échte soortverschil, of hadden we pech (of geluk) met wie er in onze armen belandde?

Dezelfde vraag, twee keer: bestaat het verschil echt, of danst het op toeval? En let straks op iets moois — bij de pinguïns wordt het antwoord zó overweldigend dat de interessante vraag verschuift. Trek even mee.

Speel het

⬇ Download de data — slaap_middelen.csv

⬇ Download de data — penguins.csv

Twee raadsels, twee toetsen — en het verschil zit in het design. Bij de slaapmiddelen meten we dezelfde tien mensen twee keer; die twee kolommen horen per rij bij elkaar. Dat vraagt een gepaarde t-toets (paired). Bij de pinguïns hebben we twee losse groepen dieren, geen koppels — dat vraagt een onafhankelijke t-toets (independent). Doe ze allebei.

OpmerkingIn R · trek aan de slaapmiddelen (gepaard)
slaap <- read.csv("slaap_middelen.csv")

mean(slaap$slaap_middelA)                                  # → 0.75 uur
mean(slaap$slaap_middelB)                                  # → 2.33 uur

t.test(slaap$slaap_middelA, slaap$slaap_middelB, paired = TRUE)
# verschil A - B = -1.58 u,  t(9) = -4.06,  p = 0.003
# 95%-CI [-2.46, -0.70]

Het min-teken zegt alleen dat A mínder oplevert dan B; de grootte is 1.58 uur. De p van 0.003 zegt: als de twee middelen in werkelijkheid even goed waren, zou je zó’n verschil bij tien mensen zelden per ongeluk tegenkomen. En dat interval [−2.46, −0.70] is eerlijker dan de p: het beste dat je over het echte verschil durft te zeggen is “ergens tussen 0.70 en 2.46 uur in B’s voordeel”. Klein onderzoek, breed interval — het interval is meteen zijn eigen slag om de arm.

OpmerkingIn R · trek aan de pinguïns (onafhankelijk)
peng <- read.csv("penguins.csv")
ga   <- peng[peng$soort %in% c("Gentoo", "Adelie"), ]   # twee soorten

tapply(ga$gewicht, ga$soort, mean)                       # Adelie 3701, Gentoo 5076

t.test(gewicht ~ soort, data = ga)
# verschil ~ 1375 g,  t ~ -23.6,  p < .001
# 95%-CI van het verschil ~ [1261, 1490] g

Kijk eens naar die t van −23.6. Bij de slaapmiddelen was het −4.06 en dat vonden we al overtuigend; hier is-ie bijna zes keer zo groot. De p is zó klein dat R ’m niet eens meer voluit schrijft (< 2.2e-16). Onthoud dat cijfer even — in “Snap het” blijkt het minder indrukwekkend dan het lijkt.

Schud het

Nu de vraag die telt: bestaat het verschil écht? We gaan het toeval nabouwen. De truc is telkens dezelfde, en hij is mooi: we bouwen duizend werelden waarin de waarheid nul is — waarin er per definitie géén verschil bestaat — en kijken hoe ver puur geluk het gemeten verschil dan tóch van nul wegtrekt. In geen enkele van die werelden meet je precies nul; het toeval laat het verschil dansen om nul. Die dans is een bergje. Ligt jouw echte verschil ín het bergje, dan kan toeval het verklaren. Ligt het erbuiten, dan is het echt.

Bij de pinguïns bouw je die nul-werelden door de soort-labels te husselen. Je houdt alle gewichten precies zoals ze zijn, maar je plakt er lukraak “Gentoo” of “Adélie” op. In zo’n wereld zegt de soort niets meer over het gewicht — het echte soortverschil is nul. En dan meet je toch, elke keer, een verschil, puur door wie er toevallig welk label kreeg.

OpmerkingIn R · hussel de soort-labels (1000 nul-werelden)
echt <- mean(ga$gewicht[ga$soort == "Gentoo"]) -
        mean(ga$gewicht[ga$soort == "Adelie"])            # 1375 g

set.seed(42)
nul <- replicate(1000, {
  door_elkaar <- sample(ga$soort)                          # labels husselen
  mean(ga$gewicht[door_elkaar == "Gentoo"]) -
  mean(ga$gewicht[door_elkaar == "Adelie"])
})

hist(nul)                                                  # het toeval-bergje rond 0
abline(v = echt, col = "red", lwd = 2)                     # en dáár staat 1375
range(nul)                                                 # → ongeveer -386 tot 367

Kijk naar dat bergje. Duizend werelden waarin soort er niet toe doet, en het toeval komt niet verder dan zo’n 386 gram van nul — een klein beetje geschommel. En dan die rode streep op 1375, kilometers rechts van het hele bergje. Geen enkele van de duizend nul-werelden haalt jouw verschil, of komt zelfs maar in de buurt. Dát is “geen toeval”: geen p-waarde die je moet geloven, maar een afstand die je zíet.

Bij de slaapmiddelen hoort een ándere schud-zet, want het design is anders. Daar zijn geen twee groepen om te husselen — er zijn tien personen, elk met hun eigen verschil (A minus B). De nul-wereld is hier: het maakt niet uit welk middel je A en welk je B noemt. Dus voor elke persoon gooien we een muntje dat bepaalt of zijn verschil met een plus of een min meetelt. Duizend keer.

OpmerkingIn R · draai per persoon het teken (1000 nul-werelden)
verschil <- slaap$slaap_middelA - slaap$slaap_middelB      # 10 verschillen
echt_gem <- mean(verschil)                                 # -1.58 u

set.seed(42)
nul <- replicate(1000, {
  munt <- sample(c(-1, 1), length(verschil), replace = TRUE)
  mean(verschil * munt)                                    # teken lukraak omgooien
})

hist(nul)                                                  # bergje rond 0
abline(v = echt_gem, col = "red", lwd = 2)                 # -1.58 aan de rand

Ook hier danst het toeval om nul, en de echte −1.58 uur ligt aan de uiterste rand — met tien muntjes komt het geluk daar bijna nooit. Twee designs, twee manieren van husselen, één idee: duizend werelden waarin de waarheid nul is, maar het gemeten verschil nooit precies nul. De toets vertelt je hoe raar jouw verschil zou zijn als er niks was.

Snap het

Allebei de verschillen zijn dus echt, geen toeval. Maar “echt” is niet hetzelfde als “belangrijk”, en juist de pinguïns laten dat scherp zien.

Herinner je die t van −23.6 en de p die niet meer op het scherm paste? Die duizelingwekkende getallen betekenen niet dat het pinguïn-verschil belangrijker is dan het slaap-verschil. Ze zijn zo groot om twee saaie redenen: het verschil is bruut (anderhalve kilo) én we hebben veel dieren (274 stuks). Een t-toets straft kleine steekproeven af en beloont grote; gooi er genoeg waarnemingen in en zelfs een schamel verschil wordt “hoogsignificant”. Bij een groot, duidelijk verschil met een royale N is significantie triviaal — de toets bevestigt alleen wat je met het blote oog al zag. De interessante vraag is dan niet óf er verschil is, maar hoe groot.

Daarvoor bestaat de effectgrootte (effect size) — een verschil losgemaakt van de steekproefgrootte. Voor twee groepen is dat Cohens d: het verschil uitgedrukt in standaarddeviaties.

OpmerkingIn R · hoe groot is groot? (Cohens d)
# Cohens d: verschil in gewicht, gedeeld door de gepoolde spreiding
library(effectsize)                # of reken 'm met de hand uit de SD's
cohens_d(gewicht ~ soort, data = ga)      # → d ~ 2.87

d = 2.87. Dat is enorm — de twee soorten liggen bijna drie standaarddeviaties uit elkaar; wijs een willekeurige Gentoo en een willekeurige Adélie aan en de Gentoo is vrijwel altijd zwaarder. Dáár zit het echte verhaal, niet in de t.

En de slaapmiddelen, met hun bescheiden N van 10? De effectgrootte voor een gepaard verschil heet dz, en die is hier −1.28 — ook fors. Het verschil tussen A en B is meer dan één standaarddeviatie groot. Klein onderzoek, maar geen klein effect. Precies het omgekeerde plaatje van de pinguïns: daar was de t spectaculair en het nieuws de grootte; hier is de t bescheiden en is de grootte nog steeds het nieuws.

De les van dit blok, in drie zinnen:

  • Het design kiest de toets. Dezelfde mensen twee keer gemeten → gepaard. Twee losse groepen → onafhankelijk. Dat is geen smaak maar een feit over je data.
  • Significant zegt “waarschijnlijk niet nul”, niet “groot”. Bij veel data is significantie goedkoop; laat je niet imponeren door een t van 23.
  • De grootte is de vraag die overblijft. Rapporteer altijd een effectgrootte naast de toets — d, een interval, of gewoon het verschil in gewone eenheden (uren, grammen). Dát is wat een mens wil weten.

Zou je het in één eerlijke zin opschrijven: niet “het verschil is significant (p < .001)”, maar Gentoo’s zijn gemiddeld 1375 gram zwaarder dan Adélies (95%-CI [1261, 1490]), een zeer groot effect (d = 2.87). Het getal met een maat eromheen, niet een sterretje.

Zelfde vorm in het boek

Hier: twee groepen (of twee metingen), één verschil, en de vraag of dat verschil het toeval overleeft — plus hoe groot het eigenlijk is.

In het boek: W6 — Bestaat het verschil echt?

Daar komt de toets pas ná het interval en na de simulatie: eerst vóélen hoe ver toeval reikt, dan pas de vraag “stel dat er niks was”.

TODO (broertje-proof, 24-7, geschreven op het charter): W6 (Bestaat het verschil echt?) is nog een grove boek-schets — anker en formulering checken zodra dat hoofdstuk staat. Verhaal-stem-opening is een eerste stem-pas; kan nog stiller. Cohens d gebruikt effectsize::cohens_d — checken of dat pakket in de broertje-onboarding zit, anders met-de-hand-variant tonen. De JASP-tweeling deelt deze tekst; alleen “Speel het / Schud het” verschilt (JASP kan het husselen niet zelf → speeltje + hop).

Voetnoten

  1. Cushny & Peebles (1905), het klassieke slaapmiddelen-experiment — dezelfde data waarop Student in 1908 zijn t-verdeling demonstreerde. slaap_middelen.csv, 10 personen. Alle getallen nagerekend.↩︎

  2. Palmer Penguins — Gorman, Williams & Fraser (2014), Palmer Station Antarctica LTER; via het R-pakket palmerpenguins (CC0). penguins.csv. Alle getallen op die échte data nagerekend.↩︎