dplyr in R-handleiding: Gegevens samenvoegen en koppelen met voorbeelden
โก Slimme samenvatting
dplyr voegt dataframes samen in R met vier werkwoorden: left_join(), right_join(), inner_join() en full_join(). Het bijbehorende pakket tidyr herschikt vervolgens het samengevoegde resultaat met behulp van gather(), spread(), separate() en unite().

Inleiding tot gegevensanalyse
Voordat iemand zich aansluit of iets reshaping Het werkwoord is logisch, het helpt om te zien waar gegevensmanipulatie past. Data-analyse kan worden onderverdeeld in drie delen:
- Extractie: Ten eerste moeten we de gegevens uit vele bronnen verzamelen en combineren.
- Transformeren: Deze stap omvat de gegevensmanipulatie. Zodra we alle gegevensbronnen hebben geconsolideerd, kunnen we beginnen met het opschonen van de gegevens.
- Visualiseer: De laatste stap is het visualiseren van onze gegevens om onregelmatigheden te controleren.
Het onderstaande diagram laat zien hoe de drie fasen met elkaar verbonden zijn.

Een van de grootste uitdagingen voor datawetenschappers is datamanipulatie. Data is immers nooit direct beschikbaar in het gewenste formaat. Datawetenschappers moeten minstens de helft van hun tijd besteden aan het opschonen en manipuleren van de data. Dit is een van de meest cruciale taken binnen hun functie. Als het datamanipulatieproces niet volledig, nauwkeurig en grondig is, zal het model niet naar behoren functioneren.
R dplyr
R heeft een pakket genaamd dplyr dat datatransformatie afhandelt. Het is opgebouwd rond een kleine set kernfuncties โ filter(), select(), arrange(), mutate() en summarise() โ plus een reeks join-functies. Zodra de data in de juiste vorm is, kan ggplot2 deze visualiseren.
We zullen leren hoe we het dplyr-pakket kunnen gebruiken om een GegevensframeAls R nog niet is geรฏnstalleerd, volg dan de instructies. Installatiestappen voor R en RStudioVoer vervolgens install.packages("dplyr") uit.
Gegevens samenvoegen met dplyr
dplyr biedt een leuke en handige manier om datasets te combineren. We hebben mogelijk veel bronnen van invoergegevens en op een gegeven moment moeten we ze combineren. Een join met dplyr voegt variabelen toe aan de rechterkant van de oorspronkelijke gegevensset.
dplyr sluit zich aan
Hieronder volgen vier belangrijke soorten joins die in dplyr worden gebruikt om twee datasets samen te voegen. Alle vier gebruiken dezelfde argumenten โ de twee tabellen en de sleutel โ en verschillen alleen in welke niet-overeenkomende rijen behouden blijven:
| Functie | Objectief | argumenten | Meerdere sleutels |
|---|---|---|---|
| left_join() | Voeg twee datasets samen. Bewaar alle waarnemingen uit de oorsprongstabel | x, y, by = โIDโ | x, y, by = c(โIDโ, โID2โ) |
| right_join() | Voeg twee datasets samen. Bewaar alle waarnemingen uit de bestemmingstabel | x, y, by = โIDโ | x, y, by = c(โIDโ, โID2โ) |
| innerlijke_join() | Voeg twee datasets samen. Sluit alle niet-overeenkomende rijen uit. | x, y, by = โIDโ | x, y, by = c(โIDโ, โID2โ) |
| volledige_join() | Voeg twee datasets samen. Behoud alle waarnemingen. | x, y, by = โIDโ | x, y, by = c(โIDโ, โID2โ) |
Deze vier werkwoorden corresponderen met de LINKER-, RECHTER-, BINNENSTE- en VOLLE BUITENSTE-verbindingen van SQL. Base R bereikt dezelfde resultaten via de argumenten all, all.x en all.y van samenvoegen().
We zullen alle soorten joins bestuderen aan de hand van een eenvoudig voorbeeld.
Allereerst maken we twee datasets aan. Tabel 1 bevat twee variabelen, ID en y, terwijl Tabel 2 ID en z verzamelt. In beide gevallen hebben we een sleutelpaar variabel. In ons geval is ID onze sleutel variabele. De functie zoekt naar identieke waarden in beide tabellen en koppelt de geretourneerde waarden aan de rechterkant van tabel 1. De onderstaande afbeelding toont de twee tabellen naast elkaar.
library(dplyr) df_primary <- tribble( ~ID, ~y, "A", 5, "B", 5, "C", 8, "D", 0, "F", 9) df_secondary <- tribble( ~ID, ~z, "A", 30, "B", 21, "C", 22, "D", 25, "E", 29)
dplyr left_join()
De meest gebruikelijke manier om twee datasets samen te voegen is met behulp van de functie left_join(). De onderstaande afbeelding laat zien dat het sleutelpaar overeenkomt met rijen A, B, C en D, terwijl E en F overblijven. Met left_join() behouden we alle rijen in de oorspronkelijke tabel en negeren we de rijen die geen sleutelpaar hebben in de doeltabel. In ons voorbeeld bestaat de waarde E niet in tabel 1, dus die rij wordt verwijderd. De waarde F komt uit de oorspronkelijke tabel, dus die wordt behouden na de left_join() en retourneert NA in kolom z.
Voorbeeld van dplyr left_join()
Het onderstaande diagram laat zien wat er gebeurt tijdens een left_join().
left_join(df_primary, df_secondary, by ='ID')
Output:
## # A tibble: 5 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 F 9 NA
Merk op dat wanneer beide tabellen een kolom met dezelfde naam bevatten, dplyr deze onderscheidt met de achtervoegsels .x en .y zoals hierboven weergegeven.
dplyr right_join()
De functie right_join() werkt precies zoals left_join(). Het enige verschil is dat de rij is geschrapt. De waarde E, beschikbaar in het doelgegevensframe, bestaat in de nieuwe tabel en neemt de waarde NA aan voor de kolom y.
Voorbeeld van dplyr right_join()
Onderstaande afbeelding toont het spiegelbeeld.
right_join(df_primary, df_secondary, by = 'ID')
Output:
## # A tibble: 5 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 E NA 29
dplyr inner_join()
Als niet-overeenkomende waarnemingen helemaal niet bruikbaar zijn, kunnen we ze retourneren. Slechts de rijen die bestaan โโin zowel datasets. Dit is de juiste keuze wanneer we een complete dataset nodig hebben en ontbrekende waarden niet willen invullen met het gemiddelde of de mediaan.
De functie inner_join() biedt hier uitkomst. Deze sluit de rijen aan beide zijden uit die niet overeenkomen.
Voorbeeld van dplyr inner_join()
Het onderstaande diagram toont de vier ID's die na de samenvoeging behouden blijven.
inner_join(df_primary, df_secondary, by ='ID')
Output:
## # A tibble: 4 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25
dplyr full_join()
Tot slot behoudt de functie full_join() alle waarnemingen en vervangt ontbrekende waarden door NA.
Voorbeeld van dplyr full_join()
Het onderstaande diagram toont alle ID's uit beide tabellen die na de samenvoeging behouden blijven.
full_join(df_primary, df_secondary, by = 'ID')
Output:
## # A tibble: 6 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 F 9 NA ## 6 E NA 29
Meerdere sleutelparen
Tot slot kunnen we meerdere sleutels in onze dataset hebben. Neem bijvoorbeeld de volgende dataset met jaartallen en een lijst met producten die door de klant zijn gekocht. De onderstaande schermafbeelding toont de twee tabellen en de kolommen ID en jaar die samen een rij identificeren.
Als we beide tabellen alleen op basis van ID samenvoegen, wordt elk jaar aan elk ander jaar gekoppeld en explodeert het aantal rijen. Om dit te verhelpen, kunnen we twee sleutel-waardeparen doorgeven: ID en jaar, die in beide datasets voorkomen. We kunnen de volgende code gebruiken om tabel 1 en tabel 2 samen te voegen:
df_primary <- tribble( ~ID, ~year, ~items, "A", 2015,3, "A", 2016,7, "A", 2017,6, "B", 2015,4, "B", 2016,8, "B", 2017,7, "C", 2015,4, "C", 2016,6, "C", 2017,6) df_secondary <- tribble( ~ID, ~year, ~prices, "A", 2015,9, "A", 2016,8, "A", 2017,12, "B", 2015,13, "B", 2016,14, "B", 2017,6, "C", 2015,15, "C", 2016,15, "C", 2017,13) left_join(df_primary, df_secondary, by = c('ID', 'year'))
Output:
## # A tibble: 9 x 4 ## ID year items prices ## <chr> <dbl> <dbl> <dbl> ## 1 A 2015 3 9 ## 2 A 2016 7 8 ## 3 A 2017 6 12 ## 4 B 2015 4 13 ## 5 B 2016 8 14 ## 6 B 2017 7 6 ## 7 C 2015 4 15 ## 8 C 2016 6 15 ## 9 C 2017 6 13
Sinds dplyr 1.1.0 (januari 2023) kan dezelfde sleutel worden geschreven als join_by(ID, year), en dplyr waarschuwt nu voor onverwachte vele-op-vele-relaties, omdat de dplyr 1.1.0 voegt zich bij de aankondiging verklaart.
Gegevensopschoonfuncties in R
Het samenvoegen lost slechts de helft van het probleem op, omdat de gecombineerde tabel nog steeds opnieuw moet worden opgemaakt. Hieronder volgen de vier belangrijkste functies om de gegevens op te schonen:
| Functie | Objectief | argumenten |
|---|---|---|
| bijeenkomen() | Transformeer de gegevens van breed naar lang | (gegevens, sleutel, waarde, na.rm = FALSE) |
| spreiding() | Transformeer de gegevens van lang naar breed | (gegevens, sleutel, waarde) |
| verschillend() | Splits รฉรฉn variabele op in tweeรซn | (data, col, into, sep = โโ, remove = TRUE) |
| verenigen() | Twee variabelen samenvoegen tot รฉรฉn | (data, col, conc, sep = โโ, remove = TRUE) |
Versie-opmerking: De functies gather() en spread() werden in tidyr 1.0.0 vervangen door pivot_longer() en pivot_wider(), en separate() door de separate_wider_delim()-familie in tidyr 1.3.0. De vervangen functies werken nog steeds, dus alle onderstaande voorbeelden zijn correct, maar nieuwe code zou de voorkeur moeten geven aan de nieuwere families die in de documentatie worden weergegeven. tidyr draaibare vignet. unite() blijft actueel.
We gebruiken het tidyr-pakket, onderdeel van de tidyverse-collectie, voor het manipuleren, opschonen en visualiseren van data. Als R is geรฏnstalleerd met Anaconda, is het pakket al beschikbaar via https://anaconda.org/r/r-tidyr.
Als het nog niet is geรฏnstalleerd, voer dan de volgende opdracht in om tidyr te installeren:
install.packages("tidyr")
bijeenkomen()
Het doel van de functie gather() is om de gegevens van breed naar lang te transformeren.
Syntaxis
gather(data, key, value, na.rm = FALSE) Arguments: -data: The data frame used to reshape the dataset -key: Name of the new column created -value: Select the columns used to fill the key column -na.rm: Remove missing values. FALSE by default
Voorbeeld
Hieronder kunnen we het concept van resha visualiseren.ping Van breed naar lang. We willen รฉรฉn kolom maken met de naam 'groei', gevuld met de rijen van de kwartaalvariabelen. De onderstaande afbeelding toont de brede tabel aan de linkerkant en de aangepaste lange tabel aan de rechterkant.
library(tidyr) # Create a messy dataset messy <- data.frame( country = c("A", "B", "C"), q1_2017 = c(0.03, 0.05, 0.01), q2_2017 = c(0.05, 0.07, 0.02), q3_2017 = c(0.04, 0.05, 0.01), q4_2017 = c(0.03, 0.02, 0.04)) messy
Output:
## country q1_2017 q2_2017 q3_2017 q4_2017 ## 1 A 0.03 0.05 0.04 0.03 ## 2 B 0.05 0.07 0.05 0.02 ## 3 C 0.01 0.02 0.01 0.04
# Reshape the data
tidier <-messy %>%
gather(quarter, growth, q1_2017:q4_2017)
tidier
Output:
## country quarter growth ## 1 A q1_2017 0.03 ## 2 B q1_2017 0.05 ## 3 C q1_2017 0.01 ## 4 A q2_2017 0.05 ## 5 B q2_2017 0.07 ## 6 C q2_2017 0.02 ## 7 A q3_2017 0.04 ## 8 B q3_2017 0.05 ## 9 C q3_2017 0.01 ## 10 A q4_2017 0.03 ## 11 B q4_2017 0.02 ## 12 C q4_2017 0.04
In de gather()-functie maken we twee nieuwe variabelen aan, quarter en growth, omdat onze oorspronkelijke dataset รฉรฉn groepsvariabele bevat, country, en de sleutel-waardeparen. In tidyr 1.0.0 en later wordt dezelfde reshape geschreven als pivot_longer(messy, cols = q1_2017:q4_2017, names_to = โquarterโ, values_to = โgrowthโ).
spreiding()
De spread()-functie doet het tegenovergestelde van gather().
Syntaxis
spread(data, key, value) arguments: data: The data frame used to reshape the dataset key: Column to reshape long to wide value: Rows used to fill the new column
Voorbeeld
We kunnen de nettere dataset weer omvormen tot een rommelige dataset met behulp van spread().
# Reshape the data
messy_1 <- tidier %>%
spread(quarter, growth)
messy_1
Output:
## country q1_2017 q2_2017 q3_2017 q4_2017 ## 1 A 0.03 0.05 0.04 0.03 ## 2 B 0.05 0.07 0.05 0.02 ## 3 C 0.01 0.02 0.01 0.04
Het moderne equivalent is pivot_wider(tidier, names_from = quarter, values_from = growth).
verschillend()
De functie `separate()` splitst een kolom in tweeรซn op basis van een scheidingsteken. Deze functie is handig in situaties waarin de variabele een datum is. Onze analyse vereist mogelijk dat we ons richten op de maand en het jaar, en we willen de kolom dan opsplitsen in twee nieuwe variabelen.
Syntaxis
separate(data, col, into, sep= "", remove = TRUE) arguments: -data: The data frame used to reshape the dataset -col: The column to split -into: The name of the new variables -sep: Indicates the symbol used that separates the variable, i.e.: "-", "_", "&" -remove: Remove the old column. By default sets to TRUE.
Voorbeeld
We kunnen het kwartaal van het jaar splitsen in de overzichtelijkere dataset door de functie separate() toe te passen.
separate_tidier <-tidier %>% separate(quarter, c("Qrt", "year"), sep ="_") head(separate_tidier)
Output:
## country Qrt year growth ## 1 A q1 2017 0.03 ## 2 B q1 2017 0.05 ## 3 C q1 2017 0.01 ## 4 A q2 2017 0.05 ## 5 B q2 2017 0.07 ## 6 C q2 2017 0.02
verenigen()
De functie unite() voegt twee kolommen samen tot รฉรฉn.
Syntaxis
unite(data, col, conc ,sep= "", remove = TRUE) arguments: -data: The data frame used to reshape the dataset -col: Name of the new column -conc: Name of the columns to concatenate -sep: Indicates the symbol used that unites the variable, i.e: "-", "_", "&" -remove: Remove the old columns. By default, sets to TRUE
Voorbeeld
In het bovenstaande voorbeeld hebben we het kwartaal en het jaar gescheiden. Wat als we ze willen samenvoegen? Dan gebruiken we de volgende code:
unit_tidier <- separate_tidier %>%
unite(Quarter, Qrt, year, sep ="_")
head(unit_tidier)
Output:
## country Quarter growth ## 1 A q1_2017 0.03 ## 2 B q1_2017 0.05 ## 3 C q1_2017 0.01 ## 4 A q2_2017 0.05 ## 5 B q2_2017 0.07 ## 6 C q2_2017 0.02
Het herschikte dataframe is nu klaar voor de modelleringsstappen die in de rest van dit document worden behandeld. R-zelfstudieserie.







