dplyr i R-vejledning: Flet og saml data med eksempler

⚡ Smart opsummering

dplyr fletter og joiner dataframes i R med fire verber: left_join(), right_join(), inner_join() og full_join(). Dens ledsagende pakke tidyr omformer derefter det joinede resultat ved hjælp af gather(), spread(), separate() og unite().

  • 🔗 Muterende joins: left_join() gemmer alle rækker i oprindelsestabellen, og right_join() gemmer alle rækker i destinationstabellen.
  • 🎯 Kampkontrol: inner_join() fjerner umatchede rækker, mens full_join() beholder begge sider og udfylder hullerne med NA.
  • 🗝️ Sammensatte nøgler: Pass by = c("ID", "år"), når en enkelt kolonne ikke identificerer en række entydigt.
  • 🔄 Reshaping: gather() gør et bredt bord langt og spread() gør det tilbage, keeping én variabel pr. kolonne.
  • ✂️ Splittelse og forening: separate() opdeler en kolonne på et afgrænsertegn, og unite() sammenkæder kolonner tilbage til én.
  • ⚠️ Versionsnote: pivot_longer(), pivot_wider() og separate_wider_delim() erstatter den ældre tidyr-omstrukturering.ping funktioner.

Dplyr i R: Flet og saml data

Introduktion til dataanalyse

Før enhver tilmelding eller omdelingping verbet giver mening, det hjælper med at se, hvor datamanipulation passer ind. Dataanalyse kan opdeles i tre dele:

  • Extraction: For det første skal vi indsamle data fra mange kilder og kombinere dem.
  • Transform: Dette trin involverer datamanipulation. Når vi har konsolideret alle datakilderne, kan vi begynde at rense dataene.
  • Visualiser: Det sidste skridt er at visualisere vores data for at kontrollere uregelmæssigheder.

Diagrammet nedenfor viser, hvordan de tre faser er forbundet.

Tretrins dataanalyseproces, der viser f.eks.traction, transformation og visualisering
Dataanalyseproces

En af de største udfordringer for dataloger er datamanipulation. Data er aldrig tilgængelige i det ønskede format. Dataloger skal bruge mindst halvdelen af ​​deres tid på at rense og manipulere dataene. Det er en af ​​de mest kritiske opgaver i jobbet. Hvis datamanipulationsprocessen ikke er fuldstændig, præcis og stringent, vil modellen ikke fungere korrekt.

R-dplyer

R har en pakke kaldet dplyr, der håndterer datatransformation. Den er bygget op omkring et lille sæt af kerneverber — filter(), select(), arrange(), mutate() og summary() — plus en familie af join-funktioner. Når dataene er i form, kan ggplot2 visualisere dem.

Vi lærer, hvordan man bruger dplyr-pakken til at manipulere en DatarammeHvis R ikke er installeret endnu, skal du følge instruktionerne R og RStudio opsætningstrin, og kør derefter install.packages("dplyr").

Flet data med dplyr

dplyr giver en god og praktisk måde at kombinere datasæt på. Vi kan have mange kilder til inputdata, og på et tidspunkt skal vi kombinere dem. En joinforbindelse med dplyr tilføjer variabler til højre for det originale datasæt.

dplyr-tilslutninger

Følgende er fire vigtige typer joins, der bruges i dplyr til at flette to datasæt. Alle fire tager de samme argumenter - de to tabeller og nøglen - og adskiller sig kun ved, hvilke uoverensstemmende rækker der overlever:

Funktion Objektiv argumenter Flere nøgler
left_join() Flet to datasæt. Gem alle observationer fra oprindelsestabellen x, y, ved = “ID” x, y, ved = c("ID", "ID2")
right_join() Flet to datasæt. Gem alle observationer fra destinationstabellen x, y, ved = “ID” x, y, ved = c("ID", "ID2")
indre_join() Flet to datasæt. Udeluk alle uoverensstemmende rækker x, y, ved = “ID” x, y, ved = c("ID", "ID2")
fuld_deltagelse() Flet to datasæt. Behold alle observationer. x, y, ved = “ID” x, y, ved = c("ID", "ID2")

Disse fire verber knytter sig til VENSTRE-, HØJRE-, INDRE- og FULLE YDRE-sammenføjningerne af SQLBasis R når de samme resultater gennem argumenterne all, all.x og all.y i fusionere().

Vi vil studere alle join-typerne via et simpelt eksempel.

