Basishandelingen in JASP

de gereedschapskist — slepen en R naast elkaar

Waarvoor deze pagina is: de handelingen die ónder elke analyse liggen. Een kolom bijmaken, een kolom anders indelen, een nulpunt verschuiven. Geen les — naslag. Je slaat hem open op het moment dat een oefening erom vraagt, en klapt hem daarna weer dicht.

Deze kist is nog niet vol. Er staan nu twee handelingen in: hercoderen en centreren. Mis je iets — inlezen, filteren, samenvatten — kijk dan zolang in de gereedschapskist van het R-broertje; de handeling is daar dezelfde, alleen de knoppen zijn anders.

Alles hieronder draait op de diamantjes: de twaalf steentjes uit het boek. Twaalf rijen die je in één blik overziet, en genoeg kolommen om alles op te oefenen.

⬇ Download de data — diamantjes.csv

kolom wat
naam Anna, Bram, Cees … Leen
karaat gewicht van het steentje
glans 0–100
gladheid 0–10, hoe goed geslepen
merk golfje of sterretje
D 1 als het een sterretje is, anders 0
DxG D × gladheid — het product, voor moderatie
gepakt 1 als de kraai het steentje die nacht oppakte, anders 0
mooi 1 als de glans boven de 50 ligt, anders 0

Dat is het kortste lijstje, genoeg om verder te kunnen. Wil je van dit bestand of van een van de andere weten waar het vandaan komt, wat de eenheid is en wat er precies in staat, sla dan De datasets op.

Twee routes, één handeling

JASP is een klikprogramma, maar er zit een achterdeur naar R in — en die staat gewoon open. Elke berekende kolom begint hetzelfde: klik op de + helemaal rechts van je gegevens, naast de laatste kolom. Je vult een naam in, kiest een gegevenstype, en kiest dan één van twee icoontjes:

  • het handje — de sleep-route. Je bouwt de regel uit blokjes die je uit de lijsten aan de rand naar het midden trekt. Typefouten in kolomnamen kun je zo niet maken, want je typt ze niet.
  • de R — het R-vak. Je schrijft de regel als één R-uitdrukking.

Daarna klik je Create, en als de regel staat: Compute column. Wil je later iets veranderen aan een kolom die je al gemaakt hebt, klik dan op het fx-symbooltje in de kolomkop; dan ga je het venster weer in.

Beide routes maken exact dezelfde kolom. Ze verschillen alleen in hoe je de regel opschrijft — en in hoe ver ze reiken: alles wat de sleep-route kan, kan het R-vak ook, andersom niet.

OpmerkingDe brug naar R — wat je in het R-vak juist níét schrijft

In het R-broertje typ je een nieuwe kolom zo:

d$hoog <- ifelse(d$glans >= 50, "hoog", "laag")

In JASP’s R-vak schrijf je daar alleen het rechterdeel van:

ifelse(glans >= 50, "hoog", "laag")

Twee dingen zijn weg, en allebei om dezelfde reden: het dialoogvenster heeft ze al. De naam hoog heb je bovenin ingevuld, dus de toewijzing <- hoeft niet meer. En d$ hoeft niet, want JASP heeft één tabel tegelijk open — je spreekt de kolommen kaal aan, als gewone rijtjes getallen.

Dat maakt dit vak een prettige oversteekplaats. Wie later naar R gaat, moet vooral leren wat er bij komt, niet wat er anders is.

Nieuwe variabelen maken en hercoderen

Hercoderen is je gegevens opnieuw indelen zonder ze te veranderen. Je legt een grens en maakt er twee groepen van, je hakt een getal in klassen, of je zet een woordkolom om in een nul en een één. De oude kolom blijft gewoon staan; er komt er één naast. Dat is niet netjes-zijn maar zelfbescherming — een hercodering die niet klopt, kun je zo weggooien en overdoen.

Een grens leggen: twee groepen uit één getal

We splitsen de glans op 50: alles daarboven heet hoog, de rest laag.

OpmerkingIn JASP · een tweedeling op een grens · JASP 0.98.1
  1. Klik op de + rechts van de laatste kolom. Naam: hoog, type Text, icoon: het handje. Klik Create.
  2. Rechts staat de lijst met functies. Sleep ifElse naar het vak in het midden. Hij komt binnen met drie lege plekken.
  3. Sleep glans uit de lijst links naar de eerste plek, kies uit de rij bovenin het teken en typ 50 erachter.
  4. Vul op de tweede plek "hoog" in en op de derde "laag".
  5. Klik Compute column.

Let op de hoofdletter: het sleepvak kent ifElse, R kent ifelse. Zelfde functie, andere schrijfwijze — het zijn dan ook twee verschillende talen.

  1. Klik op de +, naam hoog, type Text, icoon R, Create.
  2. Typ de regel en klik Compute column:
ifelse(glans >= 50, "hoog", "laag")

Tel na wat eruit komt. Ga naar Analyses → Descriptives, zet hoog in het vak en vink Frequency tables aan. Er horen 7 hoge en 5 lage steentjes te staan, samen 12. Doe dat elke keer: een hercodering die één kant op scheef staat, zie je hier meteen en verderop niet meer.

OpmerkingBlijft je kolom leeg?

Het overkomt je een keer: je typt de regel, klikt Compute column, en er gebeurt niets. De kolom blijft leeg, soms met een molentje dat blijft draaien. Dat ligt niet aan jou en niet aan je regel. Klik bovenin naar Analyses en dan weer terug naar Edit Data — dan rekent hij alsnog.

Het is gemeld bij de makers en staat op dit moment nog open (jasp-issues #3441). De melding gaat over versie 0.19.3; of hij in 0.98.1 nog bijt, weten we niet. Kom je hem niet tegen: mooi, dan is hij gerepareerd.

Een getal in klassen hakken

Drie vakjes deze keer: mat, middel en helder.

OpmerkingIn JASP · drie klassen · JASP 0.98.1

Nest twee ifElse-blokjes in elkaar: sleep er één in het middenvak, en sleep op de plek van het “anders”-antwoord een tweede ifElse naar binnen.

  • eerste vraag: glans > 60"helder"
  • anders, tweede vraag: glans > 40"middel"
  • anders → "mat"
cut(glans, breaks = c(0, 40, 60, 100),
    labels = c("mat", "middel", "helder"))

Uitkomst: 5 mat, 3 middel, 4 helder. Samen 12 — en dát is de som die je moet natellen.

Waar hoort de grens zelf bij? Bij het vakje eronder. cut maakt de vakjes (0, 40], (40, 60] en (60, 100]: de bovengrens hoort er wél bij, de ondergrens niet. In deze twaalf steentjes is dat geen theorie — er ligt er precies één met een glans van 60, en die belandt dus in middel en niet in helder. De geneste ifElse hierboven doet hetzelfde, want daar staat > 60 en niet >= 60. Verzet die ene grens en je verschuift een steentje van vakje.

Nog een reden om na te tellen: valt een waarde buiten je uiterste grenzen, dan maakt cut er stilletjes een lege plek van. Geen foutmelding, gewoon een gat.

Een woordkolom omzetten in een nul en een één

Regressie kan niet rekenen met het woord sterretje. Er moet een getal van komen, en het simpelste getal is: hoort dit steentje bij die groep, ja of nee.

OpmerkingIn JASP · een dummy maken · JASP 0.98.1

Naam D2, type Nominal, handje. Sleep ifElse in het vak, daarin merk, het teken = en "sterretje"; als antwoorden 1 en 0.

ifelse(merk == "sterretje", 1, 0)

Zes enen en zes nullen — en je nieuwe D2 is regel voor regel gelijk aan de kolom D die al in het bestand zat. Zo’n 0/1-kolom heet een dummy.

Dat woord klinkt alsof er iets nep aan is, maar er is niets nep aan: het is de eerlijkste vertaling die er bestaat van een naam naar een getal. Wat je wel moet weten, is wie er nul werd.

Wie krijgt de nul — de referentiecategorie

De groep die de nul krijgt heet de referentiecategorie, en dat is geen bijrol. Alles wat je model daarna over de andere groep zegt, zegt het ten opzichte van díé groep.

Kijk wat er gebeurt als je alleen D gebruikt om glans te voorspellen — Regression → Linear Regression, glans als Dependent, D als Covariate:

wat je in de tabel ziet wat het betekent
intercept = 40.00 de gemiddelde glans van de golfjes, de groep met de nul
b voor D = 20.00 zoveel glanzender zijn de sterretjes — bovenop die 40

Reken het na en het klopt precies: de golfjes hebben gemiddeld 40 glans, de sterretjes 60. Het model vertelt je die 60 niet rechtstreeks; het geeft je het ijkpunt en de afstand, en jij telt op.

Laat je JASP de dummy’s maken, dan kiest JASP ook de referentie. Sleep je een tekstkolom als merk naar het vak Factors, dan maakt JASP er zelf 0/1-kolommen van en neemt daarbij de eerste categorie als ijkpunt. Bij merk is dat golfje. Dat merk je aan de uitvoer: er komt een rij voor sterretje en géén rij voor golfje. Die ontbrekende rij is niet vergeten — dat is de nullijn waar de rest vandaan gemeten wordt.

Zie je in een tabel dus drie groepen genoemd en maar twee rijen staan, dan is er niets weggelaten. Je kijkt naar het ijkpunt zonder het te zien.

Waar dit over gáát — waarom een groep een getal mag worden, en wat je daarmee wint — staat in het boek bij W9 · Groepen zijn ook getallen.

Centreren

Centreren is één aftrekking: je haalt van elke waarde het gemiddelde af. Meer is het niet. Je gegevens blijven precies hetzelfde — dezelfde afstanden, dezelfde volgorde, dezelfde spreiding — en toch gaat je uitvoer er anders uitzien. Wat je verschuift is namelijk niet de data maar de nul, en de nul is de plek waar je model zijn verhaal begint.

OpmerkingIn JASP · centreren · JASP 0.98.1

Naam karaat_c, type Scale, handje.

  1. Sleep karaat naar het middenvak.
  2. Klik het teken .
  3. Zoek in de functielijst rechts de knop mean(y) en klik hem aan.
  4. Sleep karaat op de lege plek binnen die mean( ).
  5. Compute column.

In het vak staat nu karaat - mean(karaat).

karaat - mean(karaat)

Zet karaat_c in Descriptives: het gemiddelde hoort 0 te zijn. Dat is geen toevalstreffer maar de definitie — je hebt er net het gemiddelde afgehaald. Staat er iets als -1.1e-16, dan is dat gewoon nul met wat rekenstof eromheen; een computer die met kommagetallen werkt komt zelden precies uit.

Zoek voor jezelf van die momentjes om te controleren. Je hebt net iets gedaan, je weet wat eruit zou moeten komen, en je kijkt of dat er staat — dat is alles. Wie het pas achteraf opschrijft heeft niets gecontroleerd, want dan is elk getal goed.

OpmerkingLet op — mean betekent hier iets anders dan je denkt

In het sleepvak neemt mean(y) één kolom en geeft je het gemiddelde van díé kolom, over alle rijen heen. Dat is precies wat je hier nodig hebt.

Maar het is niet wat je nodig hebt als je ooit een schaalscore wilt maken — het gemiddelde van tien vragen, per persoon. Dat is een gemiddelde dwars over kolommen, en daar kan het sleepvak niet bij. Daarvoor moet je het R-vak in:

rowMeans(data.frame(v1, v2, v3), na.rm = TRUE)

Twee gemiddelden die niets met elkaar te maken hebben, met bijna dezelfde naam. Hier gaat het om het eerste: één kolom, één getal.

Wat er verschuift, en wat niet

Draai twee keer dezelfde regressie — Regression → Linear Regression, glans als Dependent — eerst met karaat als Covariate, dan met karaat_c:

intercept b voor karaat
ruw (karaat) −1.43 32.14
gecentreerd (karaat_c) 50.00 32.14

De helling beweegt niet. 32.14 glanspunten per karaat, of je nu centreert of niet — en dat moet ook, want je hebt de steentjes niet aangeraakt.

Het intercept verhuist wél, en dat is de hele winst. Ruw staat er −1.43: de voorspelde glans van een steentje van nul karaat. Zo’n steentje bestaat niet, en een negatieve glans bestaat al helemaal niet — het is een keurig uitgerekend antwoord op een vraag die niemand stelt. Gecentreerd staat er 50.00, en dat is de gemiddelde glans van een gemiddeld steentje. Van een onzin-getal naar een getal dat je hardop kunt voorlezen.

En bij een interactie wordt het menens

Zolang je één voorspeller hebt, is centreren gemak. Zodra er een interactie in je model zit, gaat het over goed of fout aflezen.

Zet gladheid, D en DxG samen in Covariates. Maak daarna gladheid_c (hetzelfde recept als hierboven, mean = 5) en draai het model opnieuw.

b voor D interactie R²
ruw 1.84 2.64 .97
gecentreerd 15.03 2.64 .97

Dezelfde data, hetzelfde model, dezelfde verklaringskracht, dezelfde interactie — en het verschil in glans tussen de twee merken leest de ene keer 1.84 en de andere keer 15.03. Ruim acht keer zo groot.

Ze zijn allebei waar. Ze beantwoorden alleen een andere vraag. In een model mét interactie is een hoofdeffect altijd het effect bij nul van de ander, en dat maakt het antwoord afhankelijk van waar de nul ligt:

  • ruw is het glansverschil tussen golfje en sterretje bij gladheid = 0 — een ongeslepen steen. De gladheid loopt in dit bestand van 1 tot 8. Zo’n steen ligt er dus niet, en 1.84 is een uitspraak over een plek waar je nooit gemeten hebt.
  • gecentreerd is datzelfde glansverschil bij een gemiddeld geslepen steen. Die kun je aanwijzen; er liggen er twaalf.

De regel om te onthouden: centreer je voorspellers en die nul wordt het gemiddelde — pas dan is de tabel te lezen zonder er nog iets bij te rekenen. De interactie zelf verandert nooit, want die gaat niet over waar je meet maar over hoe de twee hellingen uit elkaar lopen.

Opmerking⚠ De val die stil misgaat — bouw DxG opnieuw

DxG staat kant-en-klaar in het bestand, en dat is D × gladheid — het product van de ruwe gladheid. Centreer je gladheid en laat je die oude DxG in het model staan, dan krijg je dit:

b voor D interactie R²
gladheid_c + D + oude DxG 1.84 2.64 .97
gladheid_c + D + nieuwe DxG_c 15.03 2.64 .97

Lees die eerste regel nog eens. Je hebt gecentreerd, JASP geeft geen kik, het model past precies even goed — en je krijgt exact het getal terug dat je met centreren wilde repareren. Niets ziet er verkeerd uit. Dat maakt dit de vervelendste fout op deze pagina.

Maak dus een nieuwe kolom mee:

gladheid_c * D

En waarom het zo netjes misgaat, is het nakijken waard. De oude DxG is (gladheid_c + 5) × D, en die 5 lekt weg naar de D-rij. Precies daar duikt het oude getal weer op:

\[1.84 + 5 \times 2.64 = 15.03\]

Het gemiddelde dat je aan de ene kant afhaalde, zat aan de andere kant nog in het model.

In het boek gaat W8 · Meer dan één verschil over wat het intercept nog betekent zodra er meerdere voorspellers naast elkaar staan, en W10 · Verschil in verschil over hellingen die niet parallel lopen. Deze pagina laat zien hóé je centreert; daar staat waaróm het uitmaakt.