2. Reliability — Cronbach’s α, split-half en wat er overblijft

Het verhaal van dit thema

De wezel was nuchter, zoals altijd.

“Tien items,” zei hij, “en jij noemt dat een schaal.”

“Bos-Piekeren-Schaal,” zei de kraai. “Tien vragen. Eén score per dier.”

“Cronbach?”

“Komt eraan. Daarom zijn we hier.”

De wezel kruiste twee voorpoten. Hij was niet onder de indruk, maar hij was ook niet ongeïnteresseerd. Dat was zijn ding. “Eerst zien.”

“Als alpha onder de zeventig is,” zei hij, “ga ik weg.”

Tweehonderd bosdieren in dit thema. Tien items op een 55-puntsschaal, samen de Bos-Piekeren-Schaal (BPS). Daarnaast twee kleine datasets: 70 pissebedden op een zes-item emotie-regulatie-schaal voor een mini-practical, en 143 egels op een zes-item doorzet-schaal, die bij de item-deletie naast de bosdieren komt te liggen.

In thema 1 leerde je wat scores betekenen (norm-scoren, T-scores, percentielen). Nu de vraag eronder: meet die schaal überhaupt iets consistents?

Drie hoofdvragen:

  1. Hangen de items samen? — Cronbach’s α\alpha, item-totaal-correlaties.
  2. Welke twee helften van de schaal zeggen hetzelfde? — split-half + Spearman-Brown.
  3. Welke items kunnen weg? — item-deletie-analyse, en wanneer het antwoord nee is.
OpmerkingA. Wat is reliability?

Betrouwbaarheid reliability = de mate waarin een meting consistent is. Meet je hetzelfde nog een keer, onder dezelfde omstandigheden — krijg je dan hetzelfde getal?

Om dat na te gaan heb je twee metingen nodig die je eerlijk naast elkaar mag leggen. Zulke metingen heten parallel: ze meten allebei even goed hetzelfde onderliggende ding. Dat onderliggende ding heet de ware score — wat je zou meten als je instrument geen enkele ruis had. Het addertje: die ware score kun je niet zien, want je hebt alleen je meting. Of twee metingen écht parallel zijn weet je dus nooit zeker — je schat het. Vandaar drie manieren om aan die twee metingen te komen, elk met een eigen zwakke plek:

  • Parallelle vormen alternate forms — twee losse testen die hetzelfde meten, allebei afgenomen. Correleren de scores? Zwakke plek: dát ze parallel zijn is een aanname, geen meting.
  • Test-hertest test-retest — één test, twee momenten, dezelfde personen. Pearson-rr tussen meting 1 en 2. Zwakke plek: de tweede keer is de eerste keer nog niet vergeten. Wie zich zijn antwoord herinnert, herhaalt het — inclusief de vergissing die hij de eerste keer maakte. De test lijkt daardoor stabieler dan hij is, en je schat de betrouwbaarheid te hoog.
  • Split-half — één test, één moment, in twee helften geknipt. Zwakke plek: je meet zo de betrouwbaarheid van een hálve test, en een kortere test is altijd minder betrouwbaar: minder items betekent minder gelegenheid om toevallige missers tegen elkaar weg te middelen. Spearman-Brown rekent daarom terug naar de volle lengte.

En als je verder telt dan twee metingen? Dan kom je bij interne consistentie internal consistency: behandel elk item als een aparte test. De maat daarvoor is Cronbach’s α\alpha. Dat is dit thema — je komt er drie varianten van tegen: de ruwe alfa, de gestandaardiseerde alfa, en KR-20 voor vragen met goed-fout-antwoorden.

Reliability ≠\neq validity. Een onbetrouwbare schaal kan onmogelijk valide zijn (te veel ruis), maar een betrouwbare schaal hoeft nog niet valide te zijn (kan consistent het verkeerde meten). Validity volgt in thema 3.

En let op wát je schat. Betrouwbaarheid is geen eigenschap van een schaal, maar van deze schaal in deze populatie. Dezelfde tien items kunnen bij bosdieren keurig samenhangen en bij pissebedden uit elkaar vallen.

Eén vorm die je elders wél tegenkomt maar hier niet: inter-rater — stemmen twee beoordelaars overeen die hetzelfde object scoren? Dat is een volwaardige vorm van betrouwbaarheid, maar je meet hem niet met α\alpha: daarvoor gebruik je Cohen’s κ\kappa bij een categorisch oordeel, en de ICC bij continue scores. Meer erover achterin, bij Wat blijft liggen.

OpmerkingB. Cronbach’s α — de standaardmaat voor internal consistency

Cronbach’s α\alpha kwantificeert hoe sterk de items binnen een schaal samenhangen. Formules:

𝛼=kk−1(1−∑i=1ksi2ssom2) \mathit{\alpha} = \frac{k}{k - 1} \left( 1 - \frac{\sum_{i=1}^k s_i^2}{s_{\text{som}}^2} \right)

Met kk = aantal items, si2s_i^2 = variantie van item ii, ssom2s_{\text{som}}^2 = variantie van de som-score.

Of equivalent (gebaseerd op gemiddelde inter-item-correlatie r‾\bar{r}):

𝛼std=k⋅r‾1+(k−1)⋅r‾ \mathit{\alpha}_{\text{std}} = \frac{k \cdot \bar{r}}{1 + (k - 1) \cdot \bar{r}}

Twee belangrijke eigenschappen:

  1. α\alpha stijgt met kk — meer items = hogere α\alpha, ook bij gelijke inter-item-correlatie. Dat verklaart waarom kortere schalen het lastiger hebben.
  2. α\alpha stijgt met r‾\bar{r} — sterker samenhangende items = hogere α\alpha.

Vuistregels (gangbaar, niet wettelijk):

α\alpha-niveau Interpretatie
≥.90\geq .90 Uitstekend (soms te hoog — items kunnen redundant zijn)
.80.80-.89.89 Goed
.70.70-.79.79 Acceptabel voor onderzoek
.60.60-.69.69 Twijfelachtig — zeker geen klinische beslissing op baseren
<.60< .60 Schaal werkt niet
OpmerkingC. Wezel-frame — wat onderzoeken we?

De wezel — sluw, kritisch — kijkt naar de Bos-Piekeren-Schaal (BPS) en wil weten:

  • Hangen de tien items voldoende samen om er één score uit te halen?
  • Zijn er items die er niet bij horen (te zwak gerelateerd, andere structuur)?
  • Hoe stevig is de geschatte α\alpha — bouwt hij door als ik items wegsnijd?

De wezel werkt door. Hij is niet snel tevreden. Niemand mag “α=.85\alpha = .85, klaar” zeggen zonder dat de wezel naar de items kijkt en vraagt: “Welk item is de zwakkere broer?”

OpmerkingHoe dit hoofdstuk leest

Drie-laagse structuur als de andere thema’s:

  1. Verhaal-frame — wezel en consorten in het bos.
  2. Algemene vorm — abstract met mijn_data.
  3. Voor onze dieren — uitvoerend, concrete namen.

Daarnaast vier soorten blokken, elk met zijn eigen kop: vragen die je zelf maakt, antwoorden die je pas openklapt ná je eigen poging, vuistregels om vast te houden, en alarmen bij wat er in de praktijk vaak misgaat.

  • Scale-score als gemiddelde over kk items (rowMeans).
  • NA-discipline bij scale-scoren: bij hoogstens één ontbrekende waarde mag je middelen, vanaf twee ontbrekend zet je de scale-score op NA — op de 5 items van thema 1 dus minstens 4 ingevuld. Waaróm die grens zo streng staat zie je pas in dít thema: Spearman-Brown laat die schaal zakken van α=.85\alpha = .85 over 5 items naar .81.81 over 4 en .77.77 over 3.
  • Norm-scoren via z, T, percentiel — nu pas zinvol als de schaal meet. Vandaar dit thema vóór je veel norm-tabellen bouwt.

Plus de slogan uit thema 1: Ruw is Ruk. Geldt hier dubbel — een ruwe item-totaal-correlatie zegt niets als de items op verschillende schalen staan. Standaardiseren of rekening houden met item-variantie.

Werkmaterialen — R-pakketten en functies

De wezel pakt zijn gereedschap

Gereedschap Waar het voor is Pakket
psych::alpha() Cronbach’s α\alpha + item-statistieken in één output psych
psych::splitHalf() Alle mogelijke split-halfs en gemiddelde psych
cor() Item-correlatiematrix base
rowMeans(), rowSums() Som-score / scale-score base
cor(meting1, meting2) Test-retest betrouwbaarheid (zelden in dit thema) base
var() Variantie van items en som-score base

Let op de laatste regel maar één: test-retest is een correlatie tussen meting 1 en meting 2, niet een t.test(..., paired = TRUE). Die gepaarde toets vraagt of het gemiddelde van de groep verschuift tussen de twee momenten — een heel andere vraag. Een schaal kan perfect betrouwbaar zijn en tóch een verschuiving in het gemiddelde laten zien (iedereen scoort de tweede keer twee punten hoger), en een schaal kan volstrekt onbetrouwbaar zijn terwijl het gemiddelde precies gelijk blijft.

Je kunt α\alpha zelf uitrekenen — en de formule kennen hoort erbij. Maar in praktijk is psych::alpha() éé́n commando dat je alles geeft: α\alpha raw + standardized, item-statistieken (raw.r, r.drop), α\alpha-als-item-deleted, gemiddelden + SDs per item. Voor onderzoek + rapportage de werkelijke route. Voor het tentamen: weet de formule én weet wat de output betekent.

Notatie — symbolen voor reliability

OpmerkingSleutelsymbolen
  • α\alpha — Cronbach’s alpha. Niet te verwarren met het Type-I-foutniveau (ook α\alpha). Context maakt duidelijk welke.
  • kk — aantal items in de schaal.
  • r‾\bar{r} — gemiddelde inter-item-correlatie.
  • si2s_i^2 — variantie van item ii.
  • ssom2s_{\text{som}}^2 — variantie van de som-score.
  • rhalfr_{\text{half}} — correlatie tussen twee schaal-helften (split-half-correlatie).
  • rSBr_{\text{SB}} — door Spearman-Brown gecorrigeerde betrouwbaarheid.
  • rdropr_{\text{drop}} — item-totaal-correlatie als het item zelf eruit is gehaald (corrected item-total correlation).
  • semse_{\text{m}} — de standaardmeetfout standard error of measurement: hoe ver de score van één persoon gemiddeld naast zijn ware score valt. In dit hoofdstuk rekenen we hem als sem=SD⋅1−𝛼se_{\text{m}} = SD \cdot \sqrt{1 - \mathit{\alpha}}. Andere boeken schrijven dezelfde som met andere letters; die vertaling staat bij de opgave over de standaardmeetfout.
  • ses_{\text{e}} — de standaardafwijking van de meetfout. Dat is per definitie hetzelfde getal als semse_{\text{m}}, en daarom staat er in die andere notatie een gelijkteken tussen.
  • NN — omvang van de hele steekproef. nn — omvang van een deelgroep daarbinnen.
TipVuistregels zijn afspraken, geen wetten
  • α\alpha-grens voor gebruik in onderzoek: ≥.70\geq .70. Voor klinische beslissingen op individueel niveau: ≥.80\geq .80, bij voorkeur ≥.90\geq .90.
  • Schaal-lengte: k≥5k \geq 5 voor stabiele α\alpha-schatting. Onder k=3k = 3: rapporteer met expliciete waarschuwing.
  • Steekproef-grootte voor reliability-schatting: N≥100N \geq 100 voor betrouwbare α\alpha. Bij N<50N < 50: bootstrap-CI is gepast.
  • Item-totaal-correlatie: rdrop≥.30r_{\text{drop}} \geq .30 voor gangbare items. <.30< .30 = kandidaat voor verwijdering.
  • Spearman-Brown drempel: na correctie naar volledige schaal-lengte; gebruik bij split-half waar je twee parallelle helften hebt.

Verschillende vakgroepen hanteren iets andere drempels. Kom je er in een tentamenvraag of in een artikel een tegen die van deze afwijkt, dan is dat geen fout van jou: noem de grens die je aanhoudt, en zeg erbij waarom. Een drempel is een afspraak, en een afspraak die je opschrijft kan iemand met je oneens zijn — een drempel die je stil aanneemt niet.

OpmerkingCode in dit hoofdstuk — wat moet je kunnen typen?

Code is standaard open als je hem zelf moet kunnen typen: psych::alpha(), cor(), rowMeans(), rowSums(), var(), psych::splitHalf(). Code die alleen ter illustratie dient — gt-tabellen, ggplot-decoratie, item-pair-matching-algoritme — staat ingeklapt met een knopje “Toon code”.

2.0 Project- en datavoorbereiding

Open de meegestuurde projectmap (02_reliability/) en dubbelklik op 02_reliability.Rproj.

install.packages(c("tidyverse", "psych"))
  1. Open de hoofd-dataset.
# load() opent het bestand en zet het object dat erin zit klaar onder zijn
# eigen naam -- vandaar dat er nergens `iets <- load(...)` staat.
load("data/bos_dieren_piekeren.RData")

# str() geeft de bouwtekening: hoeveel rijen, welke kolommen, van welk soort.
str(bos_dieren_piekeren)
'data.frame':   200 obs. of  13 variables:
 $ dier_id             : Factor w/ 200 levels "d001","d002",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ geslacht            : Factor w/ 2 levels "man","vrouw": 1 2 1 1 2 2 1 1 1 2 ...
 $ diersoort           : Factor w/ 4 levels "bunzing","egel",..: 4 4 3 3 4 3 1 3 4 4 ...
 $ item1_terugkijken   : num  3 3 3 2 3 3 5 5 2 2 ...
 $ item2_nachtgedachten: num  2 3 2 4 5 3 3 3 4 1 ...
 $ item3_anderengedrag : num  3 2 5 3 3 4 1 4 1 1 ...
 $ item4_ergevoel      : num  2 3 4 3 3 4 4 4 3 1 ...
 $ item5_zinloos       : num  3 3 5 1 3 2 5 1 5 1 ...
 $ item6_loslaten      : num  2 1 5 3 3 2 4 5 1 1 ...
 $ item7_doorzetten    : num  3 5 4 4 2 2 1 3 2 3 ...
 $ item8_zorgen        : num  4 2 4 2 4 3 4 2 2 1 ...
 $ item9_terug         : num  4 2 5 5 2 3 4 3 3 1 ...
 $ item10_aanwezigheid : num  2 3 5 5 2 5 4 3 2 1 ...

Per dier: een dier_id, geslacht, diersoort, en tien items op een 55-puntsschaal die samen de Bos-Piekeren-Schaal (BPS) vormen.

  • item1_terugkijken: “Ik blijf hangen in wat er gisteren is gebeurd.”
  • item2_nachtgedachten: “’s Nachts spelen problemen door mijn kop.”
  • item3_anderengedrag: “Ik vraag me af wat anderen van mij vinden.”
  • item4_ergevoel: “Ik voel me schuldig over kleine dingen.”
  • item5_zinloos: “Ik vind sommige dingen achteraf zinloos.”
  • item6_loslaten: “Ik krijg gedachten niet zomaar uit mijn hoofd.”
  • item7_doorzetten: “Ik laat me niet snel uit het veld slaan.” — ongepoold: hoog op dit item = láge piekeren. De wezel had hem zo opgeschreven en is vergeten hem om te keren bij scoring. Komt straks aan de beurt.
  • item8_zorgen: “Ik maak me zorgen over de toekomst.”
  • item9_terug: “Ik kom terug op gesprekken die niet goed liepen.”
  • item10_aanwezigheid: “Het kost moeite om bij het hier-en-nu te blijven.”

Allemaal 1=1 = bijna nooit, 5=5 = bijna altijd. Eén ontbrekende waarde op item6_loslaten[73].

2.1 Cronbach’s α en item-totaal-correlaties

Hangen de items samen?

“α\alpha,” zei de wezel. “Eén getal dat samenvat hoe goed je items op één golflengte zitten. Bij hoge α\alpha doen ze dat — onder lage α\alpha niet.”

OpmerkingVoor je gaat rekenen — vijf vragen aan jezelf
  1. Wie of wat wordt er gemeten? De wezel heeft 200200 bosdieren op tien BPS-items genoteerd.
  2. Wat wordt er gemeten? Tien items, elk 11-55, plus twee groeps-variabelen.
  3. Onafhankelijk of afhankelijk? Geen voorspelmodel. We willen weten: hangen de items genoeg samen om één som-score te rechtvaardigen?
  4. Meetniveau? Items: ordinaal, behandeld als interval. Som-score: interval (1010-5050). Geslacht: nominaal. Diersoort: nominaal.
  5. Welke techniek? Bij internal consistency: Cronbach’s α\alpha + item-statistieken. Bij parallelle helften: split-half + Spearman-Brown. Beide oefenen we hier.

T1 — Welke reliability-soort?

OpmerkingVraag T1 — Pen-en-papier

Voor elk vignet: kies tussen internal consistency (α\alpha, KR-20, split-half), test-retest, inter-rater (κ\kappa, ICC), of parallel-forms.

Wat tussen haakjes staat zijn de maten die bij die soort horen. Je hoeft ze hier nog niet te kunnen uitrekenen en je hebt ze niet nodig om de vraag te maken — kies de soort. KR-20 komt verderop nog langs; κ\kappa en ICC blijven buiten dit hoofdstuk.

a) Een psycholoog wil weten of de tien items van haar nieuwe depressie-vragenlijst samen één construct meten.

b) Een onderzoeker meet bij 8080 patiënten op t0t_0 en zes weken later op t1t_1 dezelfde stress-vragenlijst — werkt de schaal stabiel?

c) Twee psychiaters scoren 5050 patiënten elk op een PTSS-symptoomschaal, op basis van interview. Komen hun scores overeen?

d) Een uitgever heeft twee versies van dezelfde rekenkundetoets (vorm A en vorm B). Geven ze dezelfde score per leerling?

e) Een toetsenmaker knipt een rekenvaardigheidstoets van 4040 opgaven in twee helften van 2020, en kijkt of een leerling op beide helften ongeveer even goed scoort. Eén afname, één moment.

a) Internal consistency (α\alpha). Tien items, één meetmoment, geen rater-vraag — gewoon: meten ze hetzelfde construct?

b) Test-retest. Twee meetmomenten op dezelfde personen, dezelfde test. Pearson-rr tussen t0t_0 en t1t_1.

c) Inter-rater (ICC voor continue scores, κ\kappa voor categorische). Twee beoordelaars, hetzelfde object, vraag is consistentie tussen beoordelaars.

Dit is de enige soort in deze rij die je in dit hoofdstuk niet leert uitrekenen, en dat is met opzet: interbeoordelaarsbetrouwbaarheid vraagt eigen maten, en die blijven buiten dit hoofdstuk. Je hoeft hem hier alleen te herkennen — aan het patroon twee beoordelaars, één object — en te weten dat α\alpha er niet voor deugt. Wat je er wél voor gebruikt staat in Wat blijft liggen: Cohen’s κ\kappa bij een categorisch oordeel, de ICC bij continue scores.

d) Parallel-forms. Twee versies van hetzelfde construct — bedoeld als equivalent. Pearson-rr tussen vorm A en vorm B.

e) Internal consistency, en wel via split-half. Dit is de valkuil van de rij: twee helften zien eruit als twee vormen, dus parallel-forms ligt voor de hand. Het verschil zit in de afname. Bij d) zijn het twee toetsen die apart zijn gemaakt en apart worden afgenomen; hier is er één toets, één afname, en de tweedeling komt pas achteraf op de tafel van de onderzoeker. Alles wat je uit één afname over samenhang binnen de toets haalt, is interne consistentie — split-half is daar één route in, Cronbach’s α\alpha een andere. En let op: de correlatie tussen de twee helften is de betrouwbaarheid van een halve toets, dus die moet nog met Spearman-Brown naar volle lengte worden opgehoogd. Dat doe je verderop, bij de split-half zelf.

Vuistregel. Eén meetmoment, items binnen schaal = internal consistency (α\alpha, of split-half). Twee meetmomenten, dezelfde test = test-retest. Twee beoordelaars, één object = inter-rater. Twee apart afgenomen versies van een test = parallel-forms. Zit je te twijfelen: tel eerst hoe vaak er gemeten is, en pas daarna wat er met de uitkomst gebeurt.

2.1.a Verkenning — item-statistieken

# De tien itemnamen één keer in een rijtje. c() is kort voor combine: het plakt
# losse waarden aan elkaar tot één rijtje. Zo hoef je die namen verderop niet
# tien keer over te tikken -- en vertik je je ook niet.
items <- c("item1_terugkijken", "item2_nachtgedachten", "item3_anderengedrag",
           "item4_ergevoel",    "item5_zinloos",        "item6_loslaten",
           "item7_doorzetten",  "item8_zorgen",         "item9_terug",
           "item10_aanwezigheid")

Algemene vorm.

# Item-means en SDs.
sapply(mijn_data[, items], mean, na.rm = TRUE)
sapply(mijn_data[, items], sd,   na.rm = TRUE)

# Item-correlatiematrix.
round(cor(mijn_data[, items], use = "complete.obs"), 2)

Voor onze dieren.

Ook hier staat een aantal sommen in twee schrijfwijzen naast elkaar, in tabbladen. Net als in thema 1: Base R staat vooraan en is het enige dat je zelf moet kunnen typen; dplyr staat ernaast om te kijken, en je hoeft er niets van te kunnen typen. Ben je het pijpje |> of \(x) kwijt, dan staan die uitgelegd in het kader Twee tekens die je in elk dplyr-blok terugziet in thema 1.

# sapply() past een functie toe op elke kolom en geeft je een rijtje getallen
# terug, netjes met de itemnamen erbij.
round(sapply(bos_dieren_piekeren[, items], mean, na.rm = TRUE), 2)
   item1_terugkijken item2_nachtgedachten  item3_anderengedrag 
                3.13                 3.10                 3.13 
      item4_ergevoel        item5_zinloos       item6_loslaten 
                3.09                 2.98                 3.07 
    item7_doorzetten         item8_zorgen          item9_terug 
                3.02                 3.08                 3.00 
 item10_aanwezigheid 
                2.92 
# na.rm = TRUE laat de ontbrekende waarde op item6 weg. Zonder die schakelaar
# krijgt dat ene item een gemiddelde van NA en de rest gewoon een getal -- één
# gat maakt dus één kolom stil onbruikbaar.
round(sapply(bos_dieren_piekeren[, items], sd,   na.rm = TRUE), 2)
   item1_terugkijken item2_nachtgedachten  item3_anderengedrag 
                1.24                 1.27                 1.43 
      item4_ergevoel        item5_zinloos       item6_loslaten 
                1.28                 1.19                 1.27 
    item7_doorzetten         item8_zorgen          item9_terug 
                1.32                 1.23                 1.22 
 item10_aanwezigheid 
                1.24 
library(dplyr)

# summarise() perst de tabel samen tot één regel; across() doet dat voor alle
# tien de items in één keer, en all_of() zegt dat hun namen in het rijtje
# `items` staan en niet hier in de code.
bos_dieren_piekeren |>
  summarise(across(all_of(items), \(x) mean(x, na.rm = TRUE))) |>
  round(2)
  item1_terugkijken item2_nachtgedachten item3_anderengedrag item4_ergevoel
1              3.13                  3.1                3.13           3.09
  item5_zinloos item6_loslaten item7_doorzetten item8_zorgen item9_terug
1          2.98           3.07             3.02         3.08           3
  item10_aanwezigheid
1                2.92
bos_dieren_piekeren |>
  summarise(across(all_of(items), \(x) sd(x, na.rm = TRUE))) |>
  round(2)
  item1_terugkijken item2_nachtgedachten item3_anderengedrag item4_ergevoel
1              1.24                 1.27                1.43           1.28
  item5_zinloos item6_loslaten item7_doorzetten item8_zorgen item9_terug
1          1.19           1.27             1.32         1.23        1.22
  item10_aanwezigheid
1                1.24

Bij tien items zie je waarom dit een keuze blijft en geen regel. Base R zet de namen boven de getallen en breekt af per drie; dplyr maakt één tabel van tien kolommen breed, die in blokken onder elkaar doorloopt. Even lang ongeveer — base R neemt er hier zelfs twee printregels méér — maar bij base R staat elke naam pal boven zijn eigen getal, en dat leest bij tien items makkelijker.

Kijk daarbij ook naar de decimalen in de dplyr-tabel: item9_terug staat er als kale 3 en item2_nachtgedachten als 3.1. Dat is dezelfde afdruk-eigenaardigheid als in thema 1, en nu per kolom in plaats van per rijtje — elke kolom kiest zijn eigen breedte. Voor je erover rapporteert zet je zo’n getal dus altijd zelf op twee decimalen.

Toon code (item-correlatiematrix)
# cor() op een hele tabel geeft een matrix: elk item tegen elk ander item, met
# een diagonaal van enen (elk item correleert perfect met zichzelf).
# use = "complete.obs" gooit de dieren met een gat eruit vóór het rekenen.
cor_BPS <- cor(bos_dieren_piekeren[, items], use = "complete.obs")
round(cor_BPS, 2)
                     item1_terugkijken item2_nachtgedachten item3_anderengedrag
item1_terugkijken                 1.00                 0.41                0.25
item2_nachtgedachten              0.41                 1.00                0.34
item3_anderengedrag               0.25                 0.34                1.00
item4_ergevoel                    0.35                 0.39                0.29
item5_zinloos                     0.38                 0.38                0.30
item6_loslaten                    0.41                 0.37                0.36
item7_doorzetten                 -0.53                -0.46               -0.33
item8_zorgen                      0.47                 0.52                0.29
item9_terug                       0.43                 0.43                0.32
item10_aanwezigheid               0.47                 0.48                0.40
                     item4_ergevoel item5_zinloos item6_loslaten
item1_terugkijken              0.35          0.38           0.41
item2_nachtgedachten           0.39          0.38           0.37
item3_anderengedrag            0.29          0.30           0.36
item4_ergevoel                 1.00          0.33           0.38
item5_zinloos                  0.33          1.00           0.44
item6_loslaten                 0.38          0.44           1.00
item7_doorzetten              -0.37         -0.40          -0.38
item8_zorgen                   0.52          0.43           0.38
item9_terug                    0.39          0.41           0.50
item10_aanwezigheid            0.40          0.36           0.36
                     item7_doorzetten item8_zorgen item9_terug
item1_terugkijken               -0.53         0.47        0.43
item2_nachtgedachten            -0.46         0.52        0.43
item3_anderengedrag             -0.33         0.29        0.32
item4_ergevoel                  -0.37         0.52        0.39
item5_zinloos                   -0.40         0.43        0.41
item6_loslaten                  -0.38         0.38        0.50
item7_doorzetten                 1.00        -0.48       -0.41
item8_zorgen                    -0.48         1.00        0.43
item9_terug                     -0.41         0.43        1.00
item10_aanwezigheid             -0.46         0.44        0.40
                     item10_aanwezigheid
item1_terugkijken                   0.47
item2_nachtgedachten                0.48
item3_anderengedrag                 0.40
item4_ergevoel                      0.40
item5_zinloos                       0.36
item6_loslaten                      0.36
item7_doorzetten                   -0.46
item8_zorgen                        0.44
item9_terug                         0.40
item10_aanwezigheid                 1.00
Toon code (item-correlatiematrix)
# cat() drukt tekst af zoals je hem typt; "\n" is een regelovergang.
cat("\nGemiddelde inter-item-correlatie:\n")

Gemiddelde inter-item-correlatie:
Toon code (item-correlatiematrix)
# upper.tri() pakt alleen de driehoek bóven de diagonaal. Dat moet, want de
# matrix bevat elke correlatie twee keer en de diagonaal van enen erbij --
# gemiddel je de hele matrix, dan trekken die enen het getal omhoog.
mean_r <- mean(cor_BPS[upper.tri(cor_BPS)])
round(mean_r, 3)
[1] 0.231
OpmerkingVragen 2.1.a

a) Liggen de item-means dicht bij elkaar?

b) Welk item heeft de laagste correlaties met de rest?

c) Wat is de gemiddelde inter-item-correlatie? Past die bij een redelijk werkende schaal?

d) Voorspel op basis van kk en r‾\bar{r} wat αstd\alpha_{\text{std}} ongeveer wordt.

a) Item-means liggen tussen 2.922.92 en 3.133.13 — vrijwel gelijk. Dat is gewenst voor split-half (zie 2.2): items met sterk afwijkende moeilijkheid zijn lastig te paren.

b) item7_doorzetten valt op met negatieve correlaties met vrijwel alle andere items (r=−.33r = -.33 tot −.53-.53). Dat is een sterk signaal: dit item is ongepoold (negatief geformuleerd t.o.v. de rest van de schaal). Voordat we α\alpha berekenen moet hij worden omgepoold — zie 2.1.b en 2.1.c. Daarnaast heeft item3_anderengedrag lagere maar wel positieve correlaties — kandidaat voor item-deletie-discussie, maar dat speelt pas ná ompoling van item7.

c) Gemiddelde inter-item-correlatie vóór ompoling: r‾=.23\bar{r} = .23 — kunstmatig laag door de negatieve correlaties van item7. Na ompoling van item7: r‾=.40\bar{r} = .40 — past bij een schaal die één construct meet met enige item-variatie.

d) Voorspelling vóór ompoling: αstd=(10⋅.23)/(1+9⋅.23)=.75\alpha_{\text{std}} = (10 \cdot .23) / (1 + 9 \cdot .23) = .75 — onderschatting. Voorspelling na ompoling: αstd=(10⋅.40)/(1+9⋅.40)=.87\alpha_{\text{std}} = (10 \cdot .40) / (1 + 9 \cdot .40) = .87. Verschil =.12= .12 — substantieel, en precies waarom ompolen niet optioneel is.

APA-stijl. (rapportage volgt na ompoling — zie 2.1.d)

2.1.b Recoden / ompolen — hoog wordt laag

Het item dat de andere kant op staat

De wezel rolde door zijn correlatiematrix en bleef bij item 7 hangen.

“Min vier-en-veertig,” zei hij. “Negatieve correlatie met de rest.”

“Item is kapot,” zei de bunzing.

“Item is andersom geschreven,” zei de wezel. “Ik laat me niet uit het veld slaan. Hoog op die zin = lage piekeren. Tegen de rest van de schaal in. Niet kapot — alleen ongepoold.”

“Wat doe je ermee?”

“Recoden. Ompolen. Score van 55 wordt 11, 44 wordt 22, 33 blijft 33. Dan loopt hij weer mee.”

OpmerkingWat is ompolen — en waarom moet het?

Bij vragenlijsten zijn sommige items negatief geformuleerd: hoge score = laag construct. Voorbeelden in een piekeren-schaal:

  • “Ik blijf hangen in nare gedachten” — hoog = veel piekeren ✓ (positief geformuleerd voor piekeren)
  • “Ik laat me niet uit het veld slaan” — hoog = weinig piekeren ✗ (omgekeerd geformuleerd)

Ongepoolde items werken tegen de schaal:

  • Negatieve item-totaal-correlaties.
  • Lage of zelfs negatieve α\alpha.
  • Misleidende som-scores als je toch optelt.

Oplossing: ompolen vóór je alpha berekent. Op een 55-punts Likert (11-55):

nieuwe score=(max+min)−oude score=6−oude score \text{nieuwe score} = (\text{max} + \text{min}) - \text{oude score} = 6 - \text{oude score}

Op 11-77 Likert: 8−score8 - \text{score}. Algemeen: (max+min)−score(\text{max} + \text{min}) - \text{score}.

Hoe weet je of een item omgepoold moet?

  1. Theoretisch — bij item-constructie weet je welke items omgekeerd geformuleerd zijn. Markeer ze in de data-dictionary.
  2. Empirisch — bekijk de correlatiematrix. Items met overwegend negatieve correlaties met de rest zijn ongepoolde kandidaten.
  3. Auto-detectie via psych::alpha(..., check.keys = TRUE) — psych keert items met negatieve item-totaal-correlatie automatisch om en waarschuwt.
WaarschuwingPas op — niet elk boek doet het, wij wel

Soms wordt het ompolen overgeslagen en gaat men direct door naar Cronbach’s α\alpha. Voor dit oefenboek geldt: altijd checken op ongepoolde items vóór α\alpha. Een gepubliceerde α\alpha op een schaal met ongepoolde items is een ongeldige schatting — geen kleine fout, maar een fundamentele meet-claim die niet klopt.

Tijdsinvestering: 3030 seconden per schaal (correlatiematrix scannen op negatieve waarden). Risico bij overslaan: alpha onderschat, schaal ten onrechte als onbetrouwbaar beoordeeld, of erger — onterecht als betrouwbaar.

2.1.c Recoden in R — drie routes

In onze dataset staat één ongepoold item: item7_doorzetten (“Ik laat me niet snel uit het veld slaan”). Hoog op dit item = láge piekeren. De wezel had hem zo geformuleerd en is vergeten hem om te keren bij scoring. Vóór alle volgende analyses ompolen we hem.

Eerste stap: kijk naar de correlaties. In 2.1.a heb je de correlatiematrix al gezien — item7_doorzetten heeft negatieve correlaties met alle andere items. Dat is het signaal.

# Alleen de correlaties van item7 met de rest -- duidelijker dan de hele matrix.
# De naam vóór de komma kiest een rij: cor_full["item7_doorzetten", ] is de
# hele regel van item7. Zou je hem ná de komma zetten, dan kreeg je de kolom --
# bij een correlatiematrix dezelfde getallen, maar dat is toeval en geen regel.
cor_full <- cor(bos_dieren_piekeren[, items], use = "complete.obs")
round(cor_full["item7_doorzetten", ], 2)
   item1_terugkijken item2_nachtgedachten  item3_anderengedrag 
               -0.53                -0.46                -0.33 
      item4_ergevoel        item5_zinloos       item6_loslaten 
               -0.37                -0.40                -0.38 
    item7_doorzetten         item8_zorgen          item9_terug 
                1.00                -0.48                -0.41 
 item10_aanwezigheid 
               -0.46 

Route 1 — handmatig met aritmetiek

Er zijn twee schrijfwijzen voor het ompolen zelf. Wat je erna doet om te kijken of het gelukt is, is in beide gevallen hetzelfde, en dat staat daarom één keer onder de tabbladen.

# 5-punts Likert: nieuwe waarde = 6 - oude waarde. Waar die 6 vandaan komt:
# hoogste antwoord plus laagste antwoord, dus 5 + 1. Bij een 7-puntsschaal
# wordt het 8 - oude waarde.
bos_dieren_piekeren$item7_doorzetten_REC <- 6 - bos_dieren_piekeren$item7_doorzetten
# mutate() zet de omgepoolde kolom erbij. Binnen mutate() noem je het item bij
# zijn kale naam -- geen dollarteken, want dplyr weet al in welke tabel hij
# kijkt. Dat is het hele verschil met de regel links.
bos_dieren_piekeren <- bos_dieren_piekeren |>
  mutate(item7_doorzetten_REC = 6 - item7_doorzetten)

Heb je er drie of vier, dan hoef je die regel niet drie of vier keer te schrijven. across() doet ze in één keer:

ompool <- c("item7_doorzetten", "item3_anderengedrag")

bos_dieren_piekeren |>
  mutate(across(all_of(ompool), \(x) 6 - x, .names = "{.col}_REC"))

.names = "{.col}_REC" bepaalt hoe de nieuwe kolommen gaan heten: {.col} is de oude naam, dus item7_doorzetten wordt item7_doorzetten_REC. Laat dat niet weg — dan schrijft across() over de oorspronkelijke kolommen heen, en dan zijn je ruwe antwoorden weg zonder dat iets dat meldt.

# Natrekken of het gelukt is: na ompoling horen de correlaties van item7 met de
# rest positief te worden. Blijven ze negatief, dan meet dat item echt iets
# anders, en is ompolen niet de oplossing.
items_REC <- c("item1_terugkijken", "item2_nachtgedachten", "item3_anderengedrag",
               "item4_ergevoel",    "item5_zinloos",        "item6_loslaten",
               "item7_doorzetten_REC",  "item8_zorgen",     "item9_terug",
               "item10_aanwezigheid")

# Een naam tussen blokhaken vóór de komma kiest een rij en geen kolom:
# cor_REC["item7_doorzetten_REC", ] is de hele regel van item7.
cor_REC <- cor(bos_dieren_piekeren[, items_REC], use = "complete.obs")
round(cor_REC["item7_doorzetten_REC", ], 2)
   item1_terugkijken item2_nachtgedachten  item3_anderengedrag 
                0.53                 0.46                 0.33 
      item4_ergevoel        item5_zinloos       item6_loslaten 
                0.37                 0.40                 0.38 
item7_doorzetten_REC         item8_zorgen          item9_terug 
                1.00                 0.48                 0.41 
 item10_aanwezigheid 
                0.46 

Alle correlaties zijn nu positief — item7_doorzetten_REC loopt mee met de andere items.

Route 2 — psych::reverse.code() met sleutelvector

# Sleutelvector: 1 = laat item ongemoeid; -1 = pol om.
# Lengte gelijk aan het aantal items (10), met -1 op de plek van item7.
keys_vec <- c(1, 1, 1, 1, 1, 1, -1, 1, 1, 1)

# mini en maxi zijn de laagste en hoogste mogelijke antwoordwaarde. Die moet je
# zélf opgeven: reverse.code() leest ze niet af uit de data, en dat is ook
# terecht -- als niemand een 1 of een 5 heeft geantwoord staat de grens er niet
# in, en dan zou hij de verkeerde omkering rekenen.
bos_REC <- psych::reverse.code(keys_vec,
                               bos_dieren_piekeren[, items],
                               mini = 1,
                               maxi = 5)

# colnames() geeft de kolomnamen. De omgepoolde kolom krijgt automatisch een
# minteken achter zijn naam, zodat je later kunt zien dat er iets met hem is
# gebeurd.
colnames(bos_REC)
 [1] "item1_terugkijken"    "item2_nachtgedachten" "item3_anderengedrag" 
 [4] "item4_ergevoel"       "item5_zinloos"        "item6_loslaten"      
 [7] "item7_doorzetten-"    "item8_zorgen"         "item9_terug"         
[10] "item10_aanwezigheid" 

psych::reverse.code() levert een data-frame waarin de omgepoolde kolom is hernoemd (suffix -). Voor downstream-gebruik kun je hem aankoppelen aan de oorspronkelijke data of vervangen.

Route 3 — auto-detectie via psych::alpha(check.keys = TRUE)

# check.keys = TRUE laat psych zelf zoeken naar ongepoolde items -- hij kijkt
# naar negatieve item-totaal-correlaties en keert die items om.
res_auto <- psych::alpha(bos_dieren_piekeren[, items], check.keys = TRUE)

# $keys laat zien wat hij besloten heeft: de itemnamen, met een minteken vóór
# de naam van elk item dat hij heeft omgekeerd. Lees dat altijd na -- zo zie je
# of hij hetzelfde item heeft aangewezen als jij. Let op het verschil met de
# sleutelvector van route 2: die schrijf je als 1 en -1, deze komt eruit als
# namen.
res_auto$keys
[[1]]
 [1] "item1_terugkijken"    "item2_nachtgedachten" "item3_anderengedrag" 
 [4] "item4_ergevoel"       "item5_zinloos"        "item6_loslaten"      
 [7] "-item7_doorzetten"    "item8_zorgen"         "item9_terug"         
[10] "item10_aanwezigheid" 

psych::alpha print een waarschuwing dat item7_doorzetten ongepoold is, en keert hem automatisch om voor de α\alpha-berekening. Handig — maar valideer altijd theoretisch dat de auto-omkering klopt.

Alle drie de routes komen op hetzelfde neer; wat verschilt is hoeveel je zelf opschrijft en hoeveel je aan psych overlaat. Route 1 laat je de rekenregel zien, route 3 verbergt hem — en dat is precies waarom je hem één keer met de hand hoort te doen.

# Vanaf hier wijst `items` naar het omgepoolde item7 in plaats van naar het
# oorspronkelijke. De oude kolom blijft wel in de data staan -- we hebben hem
# niet weggegooid, alleen niet meer in de lijst gezet. Dat is met opzet: zo kun
# je altijd terug naar de ruwe antwoorden.
items <- c("item1_terugkijken", "item2_nachtgedachten", "item3_anderengedrag",
           "item4_ergevoel",    "item5_zinloos",        "item6_loslaten",
           "item7_doorzetten_REC",  "item8_zorgen",     "item9_terug",
           "item10_aanwezigheid")
OpmerkingVragen 2.1.c

a) Welk getal trek je af bij een 77-punts Likert (11-77)?

b) Welke drie signalen wijzen op een ongepoold item?

c) Wat is het effect op α\alpha van een ongepoold item dat je niet ompolt?

d) Wanneer is auto-detectie via check.keys = TRUE riskant?

a) 8−score8 - \text{score}. Algemene formule: (max+min)−score(\text{max} + \text{min}) - \text{score}. Bij 11-77: 7+1=87 + 1 = 8.

b) (1) Negatieve correlatie tussen item en rest van de schaal. (2) Negatieve item-totaal-correlatie (rdrop<0r_{\text{drop}} < 0). (3) Itemtekst die conceptueel tegengesteld geformuleerd is t.o.v. wat de schaal meet (theoretische check).

c) α\alpha onderschat de werkelijke betrouwbaarheid sterk — kan dalen tot ver onder .50.50 of zelfs negatief worden. Schaal lijkt onbetrouwbaar terwijl hij dat niet is — alleen één item wijst de andere kant op.

d) Bij kleine NN of bij schalen met echte negatieve correlaties (onverwante constructen die toevallig in dezelfde dataset zitten) kan check.keys = TRUE ten onrechte items omkeren. Vuistregel: gebruik auto-detectie als diagnostiek, valideer altijd theoretisch — en vermeld in je rapport welke items zijn omgepoold en op basis van welk argument.

2.1.d Cronbach’s α — fitten en interpreteren

Algemene vorm.

# Snelle alpha + item-statistieken.
res <- psych::alpha(mijn_data[, items])
res$total       # alpha raw + std + andere globale maten
res$item.stats  # per item: raw.r, r.drop, mean, sd
res$alpha.drop  # alpha als item-eruit

Voor onze dieren.

# check.keys = FALSE zegt: pol niets voor me om. Dat staat hier met opzet zo,
# want je hebt item7 hierboven zelf al omgepoold -- zou psych het nóg eens
# doen, dan stond hij weer verkeerd.
# De uitkomst is geen los getal maar een pakketje met meer tabellen erin; met
# het dollarteken haal je er één uit ($total, $item.stats, $alpha.drop).
alpha_res <- psych::alpha(bos_dieren_piekeren[, items],
                          check.keys = FALSE)

# raw_alpha rekent met de ruwe item-varianties, std.alpha doet alsof elk item
# even zwaar weegt. Liggen die twee ver uit elkaar, dan verschillen je items
# sterk in spreiding. average_r is de gemiddelde correlatie tussen twee items.
# Die drie heb je nodig. G6(smc), S/N en ase komen er gratis bij omdat psych ze
# toch al uitrekent -- kijk er niet naar, ze vallen buiten dit hoofdstuk.
round(alpha_res$total[, c("raw_alpha", "std.alpha", "G6(smc)",
                          "average_r", "S/N", "ase")], 3)
 raw_alpha std.alpha G6(smc) average_r   S/N   ase
     0.868     0.869   0.864     0.399 6.644 0.014

Hieronder kies je vijf van de kolommen die psych heeft uitgerekend. Ook dat kan op twee manieren, en hier zit het verschil in de aanhalingstekens.

# Per item: raw.r is de item-totaal-correlatie, r.drop diezelfde correlatie
# maar met het item zelf uit het totaal gehaald, plus het gemiddelde en de SD.
# In [ , c("n", "raw.r", ...) ] staan de kolomnamen tussen aanhalingstekens:
# base R wil hier tekst, geen kale namen.
round(alpha_res$item.stats[, c("n", "raw.r", "r.drop", "mean", "sd")], 3)
                       n raw.r r.drop  mean    sd
item1_terugkijken    200 0.691  0.603 3.130 1.241
item2_nachtgedachten 200 0.702  0.614 3.100 1.272
item3_anderengedrag  200 0.584  0.458 3.135 1.427
item4_ergevoel       200 0.650  0.550 3.095 1.282
item5_zinloos        200 0.646  0.553 2.980 1.186
item6_loslaten       199 0.674  0.582 3.065 1.268
item7_doorzetten_REC 200 0.712  0.622 2.980 1.322
item8_zorgen         200 0.725  0.645 3.080 1.229
item9_terug          200 0.691  0.604 3.000 1.224
item10_aanwezigheid  200 0.701  0.615 2.915 1.243
# select() kiest kolommen, en daar mogen de namen kaal -- zonder
# aanhalingstekens, zonder c() eromheen. Dat is het hele verschil met de
# schrijfwijze links.
alpha_res$item.stats |>
  select(n, raw.r, r.drop, mean, sd) |>
  round(3)
                       n raw.r r.drop  mean    sd
item1_terugkijken    200 0.691  0.603 3.130 1.241
item2_nachtgedachten 200 0.702  0.614 3.100 1.272
item3_anderengedrag  200 0.584  0.458 3.135 1.427
item4_ergevoel       200 0.650  0.550 3.095 1.282
item5_zinloos        200 0.646  0.553 2.980 1.186
item6_loslaten       199 0.674  0.582 3.065 1.268
item7_doorzetten_REC 200 0.712  0.622 2.980 1.322
item8_zorgen         200 0.725  0.645 3.080 1.229
item9_terug          200 0.691  0.604 3.000 1.224
item10_aanwezigheid  200 0.701  0.615 2.915 1.243
# $alpha.drop heeft één regel per item, en op die regel staat wat alpha wordt
# als je juist dát item weglaat. Dus: hoger dan de alpha hierboven betekent
# "de schaal wordt beter zonder hem".
round(alpha_res$alpha.drop[, c("raw_alpha", "std.alpha", "average_r")], 3)
                     raw_alpha std.alpha average_r
item1_terugkijken        0.854     0.855     0.396
item2_nachtgedachten     0.853     0.854     0.394
item3_anderengedrag      0.867     0.867     0.419
item4_ergevoel           0.858     0.859     0.404
item5_zinloos            0.857     0.859     0.404
item6_loslaten           0.855     0.857     0.400
item7_doorzetten_REC     0.852     0.854     0.393
item8_zorgen             0.850     0.852     0.390
item9_terug              0.854     0.855     0.396
item10_aanwezigheid      0.853     0.854     0.395
OpmerkingVragen 2.1.d

a) Wat is Cronbach’s α\alpha (raw)? Past het bij de vooraf-voorspelling?

b) Welk item heeft de laagste rdropr_{\text{drop}}? Wat zegt dat?

c) Als je dat zwakke item zou verwijderen, wat zou α\alpha worden?

d) Stel je hebt een schaal met α=.65\alpha = .65. Wat zijn je opties om hem te verbeteren?

a) αraw=.87\alpha_{\text{raw}} = .87 — goed. Komt overeen met de vooraf-voorspelling op basis van k=10k = 10 en r‾=.40\bar{r} = .40.

b) item3_anderengedrag: rdrop=.46r_{\text{drop}} = .46 — het laagste van de tien, tegen .55.55 tot .65.65 voor de rest. Het meet minder hetzelfde construct dan de andere items. Let op wat dat wél en niet betekent: de vuistregel hierboven legt de grens bij rdrop<.30r_{\text{drop}} < .30, en dit item zit daar ruim boven. Het is dus het zwakste van een stel goede items, geen kandidaat voor verwijdering. “Zwakst” is een rangorde, “te zwak” is een oordeel — die twee lopen in verslagen voortdurend door elkaar.

c) Uit de alpha.drop-output: α\alpha zonder item3_anderengedrag wordt .8666.8666, tegen .8678.8678 nu. Dus niet hoger maar iéts lager. Item3 doet weinig kwaad omdat de schaal verder sterk is, maar voegt ook weinig toe. Bij een korte schaal zou verwijdering aanzienlijk effect hebben; bij k=10k = 10 nauwelijks.

d) Drie opties: (1) Items toevoegen — meer items met goede r‾\bar{r} verhogen α\alpha (α\alpha-vs-kk-formule). (2) Items verwijderen die niet samenhangen — kan helpen als ze de gemiddelde r‾\bar{r} omhoog trekken. (3) Items herformuleren als de zwakte ligt aan vraagstelling, niet aan construct. Zonder nieuwe data: route 2 als snelste fix.

Inzicht. α\alpha is niet een eigenschap van een schaal — het is een eigenschap van deze schaal in deze populatie. Bij een andere populatie (klinisch versus niet-klinisch, jongeren versus ouderen) kan α\alpha anders uitkomen. Vandaar de verplichte vermelding “in this sample α = …”.

TipAPA-rapportage — Cronbach’s α in lopende tekst

De Bos-Piekeren-Schaal toonde goede internal consistency in deze steekproef (N=200N = 200 bosdieren), Cronbach’s α = .87, r‾=.40\bar{r} = .40. Item-totaal-correlaties (gecorrigeerd) varieerden van rdrop=.46r_{\text{drop}} = .46 (item 3, “Ik vraag me af wat anderen van mij vinden”) tot rdrop=.65r_{\text{drop}} = .65 (item 8, “Ik maak me zorgen over de toekomst”). Geen enkel item verhoogde de α bij verwijdering.

BelangrijkDon’t: α\alpha onder .60.60 publiceren als “acceptabel”

Een schaal met α=.58\alpha = .58 en de tekst “de internal consistency was acceptabel” — het staat in echte artikelen, en het is om boos van te worden. Dat is geen acceptabele consistency. Dat is een schaal die niet meet wat hij beweert te meten in deze steekproef.

Je hebt twee opties: óf je herziet de schaal (items eruit, items erbij, andere bewoording), óf je rapporteert eerlijk dat de schaal in deze sample onbetrouwbaar was en interpreteert resultaten met grote voorzichtigheid. Je kunt niet een α=.58\alpha = .58 rapporteren en doen alsof het een betrouwbaar instrument is.

Wie dat tóch doet — meestal omdat de deadline drukt en de reviewer streng is — bouwt een literatuur op getallen die niet meten wat ze beweren. Dat is wetenschappelijk vandalisme. “Ruw is Ruk”, en “α<.60\alpha < .60” ook.

T2 — Cronbach’s α handrekenen

OpmerkingVraag T2 — Pen-en-papier

Een vragenlijst van 55 items heeft een gemiddelde inter-item-correlatie van r‾=.30\bar{r} = .30.

a) Bereken αstd\alpha_{\text{std}}.

b) Wat als je 55 extra equivalente items toevoegt (k=10k = 10)?

c) Wat als je r‾\bar{r} verhoogt naar .40.40 bij k=5k = 5?

d) Welk effect is groter — items toevoegen of items verbeteren?

a) α=(5⋅.30)/(1+4⋅.30)=1.50/2.20≈.68\alpha = (5 \cdot .30) / (1 + 4 \cdot .30) = 1.50 / 2.20 \approx .68. Twijfelachtig.

b) α=(10⋅.30)/(1+9⋅.30)=3.00/3.70≈.81\alpha = (10 \cdot .30) / (1 + 9 \cdot .30) = 3.00 / 3.70 \approx .81. Goed.

c) α=(5⋅.40)/(1+4⋅.40)=2.00/2.60≈.77\alpha = (5 \cdot .40) / (1 + 4 \cdot .40) = 2.00 / 2.60 \approx .77. Acceptabel.

d) Items toevoegen geeft hier het grotere effect (+.13+.13 vs +.09+.09). De Spearman-Brown-formule (zie 2.2) maakt dit expliciet: bij gelijke item-kwaliteit kun je de schaal “beter” maken door hem langer te maken.

Inzicht. α\alpha is een functie van twee dingen — schaal-lengte (kk) en item-kwaliteit (r‾\bar{r}). Bij ontwerp-keuzes: weeg af welke bijdrage haalbaar is.

2.2 Split-half + Spearman-Brown

Twee helften, één schaal

“Eerst halveren,” zei de wezel. “Items in twee groepen — als de twee groepen iets meten dat samenhangt, dan meten we hetzelfde.”

Idee: deel de schaal in twee gelijke helften, bereken twee aparte som-scores, correleer ze. Een hoge correlatie = beide helften meten hetzelfde. Probleem: de correlatie is lager dan α\alpha omdat kortere schalen lagere reliability hebben. Spearman-Brown corrigeert hiervoor.

2.2.a Splitsen — het algoritme: matchen op gelijksoortige gemiddelden

Een naïeve splitsing (item 11-55 versus 66-1010) is gevoelig voor systematische verschillen tussen “vroege” en “late” items. Een betere aanpak: items paren op gelijksoortige gemiddelden, dan elk paar splitsen over de twee helften.

Bij dat handmatig matchen hoort een algoritme:

  1. Bereken voor elk item het gemiddelde.
  2. Maak een afstandsmatrix: |Mi−Mj||M_i - M_j| voor elk paar items.
  3. Selecteer iteratief het paar met de kleinste afstand. Markeer beide items als “gepaird”.
  4. Herhaal tot alle items in paren zitten.
  5. Verdeel binnen elk paar willekeurig over helft A en helft B.

Dit is eenvoudiger dan het klinkt. We doen het twee keer — één keer met de hand, één keer in R.

Toon code (item-pair-matching algoritme)
item_means <- sapply(bos_dieren_piekeren[, items], mean, na.rm = TRUE)

# Afstandsmatrix tussen item-means.
dist_matrix <- as.matrix(dist(item_means))
diag(dist_matrix) <- Inf  # eigen-afstand op Inf om zelf-paren te voorkomen.

# Iteratief paren maken.
paren <- list()
ongepairde <- seq_along(items)

set.seed(42)  # voor reproduceerbaarheid van de splitsing.
while (length(ongepairde) >= 2) {
  sub <- dist_matrix[ongepairde, ongepairde, drop = FALSE]
  # Vind paar met kleinste afstand.
  min_idx <- which(sub == min(sub), arr.ind = TRUE)[1, ]
  i <- ongepairde[min_idx[1]]
  j <- ongepairde[min_idx[2]]
  paren[[length(paren) + 1]] <- c(i, j)
  ongepairde <- setdiff(ongepairde, c(i, j))
}

# Splits paren over helft A en helft B (random).
helft_A <- helft_B <- integer(0)
for (p in paren) {
  if (runif(1) < 0.5) {
    helft_A <- c(helft_A, p[1]); helft_B <- c(helft_B, p[2])
  } else {
    helft_A <- c(helft_A, p[2]); helft_B <- c(helft_B, p[1])
  }
}

cat("Helft A:", items[helft_A], "\n")
Helft A: item5_zinloos item1_terugkijken item4_ergevoel item6_loslaten item9_terug 
Toon code (item-pair-matching algoritme)
cat("Helft B:", items[helft_B], "\n")
Helft B: item7_doorzetten_REC item3_anderengedrag item2_nachtgedachten item8_zorgen item10_aanwezigheid 
# Stel: helft A = items 1, 3, 5, 7, 9; helft B = items 2, 4, 6, 8, 10.
# (In praktijk laat je de matching-output beslissen — hier voor reproduceerbaarheid
# zo gefixeerd.)
helft_A <- c("item1_terugkijken",   "item3_anderengedrag",
             "item5_zinloos",       "item7_doorzetten_REC",
             "item9_terug")
helft_B <- c("item2_nachtgedachten","item4_ergevoel",
             "item6_loslaten",      "item8_zorgen",
             "item10_aanwezigheid")
# Twee scores per dier: het gemiddelde over zijn vijf items in helft A, en dat
# over zijn vijf in helft B.
bos_dieren_piekeren$score_A <- rowMeans(bos_dieren_piekeren[, helft_A], na.rm = TRUE)
bos_dieren_piekeren$score_B <- rowMeans(bos_dieren_piekeren[, helft_B], na.rm = TRUE)
# Binnen mutate() heeft rowMeans() een across() nodig om te weten welke
# kolommen hij moet middelen -- `helft_A` is een rijtje namen, en across()
# maakt daar de kolommen zelf van.
bos_dieren_piekeren <- bos_dieren_piekeren |>
  mutate(
    score_A = rowMeans(across(all_of(helft_A)), na.rm = TRUE),
    score_B = rowMeans(across(all_of(helft_B)), na.rm = TRUE)
  )
# use = "complete.obs" laat de dieren weg die op één van de twee helften geen
# score hebben. Zonder die regel geeft cor() gewoon NA terug, zonder te zeggen
# waaróm.
r_half <- cor(bos_dieren_piekeren$score_A,
              bos_dieren_piekeren$score_B,
              use = "complete.obs")
round(r_half, 3)
[1] 0.77
OpmerkingVragen 2.2.a

a) Wat is de split-half-correlatie rhalfr_{\text{half}}?

b) Waarom is deze correlatie lager dan de Cronbach’s α\alpha van de hele schaal?

c) Hoe verandert rhalfr_{\text{half}} als je items random over de helften verdeelt versus matched-pairs verdeelt?

d) Zou de split-half-correlatie hoger of lager worden als je een nieuwe ronde van paren maakt?

a) rhalf=.77r_{\text{half}} = .77 voor déze splitsing. De twee helften hangen sterk samen. Zet er “voor deze splitsing” bij: een andere verdeling van de tien items over twee helften geeft een ander getal, en hoeveel het scheelt zie je in 2.2.c.

b) Lager omdat elk van de twee helften korter is dan de hele schaal. Bij gelijke r‾\bar{r} daalt α\alpha met kk. De full-scale α\alpha kun je terugkrijgen met de Spearman-Brown-correctie (zie 2.2.b).

c) Random: meer variabel; soms verkrijg je toevallig sterke helften, soms zwakke. Matched-pairs: stabieler, want extreme items (te makkelijk of te moeilijk) worden over beide helften verdeeld in plaats van geconcentreerd.

d) Variabel — een andere splitsing geeft een andere rhalfr_{\text{half}}. Vandaar dat psych::splitHalf() alle mogelijke splitsingen berekent en het gemiddelde + min/max rapporteert.

Inzicht. Een enkele split-half is één getal uit een verdeling van mogelijke splits. Echte robuustheid: rapporteer de gemiddelde split-half over alle paren (zie 2.2.c) of gebruik direct α\alpha.

2.2.b Spearman-Brown — corrigeren naar volledige schaal-lengte

De Spearman-Brown-formule corrigeert rhalfr_{\text{half}} naar de betrouwbaarheid die de schaal als geheel zou hebben (alsof beide helften samen worden gebruikt):

rSB=2⋅rhalf1+rhalf r_{\text{SB}} = \frac{2 \cdot r_{\text{half}}}{1 + r_{\text{half}}}

Algemener (voor verlenging met factor nn in plaats van 22):

rSB=n⋅r1+(n−1)⋅r r_{\text{SB}} = \frac{n \cdot r}{1 + (n - 1) \cdot r}

Dezelfde formule die we gebruikten voor αstd\alpha_{\text{std}} — dat is geen toeval. Beide steunen op het idee dat een langere schaal van equivalente items betrouwbaarder is per definitie.

r_half <- cor(bos_dieren_piekeren$score_A,
              bos_dieren_piekeren$score_B,
              use = "complete.obs")

# De formule met n = 2 ingevuld: je maakt de schaal twee keer zo lang als één
# helft, en dus weer even lang als hij oorspronkelijk was. Vandaar de 2 en niet
# de 10 -- je rekent van een halve schaal naar een hele, niet van één item naar
# tien.
r_SB <- 2 * r_half / (1 + r_half)
round(c(r_half = r_half, r_SB = r_SB), 3)
r_half   r_SB 
  0.77   0.87 
OpmerkingVraag T3 — Spearman-Brown handrekenen

Voor elk geval: bereken rSBr_{\text{SB}} en interpreteer.

a) rhalf=.60r_{\text{half}} = .60.

b) rhalf=.85r_{\text{half}} = .85.

c) rhalf=.40r_{\text{half}} = .40 — wat zegt rSBr_{\text{SB}} over de volledige schaal?

d) Een onderzoeker meldt rSB=.92r_{\text{SB}} = .92 na split-half. Wat is dan ongeveer rhalfr_{\text{half}} geweest?

a) rSB=2⋅.60/(1+.60)=1.20/1.60=.75r_{\text{SB}} = 2 \cdot .60 / (1 + .60) = 1.20 / 1.60 = .75.

b) rSB=2⋅.85/(1+.85)=1.70/1.85≈.92r_{\text{SB}} = 2 \cdot .85 / (1 + .85) = 1.70 / 1.85 \approx .92.

c) rSB=2⋅.40/(1+.40)=.80/1.40≈.57r_{\text{SB}} = 2 \cdot .40 / (1 + .40) = .80 / 1.40 \approx .57. Twijfelachtig — ondanks correctie blijft het onder .70.70. Schaal werkt niet goed in deze steekproef.

d) Inverteren: rhalf=rSB/(2−rSB)=.92/1.08≈.85r_{\text{half}} = r_{\text{SB}} / (2 - r_{\text{SB}}) = .92 / 1.08 \approx .85.

Inzicht. Spearman-Brown is een lineaire transformatie die rekening houdt met schaal-verlenging. Geen wonder, geen tovenaarskunst — gewoon de wiskundige consequentie van het feit dat langere schalen meer signaal vangen ten opzichte van ruis.

2.2.c Robuuste split-half — alle splits in één keer

# raw = TRUE laat hem elke afzonderlijke splitsing bewaren in plaats van alleen
# de samenvatting. Dat kost geheugen, maar zonder die schakelaar kun je de
# verdeling van uitkomsten niet zelf natellen -- en juist die verdeling is hier
# het punt.
sh_res <- psych::splitHalf(bos_dieren_piekeren[, items],
                           use = "complete.obs",
                           raw = TRUE)
sh_res
Split half reliabilities  
Call: psych::splitHalf(r = bos_dieren_piekeren[, items], raw = TRUE, 
    use = "complete.obs")

Maximum split half reliability (lambda 4) =  0.9
Guttman lambda 6                          =  0.86
Average split half reliability            =  0.87
Guttman lambda 3 (alpha)                  =  0.87
Guttman lambda 2                          =  0.87
Minimum split half reliability  (beta)    =  0.83
Average interitem r =  0.4  with median =  0.4
                                             2.5% 50% 97.5%
 Quantiles of split half reliability      =  0.84 0.87 0.89
OpmerkingVragen 2.2.c

a) Wat is het gemiddelde van alle mogelijke split-halfs?

b) Wat zijn min en max?

c) De output zet als eerste regel de maximale split-half neer, en verderop het gemiddelde, het minimum en de quantielen. Waarom is dat spreidings-beeld nuttiger dan één enkel getal? En waarom zou je juist die eerste regel niet rapporteren?

d) Hoe verhoudt het gemiddelde split-half zich tot de Cronbach’s α\alpha die je in 2.1.d hebt gefit?

a) r‾SH=.87\bar{r}_{\text{SH}} = .87 — congruent met α\alpha.

b) Min =.83= .83, max =.90= .90, over 126 mogelijke splitsingen. Tussen de ongelukkigste en de gelukkigste splitsing zit dus .07.07 — en het enige wat verschilt is wélke items in welke helft belanden.

c) Omdat één split-half één trekking uit die verdeling is. Het gemiddelde en de quantielen laten zien hoeveel je getal had kunnen schelen; het minimum waarschuwt je voor de ongelukkigste verdeling. De eerste regel van de output — “Maximum split half reliability (lambda 4)” — is juist de gunstigste splitsing van allemaal, uit 126 gekozen omdat hij het hoogste uitkwam. Die rapporteren is jezelf het beste lot uitdelen en dat de betrouwbaarheid van je schaal noemen. Rapporteer het gemiddelde, of α\alpha.

d) Bij schalen die goed werken liggen r‾SH\bar{r}_{\text{SH}} en α\alpha dicht bij elkaar (verschil <.02< .02). Bij divergentie (>.05> .05): vaak een teken van schaal-heterogeniteit (meerdere subschalen vermengd).

Inzicht. Cronbach’s α\alpha is wiskundig gelijk aan het gemiddelde van alle mogelijke split-halfs (Cronbach 1951) — mits je elke split-half berekent met de Rulon-Flanagan-formule (11 min de variantie van het verschil tussen de twee helften, gedeeld door de variantie van de somscore) en de helften even lang zijn. Dat is geen benadering maar een identiteit, en je ziet hem in de output hierboven staan: “Average split half reliability” en “Guttman lambda 3 (alpha)” zijn daar niet ongeveer gelijk maar tot op 16 decimalen hetzelfde getal. En dat terwijl de item-standaarddeviaties in deze schaal uiteenlopen van 1.191.19 tot 1.431.43. Gelijke item-varianties zijn dus géén voorwaarde.

En de andere route dan? In 2.2.a en 2.2.b heb je de split-half anders berekend: als Pearson-rr tussen de twee helften, met Spearman-Brown erachteraan. Doe je dát voor alle 126 splitsingen en neem je het gemiddelde, dan kom je op .8682.8682 tegen α=.8680\alpha = .8680 — dat scheelt .0002. Dus: bij de Rulon-Flanagan-rekenwijze is de gelijkheid exact, bij de Spearman-Brown-route klopt ze bij benadering. Het is dezelfde schaal en dezelfde splitsingen; alleen de rekenwijze verschilt.

2.A Item-deletie — helpt het hier?

Welke items kunnen weg?

“Eerst kijken naar wie er minder bijdraagt,” zei de wezel. “Dan kijken we of we hem kunnen missen.”

Twee handelingen, en de wezel zet ze niet voor niets uit elkaar. Het zwakste item aanwijzen is de eerste. Nagaan of de schaal zonder dat item beter wordt, is de tweede — en het antwoord daarop kan gewoon nee zijn. Dat is geen mislukte analyse maar een uitkomst.

Je doet ze allebei, in deze volgorde.

# Welke items hebben de laagste r.drop? order() geeft je niet de gesorteerde
# waarden maar de PLEKKEN in de gesorteerde volgorde: order(c(30, 10, 20))
# wordt 2 3 1, want de kleinste staat op plek 2. Die plekken zet je dan vóór de
# komma tussen de blokhaken, en zo staan de rijen op orde.
item_stats <- alpha_res$item.stats[, c("raw.r", "r.drop", "mean", "sd")]
round(item_stats[order(item_stats$r.drop), ], 3)
                     raw.r r.drop  mean    sd
item3_anderengedrag  0.584  0.458 3.135 1.427
item4_ergevoel       0.650  0.550 3.095 1.282
item5_zinloos        0.646  0.553 2.980 1.186
item6_loslaten       0.674  0.582 3.065 1.268
item1_terugkijken    0.691  0.603 3.130 1.241
item9_terug          0.691  0.604 3.000 1.224
item2_nachtgedachten 0.702  0.614 3.100 1.272
item10_aanwezigheid  0.701  0.615 2.915 1.243
item7_doorzetten_REC 0.712  0.622 2.980 1.322
item8_zorgen         0.725  0.645 3.080 1.229

Sorteren is de plek waar dplyr het duidelijkst korter is. Je noemt de kolom en klaar; die tussenstap met plekken hoeft niet.

# arrange() zet de rijen op orde, van klein naar groot. Voor andersom zet je
# desc() om de kolom: arrange(desc(r.drop)).
alpha_res$item.stats |>
  select(raw.r, r.drop, mean, sd) |>
  arrange(r.drop) |>
  round(3)
                     raw.r r.drop  mean    sd
item3_anderengedrag  0.584  0.458 3.135 1.427
item4_ergevoel       0.650  0.550 3.095 1.282
item5_zinloos        0.646  0.553 2.980 1.186
item6_loslaten       0.674  0.582 3.065 1.268
item1_terugkijken    0.691  0.603 3.130 1.241
item9_terug          0.691  0.604 3.000 1.224
item2_nachtgedachten 0.702  0.614 3.100 1.272
item10_aanwezigheid  0.701  0.615 2.915 1.243
item7_doorzetten_REC 0.712  0.622 2.980 1.322
item8_zorgen         0.725  0.645 3.080 1.229
# Alpha als elk item eruit gaat. Het minteken vóór de kolom draait de richting
# om, zodat de hoogste alpha-na-weglaten bovenaan komt -- want dát is het item
# waar de vraag over gaat. In dplyr zou je hier arrange(desc(raw_alpha))
# schrijven.
ad <- alpha_res$alpha.drop[, c("raw_alpha", "std.alpha")]
ad <- ad[order(-ad$raw_alpha), ]
round(ad, 3)
                     raw_alpha std.alpha
item3_anderengedrag      0.867     0.867
item4_ergevoel           0.858     0.859
item5_zinloos            0.857     0.859
item6_loslaten           0.855     0.857
item1_terugkijken        0.854     0.855
item9_terug              0.854     0.855
item10_aanwezigheid      0.853     0.854
item2_nachtgedachten     0.853     0.854
item7_doorzetten_REC     0.852     0.854
item8_zorgen             0.850     0.852
OpmerkingVragen 2.A

a) Welk item heeft de laagste rdropr_{\text{drop}}? Wordt α\alpha daadwerkelijk hoger als je het verwijdert?

b) Je hebt bij a) gezien wat er in déze schaal gebeurt. Stel nu even het tegenovergestelde, bij een andere vragenlijst — acht items, α=.79\alpha = .79, en weglaten van één item tilt hem naar .80.80. Zou je het doen?

c) In welk geval zou je een zwak item toch in de schaal houden?

d) Wat is het verschil tussen “het item is een zwak item” en “het item meet iets anders”?

a) item3_anderengedrag heeft de laagste rdropr_{\text{drop}}, namelijk .46.46. Maar op de tweede vraag is het antwoord nee: verwijder je het, dan gaat α\alpha van .8678.8678 naar .8666.8666 — omlaag dus, niet omhoog. Sterker nog: in deze schaal verhoogt geen enkel van de tien items de α\alpha als je het weghaalt (de hoogste alpha.drop is .8666.8666, nog altijd onder de huidige α\alpha). Dat is precies waarom deze vraag zo staat: het zwakste item aanwijzen is één handeling, en nagaan of weghalen echt helpt is een tweede. Wie de eerste voor de tweede aanziet, gooit items weg die de schaal beter maakten.

b) Niet zomaar — en let op dat dit een gedachte-experiment is bij een andere lijst dan die van ons; in onze schaal stijgt α\alpha bij geen enkel item. Zeven items met α=.80\alpha = .80 tegen acht met α=.79\alpha = .79: een kortere schaal die even betrouwbaar meet is winst, want je vraagt je respondent minder. Maar er staat iets tegenover. Dekt dat achtste item een deel van het construct dat de andere zeven niet raken, dan koop je één honderdste α\alpha met een gat in je inhoudelijke dekking. Vraag dus eerst: meet dit item iets dat ik theoretisch belangrijk vind? Zo ja: laten staan, ook bij een lagere rdropr_{\text{drop}}. Een schaal is geen getal dat je maximaliseert.

c) Drie redenen om een zwak item te houden: (1) theoretische dekking — het item meet een aspect dat anders niet wordt gedekt. (2) face-validiteit — of de lijst er voor de invuller uitziet alsof hij meet wat hij beweert te meten. Haal je er de enige vraag uit die een respondent met het onderwerp verbindt, dan krijg je een schaal die vreemd aanvoelt om in te vullen, en dat kost je serieuze antwoorden. (3) historische continuïteit — items meenemen zodat je met eerdere studies kunt vergelijken.

d) Zwak item: meet hetzelfde construct, maar minder duidelijk (meer ruis). Item meet iets anders: zit op een ander construct of factor. Onderscheid door te kijken welke items samen één dimensie vormen: met PCA in thema 4, en met een factoranalyse, de CFA, in thema 5 — bij een multi-dimensionele schaal zijn er meerdere subschalen, en de “zwakheid” kan eigenlijk een andere subschaal blootleggen.

Inzicht. α\alpha vooronderstelt één onderliggende factor. Bij multi-dimensionele schalen onderschat α\alpha de werkelijke betrouwbaarheid van een subschaal. Vandaar dat na alpha-analyse vaak een factoranalyse volgt, exploratief (EFA) of confirmatief (CFA). Dit oefenboek doet de CFA, in thema 5; een EFA komt er niet in.

Dezelfde vraag, andere schaal — de egels

Bij de bosdieren was het antwoord nee. Dat is de gewone uitkomst bij een stel items dat al goed loopt, maar je moet het andere geval één keer van dichtbij hebben gezien, anders herken je het niet als het langskomt.

Een tweede onderzoeker legde 143 egels een korte lijst voor over doorzettingsvermogen — de Egel-Doorzet-Schaal, zes items op een 55-puntsschaal.

kolom de vraag zoals de egel hem las
item1_opnieuw “Als iets niet meteen lukt, probeer ik het nog een keer.”
item2_afmaken “Ik maak af waar ik aan begin.”
item3_andereweg “Loopt het vast, dan zoek ik een andere weg.”
item4_volhouden “Ik houd vol, ook als het lang duurt.”
item5_nietafgeschrikt “Een moeilijke klus schrikt me niet af.”
item6_alleenwerken “Ik werk het liefst alleen.”

Kijk eerst naar die zes zinnen, vóór je iets uitrekent. Vijf ervan vragen naar hetzelfde: blijf je doorgaan als het tegenzit? De zesde vraagt naar iets anders — of je gezelschap prettig vindt bij het werk. Je kunt je voorstellen hoe hij op de lijst is gekomen; wie volhoudt redt zich vaak alleen wel. Maar volhouden en liever alleen zijn twee eigenschappen, en een egel kan de ene hebben zonder de andere.

Dat is een inhoudelijk vermoeden. Nu de cijfers.

load("data/egels_doorzetten.RData")

eds_items <- c("item1_opnieuw", "item2_afmaken", "item3_andereweg",
               "item4_volhouden", "item5_nietafgeschrikt", "item6_alleenwerken")

# check.keys = FALSE ook hier: je wil zien wat de schaal doet zoals hij is
# opgeschreven. Zou psych zelf gaan ompolen, dan repareert hij precies het
# probleem dat je wil bekijken.
alpha_eds <- psych::alpha(egels_doorzetten[, eds_items], check.keys = FALSE)

# Dezelfde drie tabellen als bij de bosdieren, in dezelfde volgorde: eerst de
# schaal als geheel, dan per item, dan wat elk item weglaten zou doen.
round(alpha_eds$total[, c("raw_alpha", "std.alpha", "average_r")], 3)
 raw_alpha std.alpha average_r
     0.762     0.764      0.35
round(alpha_eds$item.stats[, c("raw.r", "r.drop", "mean", "sd")], 3)
                      raw.r r.drop  mean    sd
item1_opnieuw         0.722  0.564 3.322 1.303
item2_afmaken         0.712  0.548 2.720 1.318
item3_andereweg       0.759  0.630 3.622 1.203
item4_volhouden       0.722  0.564 3.063 1.312
item5_nietafgeschrikt 0.751  0.605 3.385 1.305
item6_alleenwerken    0.397  0.160 2.951 1.296
round(alpha_eds$alpha.drop[, c("raw_alpha", "std.alpha")], 3)
                      raw_alpha std.alpha
item1_opnieuw             0.712     0.713
item2_afmaken             0.716     0.718
item3_andereweg           0.696     0.696
item4_volhouden           0.712     0.713
item5_nietafgeschrikt     0.700     0.703
item6_alleenwerken        0.812     0.812
OpmerkingVragen 2.A — vervolg

e) Welk item heeft hier de laagste rdropr_{\text{drop}}? Klopt dat met wat je uit de zes zinnen voorspelde?

f) Wordt α\alpha hoger als je dat item weglaat? Hoeveel, en zou je het doen?

e) item6_alleenwerken, met rdrop=.16r_{\text{drop}} = .16. De andere vijf zitten tussen .55.55 en .63.63 — dat is geen rangorde met een staartje, dat is één item dat er los van staat. En het is precies het item dat je op inhoud al had aangewezen. Dat is de prettige uitkomst: de statistiek bevestigt hier een vermoeden dat je zonder rekenen ook al had.

f) Ja. α\alpha gaat van .7624.7624 naar .8116.8116 — een winst van .0492.0492. En hier vallen de twee bezwaren weg die je normaal tegen weghalen inbrengt. Het eerste is inhoudelijke dekking: haal je een item weg, dan verlies je meestal een stukje van wat je wilde meten. Hier niet — dit item meet doorzettingsvermogen juist níét, dus er valt niets weg. Het tweede is schaallengte: korter meten is meestal onbetrouwbaarder meten. Hier ook niet, want α\alpha gaat omhoog en niet omlaag. Weghalen dus — met in je verslag de reden erbij, en die reden is “dit item meet een ander construct”, niet “α\alpha ging omhoog”.

Let op de rdropr_{\text{drop}}, niet op de winst. Die .16.16 is positief, en dat is geen detail. Was hij negatief geweest, dan had je met een ongepoold item te maken en was het antwoord ompolen — zie 2.1.b — en niet weggooien. Een negatief item is niet waardeloos; het staat achterstevoren.

TipWelk van de twee gevallen heb je voor je?

Je hebt nu allebei gezien, op echte uitvoer:

waar je naar kijkt Bos-Piekeren-Schaal Egel-Doorzet-Schaal
aantal items 10 6
α\alpha .8678.8678 .7624.7624
laagste rdropr_{\text{drop}} .46.46 .16.16
beste α\alpha na weglaten .8666.8666 .8116.8116
verandering in α\alpha −.0012-.0012 (omlaag) +.0492+.0492 (omhoog)
wat je doet laten staan dat ene item eruit

De vuistregel: kijk naar de item-restcorrelatie, niet naar de winst. De winst vertelt je pas achteraf iets, en hij verleidt je tot vissen — laat er eentje weg, kijk of het getal omhoog gaat, herhaal. Zo bouw je een schaal die op jouw steekproef mooi rekent en op de volgende niet meer.

De rdropr_{\text{drop}} vertelt je waarom. Zit een item onder de .30.30 terwijl de rest er ruim boven zit, dan meet het iets anders, en dan heb je een inhoudelijk verhaal dat je kunt opschrijven en verdedigen. Zitten alle items boven de .30.30, zoals bij de bosdieren, dan is er geen zwak item — dan is er een zwákste, en dat is een rangorde en geen oordeel.

En verwacht de eerste situatie vaker dan de tweede. Een schaal die al een paar rondes gebruik en bijslijpen achter zich heeft, geeft meestal precies deze uitkomst: geen enkel item eruit, want alle item-totaalcorrelaties zijn duidelijk positief en geen enkel item maakt α\alpha kleiner. De zwakke items zijn er dan al uit, door wie de schaal maakte. Krijg jij dat resultaat, dan is er niets misgegaan. Je hebt gekeken, en dat is de handeling.

T4 — KR-20 versus α (binaire items)

OpmerkingVraag T4 — Pen-en-papier

KR-20 (Kuder-Richardson formula 20) is de variant van α\alpha voor binaire items (0/1, juist/onjuist).

a) Wat is het structurele verschil tussen α\alpha en KR-20?

b) Wat gebeurt er als je α\alpha uitrekent op binaire items?

c) In welke situatie kies je KR-20 boven α\alpha?

d) Heeft psych::alpha() automatische KR-20-detectie?

a) α\alpha neemt continue items aan (Likert, intervalschaal). KR-20 is identiek aan α\alpha maar gespecialiseerd voor binaire items: vervangt itemvariantie door pi⋅qip_i \cdot q_i (waar pp = proportie correct, q=1−pq = 1 - p). Wiskundig zijn ze dezelfde formule — KR-20 is gewoon α\alpha toegepast op 0/10/1-items.

b) Hetzelfde resultaat. Op binaire items reduceert α\alpha-formule naar KR-20. Geen verschil — andere naam, dezelfde berekening.

c) Geen praktische keuze meer in moderne software. Conventie blijft: bij binaire (juist/onjuist, ja/nee) items rapporteer je KR-20; bij Likert Cronbach’s α\alpha. Inhoudelijk dezelfde maat.

d) Ja — psych::alpha() werkt op binaire én continue data. Je hoeft niet expliciet KR-20 te kiezen.

Inzicht. KR-20 is een historisch artefact uit de tijd vóór computers. Vandaag: gewoon α\alpha. Ken de term voor papers uit de jaren 19501950-19801980.

T5 — Item-totaal-correlatie interpretatie

OpmerkingVraag T5 — Pen-en-papier

In een schaal-analyse rapporteert een onderzoeker:

Item   raw.r   r.drop
A      0.60    0.50
B      0.75    0.65
C      0.55    0.40
D      0.85    0.80

a) Welk item is het sterkst gerelateerd aan de totaalscore?

b) Welke is het zwakst?

c) Wat is het verschil tussen raw.r en r.drop?

d) Welke moet je primair rapporteren?

a) Item D (rdrop=.80r_{\text{drop}} = .80) — sterkst.

b) Item C (rdrop=.40r_{\text{drop}} = .40) — zwakst.

c) raw.r: correlatie tussen item en totaalscore inclusief het item zelf. r.drop: correlatie tussen item en totaalscore zonder het item (gecorrigeerde item-totaal-correlatie). De r.drop is altijd lager dan raw.r omdat het zelf-effect is verwijderd.

d) r.drop — anders is de correlatie kunstmatig opgeblazen door het zelf-effect (item correleert met zichzelf via de som-score).

Vuistregel. Items met rdrop<.30r_{\text{drop}} < .30 zijn kandidaat voor herziening of verwijdering. rdrop≥.50r_{\text{drop}} \geq .50 is goed.

T6 — Item-deletie en α-verbetering

OpmerkingVraag T6 — Pen-en-papier

Een schaal met k=5k = 5 items heeft α=.65\alpha = .65. De alpha.drop-output toont:

Item drop   alpha-na-deletie
A             .70
B             .60
C             .55
D             .62
E             .68

a) Welk item is het zwakste — verwijdering geeft de grootste α\alpha-stijging?

b) Welk item is het sterkste — verwijdering geeft de grootste α\alpha-daling?

c) Stel je verwijdert item A. Wat is de nieuwe α\alpha + nieuwe schaallengte?

d) Is het altijd een goed idee om het zwakste item te verwijderen?

a) Item A — verwijdering verhoogt α\alpha van .65.65 naar .70.70. Sterkste verbetering.

b) Item C — verwijdering verlaagt α\alpha naar .55.55. Sterkste daling = sterkste bijdrage aan schaal.

c) Nieuwe α=.70\alpha = .70, k=4k = 4. Iets minder data, iets betere internal consistency.

d) Nee — drie tegenargumenten: (1) Content-validiteit kan verloren gaan. (2) α\alpha kan stabieler zijn met meer items ondanks lagere rr. (3) Verlies van power voor follow-up-toetsen omdat schaal-variantie daalt.

Inzicht. α\alpha-stijging is één criterium, niet het criterium. Theoretische verdediging blijft de beste basis voor item-keuze.

T7 — Wat is een “goede” α?

OpmerkingVraag T7 — Pen-en-papier

Voor elk gebruik: welke α\alpha-drempel is gepast?

a) Een onderzoeker gebruikt een schaal als groep-niveau-uitkomst in een experiment.

b) Een psychiater gebruikt een schaal-score om individuele beslissingen over medicatie te nemen.

c) Een student gebruikt een nieuwe schaal in haar bachelorscriptie, voor exploratief onderzoek.

d) Een toegelaten testbatterij voor neuropsychologische diagnose.

a) α≥.70\alpha \geq .70. Bij groepsniveau-vergelijkingen middelen ruisstoringen uit; iets hogere ondergrens dan strikte .80.80 niet absolute eis.

b) α≥.90\alpha \geq .90. Individueel-niveau-beslissingen vereisen lage measurement-error per persoon. sem=SD⋅1−𝛼se_{\text{m}} = SD \cdot \sqrt{1 - \mathit{\alpha}} — bij lage α\alpha is semse_{\text{m}} groot, en individuele scores onbetrouwbaar.

c) α≥.70\alpha \geq .70 als doel. Bij nieuwe schaal in exploratie kan α=.60\alpha = .60-.70.70 acceptabel zijn als alle andere items goed werken; rapporteer met expliciete waarschuwing.