Først og fremmest opbygger vi to datasæt. Tabel 1 indeholder to variabler, ID og y, mens tabel 2 indsamler ID og z. I hver situation skal vi have en nøgle-par variabel. I vores tilfælde er ID vores nøgle variabel. Funktionen vil søge efter identiske værdier i begge tabeller og binde de returnerende værdier til højre for tabel 1. Figuren nedenfor viser de to tabeller side om side.

To eksempeltabeller, der deler en ID-nøglekolonne før en dplyr-fletning

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()

Den mest almindelige måde at flette to datasæt sammen på er at bruge funktionen left_join(). Billedet nedenfor viser, at nøgleparret matcher rækkerne A, B, C og D, mens E og F bliver tilbage. Med left_join() beholder vi alle rækkerne i den oprindelige tabel og ignorerer de rækker, der ikke har noget nøglepar i destinationstabellen. I vores eksempel findes værdien E ikke i tabel 1, så den række udelades. Værdien F kommer fra oprindelsestabellen, så den bevares efter left_join() og returnerer NA i kolonne z.

Eksempel på dplyr left_join()

Diagrammet nedenfor gengiver, hvad der sker under en left_join().

Diagram over dplyr left_join keeping hver række i oprindelsestabellen og slipping ID E

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

Bemærk, at når begge tabeller har en kolonne med samme navn, gør dplyr dem flertydige med suffikserne .x og .y vist ovenfor.

dplyr right_join()

Funktionen right_join() fungerer præcis som left_join(). Den eneste forskel er, at rækken er faldet. Værdien E, tilgængelig i destinationsdatarammen, findes i den nye tabel og tager værdien NA for kolonnen y.

Eksempel på dplyr right_join()

Diagrammet nedenfor viser spejlbilledet.

Diagram over dplyr right_join keeping hver række i destinationstabellen og slipping ID F

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()

Når uoverensstemmende observationer slet ikke er til nogen nytte, kan vi vende tilbage kun de rækker, der findes i både datasæt. Dette er det rigtige valg, når vi har brug for et komplet datasæt og ikke ønsker at imputere manglende værdier med middelværdien eller medianen.

Funktionen inner_join() kommer til hjælp her. Den udelukker de ikke-matchede rækker på begge sider.

Eksempel på dplyr inner_join()

Diagrammet nedenfor fremhæver de fire ID'er, der overlever join-funktionen.

Diagram over dplyr inner_join, der kun returnerer de fire ID'er, der findes i begge tabeller

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()

Endelig gemmer full_join()-funktionen alle observationer og erstatter manglende værdier med NA.

Eksempel på dplyr full_join()

Diagrammet nedenfor viser alle ID'er fra begge tabeller, der overlever joinforbindelsen.

Diagram over dplyr full_join keeping alle seks ID'er og udfyldning af manglende værdier med NA

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

Flere nøglepar

Sidst men ikke mindst kan vi have flere nøgler i vores datasæt. Overvej følgende datasæt, hvor vi har år og en liste over produkter købt af kunden. Skærmbilledet nedenfor viser de to tabeller og ID- og årkolonnerne, der tilsammen identificerer en række.

To datarammer, der deler en sammensat nøgle bestående af ID- og årskolonnerne

Hvis vi fletter begge tabeller sammen udelukkende baseret på ID, matches hvert år mod hvert år, og rækkeantallet eksploderer. For at afhjælpe situationen kan vi overføre to nøgleparvariabler. Det vil sige ID og år, som vises i begge datasæt. Vi kan bruge følgende kode til at flette tabel 1 og tabel 2:

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

Siden dplyr 1.1.0 (januar 2023) kan den samme nøgle skrives som join_by(ID, year), og dplyr advarer nu om uventede mange-til-mange-matches, da dplyr 1.1.0 tiltrædelsesmeddelelse forklarer.

Datarensningsfunktioner i R

Sammenlægning løser kun halvdelen af ​​problemet, fordi den kombinerede tabel stadig skal omformes. Følgende er de fire vigtige funktioner til at rydde op (rense) dataene:

Funktion Objektiv argumenter
samle() Transformer dataene fra brede til lange (data, nøgle, værdi, na.rm = FALSK)
spredning() Transformer dataene fra lange til brede (data, nøgle, værdi)
adskille() Opdel én variabel i to (data, col, into, sep = “”, fjern = TRUE)
forene() Foren to variabler til én (data, kolonne, konc., sep = “”, fjern = SAND)

Versionsnotat: gather() og spread() blev erstattet af pivot_longer() og pivot_wider() i tidyr 1.0.0, og separate() af separate_wider_delim()-familien i tidyr 1.3.0. Erstattede funktioner kører stadig, så alle eksempler nedenfor fungerer, men ny kode bør foretrække de nyere familier vist i tidyr drejelig vignette. unite() forbliver aktuel.

