In de praktijk staan data op verschillende servers en in allerlei verschillende bestanden. Als de data die je nodig hebt uit meerdere bronnen komen, is het essentieel dat je weet hoe je ze kunt samenvoegen zodat je zo min mogelijk informatie verliest en koppelingen maakt die kloppen bij de structuur van je data.
In deze tutorial nemen we je mee langs:
- Datasets horizontaal en verticaal samenvoegen
- Wat primaire sleutels zijn en hoe ze structuur geven aan je data
- Verschillende soorten joins (bijv. left join, inner join, full join) en hoe je daartussen kiest
- Een veelvoorkomend probleem om op te letten en hoe je het oplost
Datasets concatenaten
In grote lijnen zijn er twee manieren om datasets samen te voegen; je kunt informatie toevoegen door meer rijen toe te voegen of door meer kolommen aan je dataset toe te voegen. In het algemeen, als je datasets dezelfde set kolommen hebben of dezelfde set observaties, kun je ze respectievelijk verticaal of horizontaal concatenaten. Laten we leren aan de hand van voorbeelden.
Datasets verticaal toevoegen
Als je meerdere datasets hebt met dezelfde set kolommen, kun je de ene dataset verticaal aan de andere concatenaten. Dus, met behoud van de kolommen van je dataset kun je er meer rijen aan toevoegen. Door zulke informatie in één bestand te hebben, kun je makkelijker aggregeren en het grotere geheel zien, zonder steeds te moeten wisselen tussen meerdere bestanden en het overzicht te verliezen.
Dataset 1
| Merk | Aantal modellen |
|---|---|
| Honda | 63 |
| BMW | 10 |
Dataset 2
| Merk | Aantal modellen |
|---|---|
| Ford | 26 |
| Tesla | 4 |
Het is belangrijk om te onthouden dat als je dezelfde observatie in meerdere datasets hebt en je ze verticaal concateneert met rbind(), je dubbele observaties in je tabel krijgt. En hoewel de twee datasets dezelfde set variabelen (dus kolommen) moeten hebben, hoeven ze niet in dezelfde volgorde te staan. Zie het zelf in de console hieronder!
In je werkruimte staan twee datasets genaamd dataset1 en dataset2 die je hierboven zag. Probeer de kolommen van dataset1 te herordenen. Roep rbind() aan op dataset1 en dataset2 en ook op reordered_dataset1 en dataset2.
dataset1 <- data.frame(make = c("Honda", "BMW"),
num_models = c(63, 10))
dataset2 <- data.frame(make = c("Ford", "Tesla"),
num_models = c(26, 4))
# Add datasets vertically
rbind(dataset1, dataset2)
# Reorder columns
reordered_dataset1 <- dataset1[, c(2, 1)]
# See that rbind() is robust to column ordering
rbind(reordered_dataset1, dataset2)
Na rbind() zou je resultaat informatie over alle vier de automerken in één tabel moeten hebben, zoals dit:
Verticaal geconcateneerde dataset
| Merk | Aantal modellen |
|---|---|
| Honda | 63 |
| BMW | 10 |
| Ford | 26 |
| Tesla | 4 |
Begin gratis met R leren
R voor gevorderden
Datasets horizontaal toevoegen
Als je datasets dezelfde set observaties vertegenwoordigen, kun je zulke datasets horizontaal concatenaten. Dit keer kun je, met behoud van de rijen van je dataset, er meer kolommen aan toevoegen. In zulke gevallen moet je controleren dat de volgorde van de observaties hetzelfde is. Als je datasets een verschillend aantal rijen hebben, of als ze wel evenveel rijen hebben maar de rijen inconsistent geordend zijn, kun je de ene set kolommen koppelen aan de andere op een manier die niet klopt.
Laten we het voorbeeld hierboven uitbreiden. Stel dat je twee databestanden hebt: één met het automerk en het aantal unieke modellen dat wordt aangeboden, en een ander met het automerk en de totale verkoop:
Aantal aangeboden unieke modellen
| Merk | Aantal modellen |
|---|---|
| Honda | 63 |
| BMW | 10 |
| Ford | 26 |
| Tesla | 4 |
Totale verkoop
| Merk | Verkoop |
|---|---|
| Ford | 119157 |
| BMW | 25908 |
| Honda | 188328 |
| Tesla | 29975 |
Het is belangrijk om op te merken dat als je dezelfde observatie in meerdere datasets hebt en je ze horizontaal concateneert met cbind(), je eindigt met redundante kolommen in je tabel. En hoewel de twee datasets gerelateerde informatie bevatten, is de volgorde van de rijen wel degelijk belangrijk!
Roep in de console hieronder cbind() aan op models en sales en print het resultaat:
models <- data.frame(make = c("Honda", "BMW", "Ford", "Tesla"),
num_models = c(63, 10, 26, 4))
sales <- data.frame(make = c("Ford", "BMW", "Honda", "Tesla"),
sales = c(119157, 25908, 188328, 29975))
# Add datasets horizontally
cbind(models, sales)
Je zou zoiets als dit moeten hebben gekregen:
Modellen & verkoop
| Merk | Aantal modellen | Merk | Verkoop |
|---|---|---|---|
| Honda | 63 | Ford | 119157 |
| BMW | 10 | BMW | 25908 |
| Ford | 26 | Honda | 188328 |
| Tesla | 4 | Tesla | 29975 |
Zie je het probleem? Deze data is niet netjes!
Volgens de principes van tidy data die in deze basiscursus worden uitgelegd, hoort elke observatie van een dataset in een unieke rij te staan. En wat als je in één dataset alleen informatie hebt voor sommige rijen en alleen voor die rijen extra informatie wilt toevoegen? Met andere woorden: wat als je meer kolommen uit de ene dataset aan de andere wilt toevoegen, maar die datasets niet evenveel observaties hebben?
Primaire sleutel en vreemde sleutels
De eerste stap bij het combineren van datasets is het zoeken naar de primaire sleutel van je dataset. De primaire sleutel is de kolom of set kolommen die elke observatie in je dataset uniek identificeert. In het voorbeeld met automerken, het aantal unieke modellen en totale verkoop, is de primaire sleutel van je datasets de kolom make.
Nu kunnen we joins uitvoeren, de standaardmanier om datasets in één tabel samen te voegen.
Soorten joins
Er zijn veel soorten joins. Je kunt leren hoe je kolommen uit de ene dataset aanvult met kolommen uit een andere met mutating joins, hoe je de ene dataset filtert op basis van een andere met filtering joins, en hoe je datasets doorzoekt met setoperaties in de cursus Joining Data in R with dplyr. Hieronder staan enkele van de meest voorkomende.
left_join(x, y): geeft alle rijen uit x terug, en alle kolommen uit x en y. Rijen in x zonder match in y krijgen NA-waarden in de nieuwe kolommen. Als er meerdere matches zijn tussen x en y, worden alle combinaties van de matches teruggegeven.
inner_join(x, y): geeft alle rijen uit x terug waarvoor overeenkomende waarden in y bestaan, en alle kolommen uit x en y. Als er meerdere matches zijn tussen x en y, worden alle combinaties van de matches teruggegeven.
full_join(x, y): geeft alle rijen en alle kolommen uit zowel x als y terug. Waar geen overeenkomende waarden zijn, geeft de functie NA terug voor wat ontbreekt.
De hierboven genoemde joins zijn voorbeelden van mutating joins, omdat ze variabelen uit twee datasets combineren.
Ontbrekende sleutels
Stel dat je twee datasets hebt. De eerste dataset heet size en bevat de namen van mensen en hun shirtmaat:
> size
name size
1 Tom M
2 Dan XL
3 Keil S
De tweede dataset heet color en bevat de achternamen van mensen, voorkeuren voor shirtkleur, en slaat sommige informatie op in het attribuut row.names:
> color
surname color
Tom Jeon <NA>
Dan Smith Dark
Bob McLadden Light
Zie je wat hier mis kan gaan? Joins tussen twee tabellen kunnen ingewikkeld worden als er sleutels ontbreken of duplicaten zijn. In dit voorbeeld slaan data frames in R belangrijke informatie op in het attribuut row.names. In dat geval kun je met een join-functie niet bij de sleutel, omdat join-functies alleen toegang hebben tot kolommen van het data frame.
De truc om dit probleem eenvoudig op te lossen, is de functie rownames_to_column() uit het pakket tibble te gebruiken. Deze retourneert een kopie van je dataset met de rijnamen als kolom toegevoegd. Het eerste argument van rownames_to_column() is je data frame-object en het tweede argument is een string met de naam van de kolom die je wilt toevoegen.
Probeer te verkennen in de console hieronder. De datasets size en color zijn vooraf geladen in je werkruimte.
color <- data.frame(surname = c("Jeon", "Smith", "McLadden"), color = c(NA, "Dark", "Light"))
row.names(color) <- c("Tom", "Dan", "Bob")
size <- data.frame(name = c("Tom", "Dan", "Keil"), size = c("M", "XL", "S"))
# Explore here!
Tot slot
In de echte wereld kunnen data opgesplitst zijn over veel datasets en in allerlei verschillende formaten. Omdat R is ontworpen om met enkele tabellen met data te werken, is het manipuleren en combineren van datasets tot één tabel een essentiële vaardigheid. Volg het vaardigheidstraject Importing & Cleaning Data with R en leer data in elk formaat te parsen en te combineren. Bekijk ook DataCamp’s tutorial R Data Import. Veel leerplezier!