d) α≥.90\alpha \geq .90, ofwel reëel >.85> .85 met grote NN + diverse populatie. Diagnostiek vereist ondergrens hoog.

Inzicht. Hoe hoger de individuele consequentie, hoe hoger de α\alpha-eis. Groepsniveau-onderzoek mag iets soepeler; individuele beslissingen vereisen strenger.

T8 — De standaardmeetfout

Tot nu toe ging alles over de schaal: is die betrouwbaar genoeg. De standaardmeetfout standard error of measurement vertaalt dat naar één persoon. Hij zegt hoe ver iemands geobserveerde score gemiddeld naast zijn ware score valt — en dus hoe breed de band is waarbinnen je die ware score mag vermoeden.

sem=SD⋅1−𝛼 se_{\text{m}} = SD \cdot \sqrt{1 - \mathit{\alpha}}

Een betrouwbare schaal (α\alpha dicht bij 11) laat weinig over onder dat wortelteken, en dan is de fout klein. Kijk wat er aan de uiterste gebeurt: een schaal die niks meet heeft α=0\alpha = 0, en dan is 1−0=1\sqrt{1 - 0} = 1, dus sem=SDse_{\text{m}} = SD. Bij SD=10SD = 10 wordt de band rond een score dan ±1.96⋅10\pm 1.96 \cdot 10, oftewel bijna 4040 punten breed — even breed als de hele groep. Die ene score vertelt je dan niets meer dan de groep zelf.

TipWaarom kleine letters, en niet SEM

Er zijn twee “standaardfouten” die op elkaar lijken en over verschillende dingen gaan. De standaardfout van het gemiddelde zegt hoe ver een steekproefgemiddelde naast het populatiegemiddelde ligt — dat gaat over een gemiddelde van veel mensen. De standaardmeetfout gaat over de score van één persoon. En allebei worden ze SEM afgekort — sterker nog, in thema 4 en 5 staan dezelfde drie letters voor weer iets anders.

Die drie letters zeggen je dus niet wat er bedoeld wordt. Een subscript wel, en dat is waarom dit hoofdstuk semse_{\text{m}} schrijft en niet SEM. Kom je elders wél een kale ss tegen, lees hem dan als de ss van de error — met dat e’tje eronder, ses_{\text{e}}. Niet te verwarren met de standaardfout van het gemiddelde; dat is iets anders.

Elders staat deze som soms met andere symbolen:

sem=se=so1−Rxx se_{\text{m}} = s_{\text{e}} = s_{\text{o}} \sqrt{1 - R_{xx}}

Dat is geen andere formule maar dezelfde, in een andere notatie. Van links naar rechts, na de semse_{\text{m}} die je al kent:

  • ses_{\text{e}} — de s van de error: de standaardafwijking van de meetfouten. Dat ís de standaardmeetfout, niet iets wat eraan gelijk blijkt te zijn; het gelijkteken staat er omdat het twee namen voor één ding zijn.
  • sos_{\text{o}} — de s van de observed scores: de standaardafwijking van de scores zoals je ze gemeten hebt. Dat is wat wij SDSD noemen. Let op wélke: bij een schaal is dat de SDSD van de somscore over alle items, niet die van een los item.
  • RxxR_{xx} — de betrouwbaarheid van de test, hóé je hem ook geschat hebt: met split-half, met test-hertest, of met Cronbach’s α\alpha. In dit hoofdstuk schatten we hem met α\alpha, dus daar mag je α\alpha invullen.

Zie je ergens Rxx=.80R_{xx} = .80 staan, dan is dat dus hetzelfde getal als de α=.80\alpha = .80 in de opgave hierna.

OpmerkingVraag T8 — Pen-en-papier

Voor een schaal met SD=10SD = 10 en α=.80\alpha = .80:

a) Bereken semse_{\text{m}}.

b) Een persoon scoort X=65X = 65 op T-score-schaal. Wat is het 95%95\%-betrouwbaarheidsinterval rond zijn ware score?

c) Bij α=.95\alpha = .95 wat zou semse_{\text{m}} worden? En het CI?

d) Welke implicatie heeft een hoge semse_{\text{m}} voor klinische beslissingen?

a) sem=10⋅1−.80=10⋅0.20=10⋅0.4472=4.472≈4.47se_{\text{m}} = 10 \cdot \sqrt{1 - .80} = 10 \cdot \sqrt{0.20} = 10 \cdot 0.4472 = 4.472 \approx 4.47.

b) 95%95\%-CI: X±1.96⋅sem=65±1.96⋅4.472=65±8.77=[56.23,73.77]X \pm 1.96 \cdot se_{\text{m}} = 65 \pm 1.96 \cdot 4.472 = 65 \pm 8.77 = [56.23, 73.77]. Brede band. Die 1.961.96 is de zz-waarde die 9595 procent van een normale verdeling tussen zich in heeft.

c) Bij α=.95\alpha = .95: sem=10⋅1−.95=10⋅0.05=10⋅0.2236=2.236≈2.24se_{\text{m}} = 10 \cdot \sqrt{1 - .95} = 10 \cdot \sqrt{0.05} = 10 \cdot 0.2236 = 2.236 \approx 2.24. CI: X±1.96⋅2.236=65±4.38=[60.62,69.38]X \pm 1.96 \cdot 2.236 = 65 \pm 4.38 = [60.62, 69.38]. Aanzienlijk smaller.

d) Bij hoge semse_{\text{m}}: de score van een individu is een schatting met grote onzekerheid. Cliënt scoort T=65T = 65 (α=.80\alpha = .80): we zijn 95%95\% zeker dat zijn echte T-score tussen 5656 en 7474 ligt — dat valt deels onder en deels boven de “verhoogd”-cutoff. Klinische beslissing op zo’n schatting is gevaarlijk.

Inzicht. α\alpha rapporteren zonder semse_{\text{m}} erbij is incompleet. De standaardmeetfout vertaalt α\alpha naar wat het betekent voor de individuele score. Voor klinisch gebruik altijd allebei rapporteren.

T9 — Reliability bij kleine n

OpmerkingVraag T9 — Pen-en-papier

Een onderzoeker meet bij N=30N = 30 deelnemers een 55-item-schaal en rapporteert α=.82\alpha = .82.

a) Wat is je voornaamste zorg?

b) Wat is een redelijke methode om de onzekerheid te kwantificeren?

c) Stel het 95%95\%-bootstrap-CI is [.65,.92][.65, .92]. Wat zegt dat?

d) Mag deze schaal gebruikt worden voor klinische beslissingen?

a) Steekproef-grootte N=30N = 30 is te klein voor stabiele α\alpha-schatting. Vuistregel: N≥100N \geq 100 voor schaal-validatie. Bij N=30N = 30 is het CI rond α\alpha breed; één getal is misleidend.

b) Bootstrap-CI rond α\alpha. psych::alpha(mijn_data[, items], n.iter = 1000) of een eigen bootstrap; het interval staat daarna in res$boot.ci. Geeft een interval in plaats van een puntschatting.

c) Het CI loopt van .65.65 (twijfelachtig) tot .92.92 (uitstekend). De ware α\alpha kan dus overal in dat bereik liggen. Het puntschattings-getal .82.82 overdrijft de zekerheid.

d) Nee, niet zonder grotere validatie-studie. Bij N=30N = 30 en deze brede onzekerheid is klinisch gebruik onverantwoord. Onderzoek-gebruik op groepsniveau (met expliciete waarschuwing): mogelijk.

Inzicht. α\alpha als puntschatting verbergt de onzekerheid. Bij kleine NN rapporteer je het bootstrap-CI mee.

T10 — Test-retest versus internal consistency

OpmerkingVraag T10 — Pen-en-papier

Een schaal heeft α=.92\alpha = .92 (excellent internal consistency) maar rretest=.55r_{\text{retest}} = .55 (test-retest, 66 weken interval).

a) Wat suggereert dit patroon over de schaal?

b) Welke factor kan dit verklaren?

c) Welk type reliability is voor trait-meting belangrijker?

d) Welk type voor state-meting?

a) De schaal meet iets consistents binnen een meetmoment (alle items hangen sterk samen) maar dat ene-iets is niet stabiel over tijd (rretest=.55r_{\text{retest}} = .55 is matig).

b) Drie verklaringen: (1) State-construct — de schaal meet iets dat fluctueert (bv. acute angst, momentane stemming). Internal consistency is hoog (op één moment); retest is laag (op twee momenten). (2) Echte verandering — bv. interventie tussen t0t_0 en t1t_1. (3) Meet-instrument-instabiliteit — onwaarschijnlijk bij hoge α\alpha, want dan zou de within-moment-meting ook ruisen.

c) Test-retest — een trait is per definitie stabiel; meet-instrument moet die stabiliteit reproduceren.

d) Internal consistency — een state is per definitie fluctuatie; binnen-moment-stabiliteit is wat je test, niet over-tijd-stabiliteit.

Inzicht. α\alpha alleen vertelt het verhaal niet. Voor traits: α\alpha + test-retest. Voor states: α\alpha + (eventueel) experience sampling reliability.

Examen-stijl vragen

Vier kortere oefeningen plus één mini-practical

OpmerkingVraag E1 — α-output interpreteren
Reliability analysis (psych::alpha)
  raw_alpha  std.alpha   G6(smc)   average_r
       0.78       0.79      0.81        0.43

Item statistics (per item):
       n   raw.r   r.drop
i1   200    0.60    0.45
i2   200    0.65    0.52
i3   199    0.42    0.25
i4   200    0.71    0.58
i5   200    0.66    0.53

Welke conclusie is het meest correct?

  1. De schaal heeft uitstekende internal consistency.
  2. Item 3 is een zwak item (rdrop=.25r_{\text{drop}} = .25) — kandidaat voor verwijdering.
  3. Item 4 is het zwakste item.
  4. De schaal heeft te kleine NN voor α\alpha-schatting.

b) Item 3 heeft rdrop=.25r_{\text{drop}} = .25, onder de .30.30-drempel. De andere items hebben rdropr_{\text{drop}} tussen .45.45-.58.58. Dit maakt item 3 een duidelijke kandidaat voor herziening of verwijdering.

Optie a: α=.78\alpha = .78 is “acceptabel”, niet “uitstekend” (≥.90\geq .90). Optie c: item 4 heeft de hoogste rdropr_{\text{drop}}, niet de laagste — dus het is het sterkste, niet het zwakste. Optie d: N=200N = 200 is ruim genoeg voor α\alpha-schatting.

OpmerkingVraag E2 — Spearman-Brown handrekenen

In een split-half-analyse vond een onderzoeker rhalf=.72r_{\text{half}} = .72. Welke is de Spearman-Brown gecorrigeerde betrouwbaarheid?

  1. rSB=.77r_{\text{SB}} = .77
  2. rSB=.84r_{\text{SB}} = .84
  3. rSB=.89r_{\text{SB}} = .89
  4. rSB=.72r_{\text{SB}} = .72 (geen correctie nodig)

b) rSB=2⋅.72/(1+.72)=1.44/1.72≈.84r_{\text{SB}} = 2 \cdot .72 / (1 + .72) = 1.44 / 1.72 \approx .84.

Optie a (.77) en c (.89) zijn rekenfouten. Optie d miskent dat split-half altijd correctie vereist (twee helften zijn samen kortere schalen dan de hele schaal).

OpmerkingVraag E3 — α-na-deletie interpreteren

Een schaal met k=6k = 6 items toont:

Item   alpha-na-deletie
i1                .80
i2                .82
i3                .79
i4                .85   ← hoogste
i5                .81
i6                .80

De huidige α=.81\alpha = .81. Welke conclusie?

  1. Verwijdering van item 4 zou de schaal aanzienlijk verbeteren — overweeg eruit halen.
  2. Item 4 is het sterkste item — bewaar zeker.
  3. Alle items zijn equivalent.
  4. De schaal werkt niet (alle alphas onder .90).

a) Verwijdering van item 4 zou α\alpha verhogen van .81.81 naar .85.85 — een kleine maar reële winst. Plus: een hogere alpha-na-deletie wijst erop dat item 4 minder samenhangt met de rest dan de andere items. Theoretische check vereist (b is omgekeerd: lager item-na-deletie = sterker bijdragend).

Optie b: omgekeerd. Hoger alpha-na-deletie = item is zwak, niet sterk. Optie c: variatie van .79.79-.85.85 is niet equivalent. Optie d: α=.81\alpha = .81 is goed, niet “werkt niet”.

OpmerkingVraag E4 — De standaardmeetfout en het CI

Een schaal heeft SD=12SD = 12 en α=.85\alpha = .85 in een steekproef van N=250N = 250. Een cliënt scoort X=60X = 60.

a) Bereken semse_{\text{m}}.

b) Bouw een 95%95\%-CI rond zijn ware score.

c) Klopt de score “6060” als precieze waarde, of is het een schatting?

a) sem=12⋅1−.85=12⋅0.15=12⋅0.3873≈4.65se_{\text{m}} = 12 \cdot \sqrt{1 - .85} = 12 \cdot \sqrt{0.15} = 12 \cdot 0.3873 \approx 4.65.

b) 95%95\%-CI: 60±1.96⋅4.65≈60±9.1=[50.9,69.1]60 \pm 1.96 \cdot 4.65 \approx 60 \pm 9.1 = [50.9, 69.1].

c) Schatting. De waarheid van zijn ware score ligt 95%95\%-zeker in [51,69][51, 69] — een aanzienlijke band. Een score van exact 6060 is misleidend; rapporteer altijd X±semX \pm se_{\text{m}} of een CI.

R-practical opdrachtje

De pissebed onder de steen — opnieuw

OpmerkingVraag E5 — Mini-reliability bij de pissebed

Een ecoloog meet bij 7070 pissebedden hun emotie-regulatie via zes items op een 55-puntsschaal. De dataset staat in data/pissebed_emotie.RData en bevat het object pissebed_emotie met pissebed_id plus peb1 t/m peb6. Sla je R-commando’s op in één scriptbestand: pissebed.R.

a) Bereken Cronbach’s α\alpha (raw + standardized) plus item-totaal-correlaties.

b) Welk item is het zwakst? Wat is het effect op α\alpha als je het verwijdert?

c) Voer een split-half analyse uit met psych::splitHalf(). Wat is de gemiddelde split-half-correlatie?