Vi bruger tidyr-pakken, som er en del af tidyverse-samlingen, til at manipulere, rense og visualisere data. Hvis R blev installeret med Anaconda, er pakken allerede tilgængelig fra https://anaconda.org/r/r-tidyr.

Hvis det ikke allerede er installeret, skal du indtaste følgende kommando for at installere tidyr:

install.packages("tidyr")

samle()

Formålet med gather()-funktionen er at transformere dataene fra wide til long.

Syntaks

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

Eksempel

Nedenfor kan vi visualisere konceptet reshaping bred til lang. Vi ønsker at oprette en enkelt kolonne med navnet vækst, udfyldt af rækkerne med kvartvariablerne. Figuren nedenfor viser den brede tabel til venstre og den omformede lange tabel til højre.

Reshaping en bred kvartalstabel i langt format med tidyr gather-funktionen

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

I funktionen gather() opretter vi to nye variabler, quarter og growth, fordi vores oprindelige datasæt har én gruppevariabel, country, og nøgle-værdi-parrene. I tidyr 1.0.0 og senere er den samme omformning skrevet som pivot_longer(messy, cols = q1_2017:q4_2017, names_to = “quarter”, values_to = “growth”).

spredning()

Funktionen spread() gør det modsatte af gather().

Syntaks

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

Eksempel

Vi kan omforme det mere ryddelige datasæt tilbage til rodet med 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

Den moderne ækvivalent er pivot_wider(tidier, names_from = quarter, values_from = growth).

adskille()

Funktionen separate() opdeler en kolonne i to ved hjælp af en separator. Denne funktion er nyttig i situationer, hvor variablen er en dato. Vores analyse kan kræve fokus på måned og år, og vi ønsker at opdele kolonnen i to nye variabler.

Syntaks

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.

Eksempel

Vi kan opdele kvartalet fra året i det mere ryddelige datasæt ved at anvende separat()-funktionen.

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

forene()

Funktionen unite() sammenkæder to kolonner til én.

Syntaks

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

Eksempel

I ovenstående eksempel har vi adskilt kvartaler fra år. Hvad hvis vi vil flette dem sammen? Vi bruger følgende kode:

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

Den omformede dataramme er nu klar til de modelleringstrin, der er dækket i resten af R-tutorialserie.

Ofte Stillede Spørgsmål

merge() udtrykker hver join gennem flagene all, all.x og all.y, mens dplyr navngiver adfærden i selve verbet. dplyr bevarer også den oprindelige rækkefølge og returnerer en tibble. Den grundlæggende R-rute er dækket i flette datarammer guide.

De filtrerer join-funktioner, så de tilføjer aldrig kolonner. semi_join(x, y) gemmer de rækker i x, der har et match i y, og anti_join(x, y) gemmer de rækker, der ikke har. Begge er nyttige til at kontrollere nøgler før et muterende join-system.

Kortlæg dem eksplicit med by = c("ID" = "customer_id"), eller brug den nyere join_by(ID == customer_id) hjælper. Uden en kortlægningping, dplyr matcher på hvert delt kolonnenavn, hvilket lydløst kan indsnævre resultatet eller forstørre det.

En nøgleværdi gentages på begge sider, så hver kombination produceres. Tjek duplicated() på hver nøgle først, aggreger mange-siden, eller send relationship = “many-to-many” for at angive intentionen. dplyr advarer om uventede mange-til-mange-matches.

filter() vælger rækker, select() vælger kolonner, arranger() magi, mutate() tilføjer kolonner, og summary() skjuler grupper lavet af group_by(). Pipe-funktionen fører ét resultat ind i det næste verbum; %>% leveres med dplyr, og |> er native R.

AI-assistenter kan profilere en dataramme, markere dubletter eller forkert stavede nøgler før en join, foreslå omstruktureringping et verbum, der passer til layoutet, og forklar en pludselig ændring i rækkeantallet i et letforståeligt sprog. Kør altid koden igen, og tjek selv dimensionerne.

Ja. GitHub Copilot fungerer i RStudio Desktop 2023.09.0 og nyere og fuldfører join- og pivot-pipelines fra en kommentar. Posit bemærker, at forslag ikke er deterministiske, så gennemgå hver genereret linje, før du kører den.

Kæd sammen joinerne, eller fold en liste med Reduce(function(x, y) left_join(x, y, by = “ID”), list(df1, df2, df3)). purrr::reduce() gør det samme. Tjek nrow() efter hvert trin, fordi duplikerede nøgler sammensættes på tværs af join.

Opsummer dette indlæg med: