library(tidyverse)
library(rio)
6 Data combineren
In dit hoofdstuk bespreken we manieren om aan een bestaande dataset nieuwe rijen of kolommen toe te voegen en om twee bestaande datasets samen te voegen.
We gebruiken in dit hoofdstuk de volgende packages:
En als voorbeelddata de Canadian Election Study van 2019:
<- import("2019 Canadian Election Study.rds") canada
6.1 Datasets combineren: rijen of kolommen toevoegen
6.1.1 Rijen toevoegen
Als we twee datasets hebben met dezelfde kolommen (variabelen), kunnen we de rijen van de twee datasets samenvoegen met bind_rows
uit package dplyr
(dit package wordt geladen met de tidyverse).
Als voorbeeld hebben we twee datasets met dezelfde variabelen, name
en age
:
<- data.frame(name = c("Billy", "Xin", "Hugo"), age = c(20, 30, 40))
dta1 <- data.frame(name = c("Theresa", "Elin", "Lena"), age = c(25, 35, 45))
dta2
dta1
name age
1 Billy 20
2 Xin 30
3 Hugo 40
dta2
name age
1 Theresa 25
2 Elin 35
3 Lena 45
Wij kunnen deze datasets als volgt combineren:
<- bind_rows(dta1, dta2)
dta_combined dta_combined
name age
1 Billy 20
2 Xin 30
3 Hugo 40
4 Theresa 25
5 Elin 35
6 Lena 45
6.1.2 Kolommen toevoegen
Als we extra kolommen willen toevoegen aan een dataframe, kunnen we bind_cols
uit package dplyr
gebruiken (dit package wordt geladen met de tidyverse).
Als we bijvoorbeeld twee datasets hebben, één met de naam en leeftijd van mensen, en een andere met hun zelfgerapporteerde geslacht:
<- data.frame(name = c("Billy", "Xin", "Hugo"), age = c(20, 30, 40))
dta <- data.frame(gender = c("Non-binary", "Female", "Male")) gender
dta
name age
1 Billy 20
2 Xin 30
3 Hugo 40
gender
gender
1 Non-binary
2 Female
3 Male
We kunnen dit combineren met bind_cols
:
bind_cols(dta, gender)
name age gender
1 Billy 20 Non-binary
2 Xin 30 Female
3 Hugo 40 Male
bind_cols
zal matchen op positie, dus de volgorde van rijen moet precies hetzelfde zijn. Voor meer flexibele manieren om kolommen aan een dataset toe te voegen, zie “Datasets samenvoegen” hieronder.
6.2 Datasets samenvoegen (join
)
Als we twee datasets hebben met een gemeenschappelijke variabele (d.w.z. een variabele met dezelfde naam en vergelijkbare codering, bijvoorbeeld een landnaam of een unieke identificatiecode), kunnen we de datasets combineren met join
van dplyr
.
Laten we beginnen met wat voorbeeldgegevens over 4 landen:
<- data.frame(country = c("USA", "Germany", "Netherlands", "Kenya"),
country_dta1 population = c(332, 84, 18, 56))
<- data.frame(country = c("Netherlands", "Germany", "Kenya", "Argentina"),
country_dta2 official_name = c("Nederland", "Bundesrepublik Deutschland", "Republic of Kenya", "República Argentina"))
country_dta1
country population
1 USA 332
2 Germany 84
3 Netherlands 18
4 Kenya 56
country_dta2
country official_name
1 Netherlands Nederland
2 Germany Bundesrepublik Deutschland
3 Kenya Republic of Kenya
4 Argentina República Argentina
Merk op dat slechts drie landen voorkomen in beide datasets, maar de variabele country
is aanwezig in beide dataframes en de waarden (d.w.z. de spelling van de namen van de landen) zijn hetzelfde voor de drie landen die in beide datasets voorkomen.
We kunnen de gegevens in deze datasets als volgt samenvoegen, met behulp van zogenaamde ‘joins’ van pacakge dplyr
. De functie full_join
geeft alle rijen in beide datasets terug:
<- full_join(x = country_dta1,
joined_data y = country_dta2,
by = c("country"))
x = country_dta1
-
Dit specificeert de eerste van de twee datasets. Vervang door je eigen dataset als je met je eigen gegevens werkt.
y = country_dta2
-
Dit specificeert de tweede van de twee datasets.
by = c("country")
-
Dit specificeert de kolom waarop we de waarden van de twee dataframes willen matchen (gespecificeerd als een character vector, d.w.z. tussen dubbele haakjes). In ons voorbeeld gebruiken we de variabele
country
, omdat deze variabele vergelijkbaar is tussen onze twee datasets.
joined_data
country population official_name
1 USA 332 <NA>
2 Germany 84 Bundesrepublik Deutschland
3 Netherlands 18 Nederland
4 Kenya 56 Republic of Kenya
5 Argentina NA República Argentina
We zien dat alle vijf landen aanwezig zijn in de samengevoegde dataset. De VS ontbreekt in country_dta2
, dus er ontbreekt een waarde (NA
) voor official_name
in de gecombineerde dataset. Argentinië ontbreekt in country_dta1
en heeft dus een ontbrekende waarde voor population
in de gecombineerde dataset.
Er zijn vier soorten joins
:
Functie | Gecombineerde dataset omvat… |
---|---|
inner_join() |
… alle rijen in x en y . |
left_join() |
… alle rijen in x . |
right_join() |
… alle rijen in y . |
full_join() |
… alle rijen in x of y . |
We kunnen het resultaat zien als we de vier soorten joins uitvoeren en printen:
# Inner join: alleen de drie landen die in beide datasets voorkomen
inner_join(x = country_dta1, y = country_dta2, by = c("country"))
country population official_name
1 Germany 84 Bundesrepublik Deutschland
2 Netherlands 18 Nederland
3 Kenya 56 Republic of Kenya
# Left join: alleen de vier landen in de eerste dataset
left_join(x = country_dta1, y = country_dta2, by = c("country"))
country population official_name
1 USA 332 <NA>
2 Germany 84 Bundesrepublik Deutschland
3 Netherlands 18 Nederland
4 Kenya 56 Republic of Kenya
# Right join: alleen de vier landen in de tweede dataset
right_join(x = country_dta1, y = country_dta2, by = c("country"))
country population official_name
1 Germany 84 Bundesrepublik Deutschland
2 Netherlands 18 Nederland
3 Kenya 56 Republic of Kenya
4 Argentina NA República Argentina
# Full join: alle vijf de landen
full_join(x = country_dta1, y = country_dta2, by = c("country"))
country population official_name
1 USA 332 <NA>
2 Germany 84 Bundesrepublik Deutschland
3 Netherlands 18 Nederland
4 Kenya 56 Republic of Kenya
5 Argentina NA República Argentina
6.2.1 Joining met verschillende variabelen
Als we twee dataframes hebben met verschillende namen, moeten we R instrueren welke variabelen moeten worden vergeleken.
Stel bijvoorbeeld dat we een derde dataframe hebben met landeninformatie:
<- data.frame(country_name = c("USA", "Netherlands", "Germany"),
country_dta3 capital_city = c("Washington DC", "Amsterdam", "Berlin"))
country_dta3
country_name capital_city
1 USA Washington DC
2 Netherlands Amsterdam
3 Germany Berlin
We merken op dat de variabele met de naam van het land in dit dataframe country_name
heet. Om deze te combineren met country_dta1
, moeten we by
als volgt specificeren:
full_join(x = country_dta1, y = country_dta3,
by = c("country" = "country_name"))
country population capital_city
1 USA 332 Washington DC
2 Germany 84 Berlin
3 Netherlands 18 Amsterdam
4 Kenya 56 <NA>
by = c("country" = "country_name")
-
De syntaxis
"country" = "country_name"
betekent dat we variabelecountry
uit de eerste dataset vergelijken met variabelecountry_name
uit de tweede dataset.
Merk op dat deze oplossing alleen werkt als de landennamen identiek gespeld zijn (en alleen de naam van de variabele verschilt). Het onderstaande zal niet goed werken, omdat de landennamen niet vergelijkbaar zijn tussen de twee datasets:
<- data.frame(country = c("United States of America", "Deutschland", "Nederland"),
country_dta4 capital_city = c("Washington DC", "Berlin", "Amsterdam"))
country_dta4
country capital_city
1 United States of America Washington DC
2 Deutschland Berlin
3 Nederland Amsterdam
full_join(country_dta1, country_dta4)
country population capital_city
1 USA 332 <NA>
2 Germany 84 <NA>
3 Netherlands 18 <NA>
4 Kenya 56 <NA>
5 United States of America NA Washington DC
6 Deutschland NA Berlin
7 Nederland NA Amsterdam
In dergelijke gevallen is de oplossing om eerst de variabele die wordt gebruikt voor de matching te hercoderen:
<- country_dta4 |>
country_dta4_recoded mutate(country = recode(country,
"United States of America" = "USA",
"Deutschland" = "Germany",
"Nederland" = "Netherlands"))
De landennamen uit beide datasets komen nu overeen, en we kunnen ze dus samenvoegen:
full_join(country_dta1, country_dta4_recoded)
country population capital_city
1 USA 332 Washington DC
2 Germany 84 Berlin
3 Netherlands 18 Amsterdam
4 Kenya 56 <NA>