dplyr u R vodiču: Spajanje i spajanje podataka s primjerima

⚡ Pametni sažetak

dplyr spaja i spaja podatkovne okvire u R-u pomoću četiri glagola: left_join(), right_join(), inner_join() i full_join(). Njegov prateći paket tidyr zatim preoblikuje spojeni rezultat pomoću gather(), spread(), separate() i unite().

  • 🔗 Mutirajući spojevi: left_join() čuva svaki redak izvorne tablice, a right_join() čuva svaki redak odredišne ​​tablice.
  • 🎯 Kontrola utakmice: inner_join() izostavlja neusklađene retke, dok full_join() zadržava obje strane i popunjava praznine s NA.
  • 🗝️ Kompozitni ključevi: Propusti = c(“ID”, “year”) kad god jedan stupac ne identificira redak jedinstveno.
  • 🔄 Rešaping: gather() okreće široku tablicu dugo, a spread() je okreće natrag, keeping jedna varijabla po stupcu.
  • ✂️ Razdvajanje i ujedinjenje: separate() dijeli stupac na razdjelniku, a unite() spaja stupce natrag u jedan.
  • ⚠️ Napomena o verziji: pivot_longer(), pivot_wider() i separate_wider_delim() zamjenjuju stariji tidyr reshaping funkcije.

Dplyr u R-u: Spajanje i pridruživanje podataka

Uvod u analizu podataka

Prije bilo kakvog pridruživanja ili ponovnog dijeljenjaping Glagol ima smisla, pomaže vidjeti gdje se manipulacija podacima uklapa. Analiza podataka može se podijeliti na tri dijela:

  • ExtracANJE: Prvo, moramo prikupiti podatke iz mnogih izvora i kombinirati ih.
  • Transformirati: Ovaj korak uključuje manipulaciju podacima. Nakon što smo konsolidirali sve izvore podataka, možemo početi čistiti podatke.
  • Vizualizirajte: Zadnji korak je vizualizacija naših podataka kako bismo provjerili nepravilnosti.

Donji dijagram prikazuje kako su tri faze povezane.

Trofazni proces analize podataka koji prikazuje extraccija, transformacija i vizualizacija
Proces analize podataka

Jedan od najznačajnijih izazova s ​​kojima se suočavaju znanstvenici podataka je manipulacija podacima. Podaci nikada nisu dostupni u željenom formatu. Znanstvenici podataka moraju potrošiti barem polovicu svog vremena čisteći i manipulirajući podacima. To je jedan od najvažnijih zadataka u poslu. Ako proces manipulacije podacima nije potpun, precizan i rigorozan, model neće ispravno funkcionirati.

R dplyr

R ima paket pod nazivom dplyr koji se bavi transformacijom podataka. Izgrađen je oko malog skupa osnovnih funkcija - filter(), select(), arrange(), mutate() i summarize() - plus obitelji funkcija spajanja. Nakon što su podaci oblikovani, ggplot2 ih može vizualizirati.

Naučit ćemo kako koristiti dplyr paket za manipuliranje Okvir podatakaAko R još nije instaliran, slijedite upute Koraci postavljanja R i RStudio, a zatim pokrenite install.packages(“dplyr”).

Spoji podatke s dplyrom

dplyr pruža lijep i praktičan način kombiniranja skupova podataka. Možemo imati mnogo izvora ulaznih podataka iu nekom trenutku ćemo ih morati kombinirati. Spajanje s dplyr dodaje varijable s desne strane izvornog skupa podataka.

dplyr pridružuje se

Slijede četiri važne vrste spajanja koje se koriste u dplyr-u za spajanje dva skupa podataka. Sve četiri uzimaju iste argumente - dvije tablice i ključ - i razlikuju se samo po tome koji neusklađeni retci preživljavaju:

funkcija Cilj argumenti Više tipki
lijevo_pridruživanje() Spoji dva skupa podataka. Sačuvajte sva opažanja iz matične tablice x, y, by = “ID” x, y, by = c(“ID”, “ID2”)
desno_pridruživanje() Spoji dva skupa podataka. Sačuvajte sva zapažanja iz odredišne ​​tablice x, y, by = “ID” x, y, by = c(“ID”, “ID2”)
unutarnje_pridruživanje() Spoji dva skupa podataka. Isključi sve neusklađene retke x, y, by = “ID” x, y, by = c(“ID”, “ID2”)
full_join() Spoji dva skupa podataka. Zadrži sva zapažanja x, y, by = “ID” x, y, by = c(“ID”, “ID2”)

Ova četiri glagola preslikavaju se na LIJEVE, DESNE, UNUTARNJE i POTPUNE VANJSKE spojeve od SQLBaza R postiže iste rezultate putem argumenata all, all.x i all.y od sjediniti().

Proučit ćemo sve vrste spajanja putem jednostavnog primjera.

Prvo, gradimo dva skupa podataka. Tablica 1 sadrži dvije varijable, ID i y, dok Tablica 2 prikuplja ID i z. U svakoj situaciji moramo imati par ključeva varijabla. U našem slučaju ID je naš ključ varijabla. Funkcija će tražiti identične vrijednosti u obje tablice i vezati vraćene vrijednosti desno od tablice 1. Donja slika prikazuje dvije tablice jednu pored druge.

Dvije primjerne tablice koje dijele stupac ključa ID-a prije spajanja dplyr-a

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 lijevo_pridruživanje()

Najčešći način spajanja dvaju skupova podataka je korištenje funkcije left_join(). Slika ispod pokazuje da par ključeva odgovara retcima A, B, C i D, dok E i F ostaju. Pomoću funkcije left_join() zadržavamo sve retke u izvornoj tablici i ignoriramo retke koji nemaju par ključeva u odredišnoj tablici. U našem primjeru, vrijednost E ne postoji u tablici 1, pa se taj redak odbacuje. Vrijednost F dolazi iz izvorne tablice, pa se zadržava nakon funkcije left_join() i vraća NA u stupcu z.

Primjer dplyr left_join()

Donji dijagram reproducira što se događa tijekom left_join().

Dijagram dplyr left_join keeping svaki redak izvorne tablice i ispustiteping ID E

left_join(df_primary, df_secondary, by ='ID')

Izlaz:

## 
# 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

Imajte na umu da kada obje tablice sadrže stupac istog imena, dplyr ih razdvaja pomoću sufiksa .x i .y prikazanih gore.

dplyr desno_pridruživanje()

Funkcija right_join() radi točno kao left_join(). Jedina razlika je ispušten red. Vrijednost E, dostupna u odredišnom okviru podataka, postoji u novoj tablici i uzima vrijednost NA za stupac y.

Primjer dplyr right_join()

Donji dijagram prikazuje zrcalnu sliku.

Dijagram dplyr right_join keeping svaki redak odredišne ​​tablice i ispustiteping ID F

right_join(df_primary, df_secondary, by = 'ID')

Izlaz:

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

Kada neusklađena opažanja uopće nisu korisna, možemo se vratiti samo redovi koji postoje u oboje skupovi podataka. Ovo je pravi izbor kada nam je potreban potpuni skup podataka i ne želimo imputirati nedostajuće vrijednosti sa srednjom vrijednošću ili medijanom.

Ovdje pomaže funkcija inner_join(). Ona isključuje neusklađene retke s obje strane.

Primjer dplyr inner_join()

Donji dijagram ističe četiri ID-a koji preživljavaju spajanje.

Dijagram dplyr inner_join-a koji vraća samo četiri ID-a prisutna u obje tablice

inner_join(df_primary, df_secondary, by ='ID')

Izlaz:

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

Konačno, funkcija full_join() čuva sva opažanja i zamjenjuje nedostajuće vrijednosti s NA.

Primjer dplyr full_join()

Donji dijagram prikazuje svaki ID iz obje tablice koji je preživio spajanje.

Dijagram dplyr full_join keeping svih šest ID-ova i popunjavanje nedostajućih vrijednosti s NA

full_join(df_primary, df_secondary, by = 'ID')

Izlaz:

## # 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

Više parova ključeva

Konačno, u našem skupu podataka možemo imati više ključeva. Razmotrimo sljedeći skup podataka gdje imamo godine i popis proizvoda koje je kupac kupio. Snimka zaslona u nastavku prikazuje dvije tablice i stupce ID i godina koji zajedno identificiraju redak.

Dva podatkovna okvira koji dijele složeni ključ sastavljen od stupaca ID i godina

Ako spojimo obje tablice samo na temelju ID-a, svaka godina se uspoređuje sa svakom godinom i broj redaka eksplodira. Kako bismo riješili situaciju, možemo proslijediti dvije varijable para ključeva. To jest, ID i godinu, koje se pojavljuju u oba skupa podataka. Možemo upotrijebiti sljedeći kod za spajanje tablice 1 i tablice 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'))

Izlaz:

## # 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

Od verzije dplyr 1.1.0 (siječanj 2023.) isti ključ se može zapisati kao join_by(ID, godina), a dplyr sada upozorava na neočekivana podudaranja više-prema-više, kao što je Objava o pridruživanju dplyr-a 1.1.0 objašnjava.

Funkcije čišćenja podataka u R

Spajanje rješava samo pola problema, jer kombiniranu tablicu još treba preoblikovati. Slijede četiri važne funkcije za čišćenje podataka:

funkcija Cilj argumenti
skupiti () Pretvorite podatke iz širokih u dugačke (podaci, ključ, vrijednost, na.rm = FALSE)
širenje() Pretvorite podatke iz dugih u široke (podatak, ključ, vrijednost)
odvojeno() Podijelite jednu varijablu na dvije (podaci, stupac, u, odjeljka = "", ukloni = ISTINA)
ujediniti() Spojite dvije varijable u jednu (podaci, stupac, koncentracija, odjeljka = "", uklanjanje = ISTINA)

Napomena o verziji: Funkcije gather() i spread() zamijenjene su funkcijama pivot_longer() i pivot_wider() u tidyru 1.0.0, a separate() obitelji separate_wider_delim() u tidyru 1.3.0. Zamijenjene funkcije i dalje se izvode, tako da svaki primjer u nastavku radi, ali novi kod bi trebao preferirati novije obitelji prikazane u vinjeta za okretanje tidyr-a. unite() ostaje aktualna.

Za manipuliranje, čišćenje i vizualizaciju podataka koristimo paket tidyr, dio kolekcije tidyverse. Ako je R instaliran s Anacondom, paket je već dostupan od https://anaconda.org/r/r-tidyr.

Ako već nije instaliran, unesite sljedeću naredbu da instalirate tidyr:

install.packages("tidyr")

skupiti ()

Cilj funkcije gather() je transformirati podatke iz širokih u duge.

Sintaksa

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

Primjer

U nastavku možemo vizualizirati koncept reshaping od širokog do dugog. Želimo stvoriti jedan stupac pod nazivom rast, ispunjen retcima varijabli kvartala. Donja slika prikazuje široku tablicu s lijeve strane i preoblikovanu dugu tablicu s desne strane.

Rešaping široku tromjesečnu tablicu u dugi format pomoću funkcije uređivanja i gašenja

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

Izlaz:

##   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

Izlaz:

##    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

U funkciji gather() stvaramo dvije nove varijable, kvartal i rast, jer naš izvorni skup podataka ima jednu grupnu varijablu, državu, i parove ključ-vrijednost. U tidyr-u 1.0.0 i novijim verzijama isto preoblikovanje je zapisano kao pivot_longer(messy, cols = q1_2017:q4_2017, names_to = “quarter”, values_to = “growth”).

širenje()

Funkcija spread() radi suprotno od funkcije gather().

Sintaksa

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

Primjer

Uredniji skup podataka možemo preoblikovati natrag u neuredan pomoću spread().

# Reshape the data
messy_1 <- tidier %>%
  spread(quarter, growth) 
messy_1

Izlaz:

##   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

Moderni ekvivalent je pivot_wider(tidier, names_from = kvartal, values_from = rast).

odvojeno()

Funkcija separate() dijeli stupac na dva dijela prema razdjelniku. Ova je funkcija korisna u situacijama kada je varijabla datum. Naša analiza može zahtijevati fokusiranje na mjesec i godinu, a želimo razdvojiti stupac na dvije nove varijable.

Sintaksa

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.

Primjer

Možemo razdvojiti tromjesečje od godine u urednijem skupu podataka primjenom funkcije separate().

separate_tidier <-tidier %>%
separate(quarter, c("Qrt", "year"), sep ="_")
head(separate_tidier)

Izlaz:

##   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

ujediniti()

Funkcija unite() spaja dva stupca u jedan.

Sintaksa

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

Primjer

U gornjem primjeru odvojili smo kvartal od godine. Što ako ih želimo spojiti? Koristimo sljedeći kod:

unit_tidier <- separate_tidier %>%
  unite(Quarter, Qrt, year, sep ="_")
head(unit_tidier)

Izlaz:

##   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

Preoblikovani okvir podataka sada je spreman za korake modeliranja obuhvaćene u ostatku Serija tutorijala za R.

Pitanja i odgovori

merge() izražava svako spajanje putem zastavica all, all.x i all.y, dok dplyr imenuje ponašanje u samom glagolu. dplyr također čuva izvorni redoslijed redaka i vraća tibble. Osnovna R ruta je obuhvaćena u spajanje okvira podataka vodič.

Oni filtriraju spajanja, tako da nikada ne dodaju stupce. semi_join(x, y) čuva retke x koji imaju podudaranje u y, a anti_join(x, y) čuva retke koji ga nemaju. Oba su korisna za reviziju ključeva prije mutirajućeg spajanja.

Izričito ih mapirajte s by = c(“ID” = “customer_id”) ili upotrijebite noviji pomoćnik join_by(ID == customer_id). Bez mapiranjaping, dplyr se podudara sa svakim zajedničkim nazivom stupca, što može tiho suziti rezultat ili ga uvećati.

Ključna vrijednost se ponavlja na obje strane, tako da se generira svaka kombinacija. Prvo provjerite duplicated() na svakom ključu, agregirajte stranu "mnogo" ili proslijedite relationship = "mnogo-prema-mnogo" kako biste naveli namjeru. dplyr upozorava na neočekivana podudaranja "mnogo-prema-mnogo".

filter() odabire retke, select() odabire stupce, arrange() vrste, mutate() dodaje stupce, a summarize() sažima grupe koje je stvorio glagol group_by(). Cjevovod uvodi jedan rezultat u sljedeći glagol; %>% dolazi s dplyr-om, a |> je izvorni R.

AI asistenti mogu profilirati podatkovni okvir, označiti duplicirane ili pogrešno unesene ključeve prije spajanja, predložiti ponovno oblikovanjeping glagol koji odgovara rasporedu i objasnite iznenadnu promjenu broja redaka jednostavnim jezikom. Uvijek ponovno pokrenite kôd i sami provjerite dimenzije.

Da. GitHub kopilot Radi u RStudio Desktopu 2023.09.0 i novijim verzijama te dovršava spajanje i pivotiranje cjevovoda iz komentara. Posit napominje da prijedlozi nisu deterministički, stoga pregledajte svaki generirani redak prije pokretanja.

Spojite spojeve u lanac ili savijte listu pomoću Reduce(function(x, y) left_join(x, y, by = “ID”), list(df1, df2, df3)). purrr::reduce() radi isto. Provjerite nrow() nakon svakog koraka, jer se duplicirani ključevi spajaju u spojevima.

Sažmite ovu objavu uz: