Eerste beweging · Verschil onder de loep
Oefening 0.1 · Kijken naar de data
Kijken voor je rekent
In deze oefening
Data bij deze oefening — penguins.csv 342 pinguïns · diamantjes.csv de twaalf steentjes uit het boek · wat elke kolom betekent
prikkel
Die linker is dikker dan die rechter
kijken vóór rekenen · verschil voelen
Voordat er ergens gerekend wordt, wordt er gekeken. Iemand staat op een koude rots, ziet twee pinguïns voorbij waggelen en denkt: die linker is dikker dan die rechter. Meer is het niet. Geen formule, geen toets — een blik, en het begin van een vraag.
Zo begon het boek ook: bij het vóélen van verschil, ver voordat er iets aan gerekend werd. Dit oefenboek is de andere helft van dat verhaal, en het loopt er de hele tijd naast: het boek vertelt, hier doe je het zelf. Jij en R — en de bedoeling is dat jij die computer stap voor stap zover krijgt dat hij laat zíen wat jij al kon voelen.
Maar voor je ook maar één knop aanraakt, wil ik dat je iets doet wat bijna iedereen overslaat: kijken naar wat data eigenlijk zíjn. Niet rekenen — kijken.
kijk
Bekijk de tabel in R
data inlezen · rijen en kolommen
# de twaalf steentjes binnenhalen
d <- read.csv("diamantjes.csv")
## Kijken wat er ligt ----
# head() laat standaard de eerste zes rijen zien: Anna tot Faas
head(d)
# nrow() → 12
nrow(d)
# ncol() → 9
ncol(d)
# str() zet achter elke kolom wat erin zit: tekst of getal
str(d)library(dplyr)
# de twaalf steentjes binnenhalen
d <- read.csv("diamantjes.csv")
## Kijken wat er ligt ----
head(d)
# dim() → 12 9
dim(d)
# glimpse() doet wat str() doet, maar leesbaarder
glimpse(d)Een regel die begint met een hekje (#) is commentaar (Engels: comment): een briefje voor jezelf. R slaat alles achter een hekje over, dus je mag erachter schrijven wat je wilt — zo lees en begrijp je je script later terug.
Staat er in zo’n briefje een pijltje →, dan zegt het wat je hoort te zien: bij # nrow() → 12 hoort 12. Op je scherm zet R er zelf nog [1] voor. Dat is geen fout: R nummert wat hij teruggeeft, en [1] betekent alleen “hier begint het eerste getal” — ook als er twee staan, zoals bij dim(). En ## Kijken wat er ligt ----, met twee hekjes en streepjes? Ook commentaar, alleen dan als kopje in je script. Een heel stuk tegelijk commentaar maken kan ook, met de commentaar-sneltoets uit de installatie.
Twaalf rijen, negen kolommen — de hele dataset past in één blik, en dat is precies waarom het boek ermee rekent. Bij echte data lukt dat kijken-in-één-keer niet meer, en dan heb je gereedschap nodig om te zien wat er ligt.
Nu jij — met 342 pinguïns, te veel rijen voor één blik.
Bij dit boekje hoort een bestand: penguins.csv — 342 pinguïns van een rots bij Antarctica, écht opgetild, écht gewogen.1 Haal het binnen en kijk alleen maar. Er wordt hier niks berekend.
# de 342 pinguïns binnenhalen
peng <- read.csv("penguins.csv")
## Kijken wat er ligt ----
# head() laat de eerste zes rijen zien
head(peng)
# nrow() → 342 pinguïns
nrow(peng)
# names() geeft de negen kolomnamen
names(peng)Wil je er doorheen scrollen zoals in een spreadsheet? View(peng) opent de hele tabel in een eigen venster. Doen — scrollen hoort bij kijken.
Achterin dit boekje ligt een gereedschapskist: alle handelingen die telkens terugkomen — inlezen, filteren, kolommen maken, plotten — in base R én dplyr naast elkaar. Je hoeft hem nu niet te lezen. Loop je straks vast op een handeling, dan sla je hem daar op. Voor dit moment: inlezen en wegschrijven en kijken wat je hebt.
Wat je ziet is een tabel: 342 rijen, negen kolommen — id, soort, sekse, snavellengte, snaveldiepte, vinlengte, gewicht, stikstof en koolstof. En daarbij de belangrijkste leesregel van dit hele boekje: één rij is één pinguïn. Rij 1 is een Adelie-man met een snavel van 39.1 mm, en hij weegt 3750 gram. Kijk bij hem onder stikstof en koolstof: daar staat twee keer NA. Op die plek ontbreekt een meting — geen fout van jou en geen fout in het bestand. Wat die twee kolommen zijn, staat op de datasetbladzij. Scroll eens een flink eind naar beneden: rij 173 is een Gentoo van 5000 gram. Wijs ze allebei maar even aan. Dit beest weegt 3750 gram; dat beest 5000 — ruim een kilo verschil, twee dieren, één rots.
Je hebt nog helemaal niks berekend. En toch heb je al iets gezien.
snap het
Wat een tabel is — en wat hij weglaat
wat data zijn · meten · kijk eerst, reken dan
Dít is data. Geen mystiek, geen wiskunde — een tabel. Elke rij een echt beest (of straks, in andere bestanden, een echt mens), en elke kolom een vraag die iemand aan dat beest gesteld heeft: hoe zwaar ben je, hoe lang is je snavel, wat voor soort ben je.
En meteen ook dit, want het hoort er vanaf dag één bij: de tabel is niet de pinguïn. Rij 1 zegt niks over hoe dat dier over de rots waggelde, of hij zich liet optillen of protesteerde, hoe de wind stond die dag. Wat je meet is nooit alles wat er was. Een dataset is een net van getallen dat een stukje werkelijkheid probeert vast te houden — en er glipt altijd iets doorheen. Maar wat blijft hangen, daar kun je mee kijken. Dat is geen verlies om bij te blijven treuren; het is een begin.
Vanaf hier gaan we die tabel steeds iets slimmer laten praten. Hoofdstuk voor hoofdstuk, één techniek per keer: eerst samenvatten, dan tekenen, dan schudden, uiteindelijk voorspellen. En telkens in dezelfde volgorde, die je nu al kent: kijk eerst, reken dan.
tentamen
Tentamenvragen
één rij is één pinguïn · wat NA betekent · tekst tegenover getal · wat head() laat zien
Er valt in deze opdracht nog niets te rekenen, en tóch kan een tentamen er al vragen over stellen. Deze vijf hebben die vorm: vier opties, en precies één is de beste — de andere drie kunnen best waar zijn en toch niet het beste antwoord.
1. penguins.csv heeft 342 rijen en 9 kolommen. Wat staat er in één rij?
- Eén meting aan één pinguïn.
- Eén van de negen dingen die aan de pinguïns gemeten zijn.
- Eén pinguïn, met al zijn metingen naast elkaar.
- Eén van de drie soorten pinguïns.
2. Bij de eerste pinguïn staat onder stikstof en koolstof twee keer NA. Wat betekent dat?
- Op die twee plekken ontbreekt een meting.
- Die twee metingen kwamen op nul uit.
- Er is een fout gemaakt bij het inlezen van het bestand.
- Die pinguïn hoort niet in de dataset en moet eruit.
3. Je wil weten hoeveel pinguïns er in het bestand staan. Welke regel geeft je dat?
ncol(peng)names(peng)head(peng)nrow(peng)
4. In de kolom soort staat tekst (Adelie, Chinstrap, Gentoo), in de kolom gewicht staan getallen (3750, 5000, …). Wat kun je door dat verschil straks wél mét gewicht doen en níét met soort?
- De waarden bij elkaar optellen en er zo één getal van maken.
- Tellen hoe vaak elke waarde voorkomt.
- De rijen op die kolom sorteren.
- Niets — je kunt met beide kolommen precies hetzelfde.
5. head(peng) laat de eerste zes rijen zien, en daarin zijn alle zes pinguïns een Adelie. Wat mag je daaruit besluiten?
- Dat meer dan de helft van de pinguïns in het bestand een Adelie is.
- Dat het bestand op soort gesorteerd staat.
- Niets over de andere 336 —
head()is een kijkje, geen samenvatting. - Dat de Chinstraps en Gentoo’s in een ander bestand staan.
1 c · 2 a · 3 d · 4 a · 5 c
Hieronder staat per vraag waaróm, en waarom de drie andere opties aantrekkelijk zijn. Heb je er een goed, dan kun je die overslaan.
1. c. Dit is de leesregel van dit hele boekje: één rij is één pinguïn, en de negen kolommen zijn de negen dingen die over dat ene dier zijn opgeschreven. a ligt er het dichtst naast en is de belangrijkste om af te pellen: één meting staat in één vakje, op het kruispunt van een rij en een kolom. Wie een rij als één meting leest, raakt het idee kwijt dat de metingen van hetzélfde dier bij elkaar horen — en dat idee is straks alles. b beschrijft een kolom: negen dingen, negen kolommen. d verwart de tabel met een groepsindeling; de soort is één van de negen kolommen, niet de eenheid waarop een rij gaat.
2. a. NA betekent: hier hoort een meting, en hij is er niet. Geen fout van jou en geen fout in het bestand. b is de gevaarlijkste van de drie, want nul is juist wél een meting — een gemeten nul zegt “ik heb gekeken en er was niets”, en NA zegt “ik heb niet gekeken” of “het lukte niet”. Dat verschil maakt later het verschil tussen een gemiddelde dat klopt en een dat omlaag getrokken is door verzonnen nullen. c zoekt de oorzaak in het inlezen; je ziet het gat omdat het er echt is. d gooit een pinguïn weg om twee ontbrekende metingen, terwijl zijn gewicht en zijn snavel er gewoon staan en prima meedoen.
3. d. nrow() telt de rijen, en één rij is één pinguïn — dus dat getal, 342, is het aantal dieren. a telt de kolommen en geeft 9: het aantal dingen dat gemeten is, niet het aantal dieren. Dat is dezelfde verwisseling als bij vraag 1, nu in commandovorm. b geeft de negen kolomnamen, dus wél waarover het bestand gaat en niet over hoeveel. c laat zes rijen zien en zegt niets over de rest — zie vraag 5.
4. a. Gewichten kun je bij elkaar optellen; soorten niet. Adelie plus Gentoo is niets, en Chinstrap is niet twee keer Adelie — de tekst in die kolom is een etiket, geen hoeveelheid. Dat klinkt vanzelfsprekend, en het is de bodem onder alles wat je hierna gaat doen: wát je met een kolom kunt doen, hangt af van wat erin staat. b kan bij allebei — hoe vaak Adelie voorkomt is net zo telbaar als hoe vaak 3750 gram voorkomt. c kan ook bij allebei: tekst sorteert op alfabet, getallen op grootte. d is de val, want twee van de vier dingen kunnen inderdaad bij allebei; het optellen is juist wat de twee kolommen scheidt.
5. c. head() laat zien wát er ligt — welke kolommen, welke soort waarden, waar de gaten zitten — en niets over hoe de andere 336 rijen eruitzien. Wil je dat weten, dan tel je (nrow) of je kijkt de hele tabel door (View). b is de verleidelijkste, en hij valt om op één ding: zes rijen kunnen het niet aantonen. Zes Adelies op een rij krijg je ook in een bestand waarin niets op orde staat. Dat is het verschil tussen het klopt en je hebt het gezien — en het klopt hier zelfs bijna, want de dieren staan wél per soort bij elkaar: eerst 151 Adelies, dan 123 Gentoo’s, dan 68 Chinstraps. Gegroepeerd dus, niet gesorteerd, want alfabetisch zou Chinstrap in het midden staan. a is een uitspraak over alle 342 op grond van zes, en dat is precies de sprong die deze vraag wil tegenhouden. Hij is hier bovendien onwaar: er lopen 151 Adelies rond van de 342, oftewel 44.2% — de grootste groep van de drie, maar geen meerderheid. d verzint een tweede bestand; alle drie de soorten staan in dit ene.
Wil je de getallen uit deze vijf vragen zelf zien ontstaan — geen ervan is overgetikt:
peng <- read.csv("penguins.csv")
# vraag 1 en 3 — zoveel pinguïns: nrow() → 342
nrow(peng)
# vraag 1 — zoveel dingen zijn er per pinguïn opgeschreven: ncol() → 9
ncol(peng)
# vraag 5 — zoveel van de 342 rijen blijven buiten dat kijkje van zes → 336
nrow(peng) - 6
# vraag 5 — zoveel van de 342 zijn Adelie → 151
sum(peng$soort == "Adelie")
# vraag 5 — en dat is dus geen meerderheid, in procenten → 44.2
round(100 * sum(peng$soort == "Adelie") / nrow(peng), 1)
# vraag 5 — de soorten staan per blok bij elkaar, in deze lengtes → 151 123 68
rle(peng$soort)$lengths◠ Zelfde adem in het boek
Hier: voor het eerst naar een echte tabel kijken — zonder één berekening.
In het boek: H0 — In den beginne
Daar begint het nog vroeger: niet bij een tabel, maar bij het ervaren van verschil zelf.
Voetnoten
Palmer Penguins — Gorman, Williams & Fraser (2014), Palmer Station Antarctica LTER; via het R-pakket
palmerpenguins(CC0). Echte dieren, echte metingen.↩︎