d) Bereken semse_{\text{m}} voor de schaal. Let op welke SDSD daarin hoort: die van de somscore over de zes items (bereik 66 tot 3030), en die reken je zelf uit de data — niet die van een los item. Bouw daarna een 95%95\%-CI rond een score van X=24X = 24.

Schrijf één APA-zin met je conclusie over de betrouwbaarheid.

load("data/pissebed_emotie.RData")
str(pissebed_emotie)
'data.frame':   70 obs. of  7 variables:
 $ pissebed_id: Factor w/ 70 levels "p01","p02","p03",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ peb1       : num  5 3 3 5 4 2 4 4 1 3 ...
 $ peb2       : num  2 1 3 4 5 3 3 3 2 5 ...
 $ peb3       : num  4 1 3 4 5 2 3 3 2 5 ...
 $ peb4       : num  4 1 3 2 5 3 3 3 2 4 ...
 $ peb5       : num  5 4 3 1 4 2 3 4 4 4 ...
 $ peb6       : num  4 2 3 3 3 2 3 3 3 5 ...
# paste0() plakt tekst aan elkaar: paste0("peb", 1) wordt "peb1". Geef je hem
# een rijtje mee -- 1:6 is 1 2 3 4 5 6 -- dan doet hij het voor elk getal en
# krijg je "peb1" tot "peb6" terug. Zo hoef je zes namen niet met de hand over
# te tikken, en vertik je je ook niet.
peb_items <- paste0("peb", 1:6)

alpha_peb <- psych::alpha(pissebed_emotie[, peb_items], check.keys = FALSE)
round(alpha_peb$total[, c("raw_alpha", "std.alpha", "average_r")], 3)
 raw_alpha std.alpha average_r
     0.766     0.769     0.356
round(alpha_peb$item.stats[, c("raw.r", "r.drop", "mean", "sd")], 3)
     raw.r r.drop  mean    sd
peb1 0.681  0.517 3.157 1.199
peb2 0.707  0.555 3.186 1.183
peb3 0.641  0.437 2.786 1.350
peb4 0.678  0.501 3.171 1.274
peb5 0.704  0.541 3.200 1.246
peb6 0.673  0.517 3.114 1.136
round(alpha_peb$alpha.drop[, c("raw_alpha", "std.alpha")], 3)
     raw_alpha std.alpha
peb1     0.730     0.735
peb2     0.721     0.724
peb3     0.753     0.753
peb4     0.734     0.736
peb5     0.724     0.726
peb6     0.731     0.734
# splitHalf() rekent niet één splitsing maar alle mogelijke, en geeft je het
# gemiddelde plus de uitersten. Het getal dat de vraag wil is de gemiddelde
# split-half; de rest van de uitvoer mag je laten liggen.
sh_peb <- psych::splitHalf(pissebed_emotie[, peb_items], use = "complete.obs")
sh_peb
Split half reliabilities  
Call: psych::splitHalf(r = pissebed_emotie[, peb_items], use = "complete.obs")

Maximum split half reliability (lambda 4) =  0.84
Guttman lambda 6                          =  0.75
Average split half reliability            =  0.77
Guttman lambda 3 (alpha)                  =  0.77
Guttman lambda 2                          =  0.77
Minimum split half reliability  (beta)    =  0.71
Average interitem r =  0.36  with median =  0.38
# De standaardmeetfout hoort bij de som-score, dus ook de SD van de som-score
# -- uit de data, niet uit een aanname over hoe breed een 6-item-schaal
# "meestal" ligt. De variabele heet se_m, zoals de standaardmeetfout in dit
# hoofdstuk heet; een R-naam kan geen subscript, dus het onderstreepje doet dat werk.
SD_sum <- sd(rowSums(pissebed_emotie[, peb_items]))
alpha_raw <- alpha_peb$total$raw_alpha

se_m <- SD_sum * sqrt(1 - alpha_raw)

# De 24 staat er als los getal omdat de vraag hem geeft: bouw een interval rond
# een score van X = 24. Die 24 volgt dus niet uit de data en hoort er ook niet
# uit te komen. 1.96 is de z-waarde die 95 procent van een normale verdeling
# tussen zich in heeft.
CI_low  <- 24 - 1.96 * se_m
CI_high <- 24 + 1.96 * se_m
round(c(SD = SD_sum, alpha = alpha_raw, se_m = se_m,
        CI_low = CI_low, CI_high = CI_high), 2)
     SD   alpha    se_m  CI_low CI_high 
   5.03    0.77    2.43   19.24   28.76 

a) αraw=.77\alpha_{\text{raw}} = .77, αstd=.77\alpha_{\text{std}} = .77. Item-totaal-correlaties tussen rdrop=.44r_{\text{drop}} = .44 (peb3, zwakste) en rdrop=.55r_{\text{drop}} = .55 (peb2, sterkste).

b) peb3 is het zwakst. Verwijdering levert géén winst op: α\alpha zakt van .77.77 naar .75.75. Net als bij de bosdieren geldt: zwakste item ≠\neq item dat weg moet. En in een 66-item-schaal kost weghalen bovendien inhoudelijke dekking; dat verdedig je theoretisch vóór je het doet, niet achteraf.

c) Gemiddelde split-half =.77= .77, congruent met α\alpha.

d) sem=SDsom⋅1−𝛼=5.025⋅0.234=2.43se_{\text{m}} = SD_{\text{som}} \cdot \sqrt{1 - \mathit{\alpha}} = 5.025 \cdot \sqrt{0.234} = 2.43. CI rond X=24X = 24: 24±4.76=[19.24,28.76]24 \pm 4.76 = [19.24, 28.76].

Drie decimalen in de tussenstappen, en dat is geen slordigheid maar het punt: met SD=5.03SD = 5.03 en 0.23\sqrt{0.23} tikt je rekenmachine 2.412.41 uit, en dan denk je dat je je vergist hebt. Een uitgeschreven som moet kloppen met de getallen die er staan.

Bij N=70N = 70 pissebedden vertoonde de zes-item emotie-regulatie-schaal acceptabele internal consistency, Cronbach’s α = .77 (raw), r‾=.36\bar{r} = .36. Item-totaal-correlaties (gecorrigeerd) varieerden van rdrop=.44r_{\text{drop}} = .44 (peb3) tot rdrop=.55r_{\text{drop}} = .55 (peb2). De gemiddelde split-half-correlatie (rSH=.77r_{\text{SH}} = .77) bevestigde de α-schatting. De standaardmeetfout op de som-schaal (sem=2.43se_{\text{m}} = 2.43) levert een 95%95\%-CI van ±4.76\pm 4.76 punten rond een individuele score.

R-spiekblad — van ruwe data tot rapportage

# 1. Pakketten + data laden ---------------------------------------------
library(tidyverse)
library(psych)

load("data/bos_dieren_piekeren.RData")

# Originele items-vector (item7_doorzetten = ongepoold).
items_orig <- c("item1_terugkijken", "item2_nachtgedachten", "item3_anderengedrag",
                "item4_ergevoel",    "item5_zinloos",        "item6_loslaten",
                "item7_doorzetten",  "item8_zorgen",         "item9_terug",
                "item10_aanwezigheid")

# 2. Verkenning — item-statistieken ------------------------------------
round(cor(bos_dieren_piekeren[, items_orig], use = "complete.obs"), 2)
# >>> let op: item7_doorzetten heeft NEGATIEVE correlaties — moet ompool

# 3. Ompolen (handmatig, route 1) --------------------------------------
bos_dieren_piekeren$item7_doorzetten_REC <- 6 - bos_dieren_piekeren$item7_doorzetten

items <- c("item1_terugkijken", "item2_nachtgedachten", "item3_anderengedrag",
           "item4_ergevoel",    "item5_zinloos",        "item6_loslaten",
           "item7_doorzetten_REC", "item8_zorgen",      "item9_terug",
           "item10_aanwezigheid")

# 4. Cronbach's alpha + item-stats (op omgepoolde data) ----------------
res <- psych::alpha(bos_dieren_piekeren[, items], check.keys = FALSE)
res$total       # alpha raw + std + average_r
res$item.stats  # raw.r, r.drop per item
res$alpha.drop  # alpha als item-eruit

# 5. Split-half + Spearman-Brown ---------------------------------------
helft_A <- items[c(1, 3, 5, 7, 9)]
helft_B <- items[c(2, 4, 6, 8, 10)]

score_A <- rowMeans(bos_dieren_piekeren[, helft_A], na.rm = TRUE)
score_B <- rowMeans(bos_dieren_piekeren[, helft_B], na.rm = TRUE)

r_half <- cor(score_A, score_B, use = "complete.obs")
r_SB   <- 2 * r_half / (1 + r_half)
c(r_half = r_half, r_SB = r_SB)

# Robuust over alle splits.
sh_res <- psych::splitHalf(bos_dieren_piekeren[, items], use = "complete.obs")
sh_res

# 6. Standaardmeetfout en betrouwbaarheids-interval -------------------
SD_sum <- sd(rowSums(bos_dieren_piekeren[, items], na.rm = TRUE))
alpha  <- res$total$raw_alpha

# se_m: de standaardmeetfout, zoals hij in dit hoofdstuk heet. Een R-naam kan
# geen subscript, dus het onderstreepje doet dat werk.
se_m <- SD_sum * sqrt(1 - alpha)
se_m

# Voor één score X: CI = X +/- 1.96 * se_m.
X <- 35
c(CI_low = X - 1.96 * se_m, CI_high = X + 1.96 * se_m)

# 7. Item-deletie iteratief ------------------------------------------
# Welk item zou je weghalen als je alpha wil maximaliseren?
ad <- res$alpha.drop[, c("raw_alpha", "std.alpha")]
ad[order(-ad$raw_alpha), ]

Wat blijft liggen

Onderwerpen die buiten dit thema blijven

Cronbach’s α\alpha + split-half + Spearman-Brown is de hoofdingang. Voor verdere studie:

  • McDonald’s ω\omega — robuuster dan α\alpha bij multi-dimensionele schalen. psych::omega(). Aanbevolen alternatief.
  • Bootstrap-CI’s voor α\alpha — bij kleine NN. psych::alpha(..., n.iter = 1000), interval in $boot.ci.
  • Generaliseerbaarheids-theorie (G-theory) — variantie-decompositie over meerdere meetfacetten (rater, item, gelegenheid). Cronbach et al. (1972).
  • Reliability bij IRT — informatie-functie in plaats van α\alpha. Komt thema 6.
  • Test-equating — twee versies van een test op gelijke schaal brengen. Lord (1980).
  • Inter-rater reliability — een volwaardige vorm van betrouwbaarheid, die dit oefenboek niet behandelt: stemmen twee beoordelaars overeen die hetzelfde object scoren? Je hebt er andere maten voor nodig dan α\alpha — Cohen’s κ\kappa bij een categorisch oordeel, Fleiss’ κ\kappa bij meer dan twee beoordelaars, en de ICC bij continue scores.

Voor verdieping: Crocker & Algina (1986); Streiner, Norman & Cairney (2015, Health Measurement Scales); Cronbach (1951, Coefficient alpha and the internal structure of tests).

Aan het eind van de dag

De wezel keek tevreden — voor zijn doen, wat betekent: niet ontevreden.

“α=.87\alpha = .87,” zei hij. “Goed genoeg. En nee, item 3 mag er niet uit — ik heb het nagekeken, de schaal wordt er niet beter van. Zwakste is niet hetzelfde als slecht.”

“En de meetfout?” vroeg de bunzing.

“Klein genoeg voor onderzoek, te groot voor klinische individuele beslissing op één score.” Hij zweeg. “Tweede meting eroverheen helpen, of een schaal met α>.90\alpha > .90.”

“En morgen?”

“Validity,” zei de wezel. “Of dit construct eigenlijk wel meet wat we beweren te meten. Je kunt iets perfect betrouwbaar verkeerd meten. Daar gaan we het over hebben.”

De vos keek nieuwsgierig op vanuit de schaduw — hij was al langs voor zijn eigen hoofdstuk. “Validity? Mooi. Iemand moet die boel eens uitpluizen.”

De bunzing knikte en kroop weg. Boven het bos werd het donker, en de wezel deed zijn ogen halfdicht zonder iets te zeggen.

Verantwoording

Dit oefenboek is geschreven voor studenten die psychometrie leren via R. Het is materiaal van CountCamp, geen officieel onderdeel van een opleiding. De voorbeelden, datasets, vragen en formuleringen zijn origineel; de didactische volgorde is dat bewust niet — die volgt de gangbare opbouw van Nederlandse universitaire psychometrie-cursussen. De gebruikte drempels en formules zijn standaard psychometrische conventies; verwijzingen naar Cronbach (1951), Crocker & Algina (1986) en Streiner, Norman & Cairney (2015) volgen de gebruikelijke citaatpraktijk in dit veld.

Waar dit thema een eigen weg gaat. Eigen keuze is de NA-drempel uit thema 1, die hier ook geldt: hoogstens één ontbrekende waarde. Ook eigen keuze is dat je interbeoordelaarsbetrouwbaarheid hier niet leert uitrekenen: je hoeft hem alleen te herkennen aan het patroon twee beoordelaars, één object, en welke maten je ervoor zou gebruiken staat achterin bij Wat blijft liggen. Die maten — Cohen’s κ\kappa, de ICC — zijn een hoofdstuk op zich, en dit thema gaat over de samenhang binnen een schaal en tussen twee afnames, niet tussen twee beoordelaars. En de standaardmeetfout heet hier semse_{\text{m}} en niet SEM, omdat die drie hoofdletters in thema 4 en 5 voor iets anders staan en een subscript wél zegt wat er bedoeld wordt; andere boeken schrijven dezelfde grootheid als ses_{\text{e}}, en die vertaling staat bij de opgave over de standaardmeetfout. Het subscript zetten wij rechtop, ook waar andere boeken hem schuin zetten: het is een naampje — de m van measurement — en geen variabele.

Zegt ander materiaal dat je gebruikt iets anders dan dit oefenboek, reken dan met wat daar staat. Meestal is het verschil een afspraak — een drempel, een letter, de naam van een model — en geen rekenfout.

Versie: oktober 2026 — CountCamp Lab

Terug naar boven