Îmbinați cadre de date în R: potrivire completă și parțială
⚡ Rezumat inteligent
Îmbinarea cadrelor de date în R unește două tabele pe una sau mai multe coloane cheie partajate. Funcția merge() acoperă joncțiunile interne, stânga, dreapta și complete, iar această demonstrație demonstrează atât o potrivire completă, cât și o potrivire parțială.

Foarte des, avem date din mai multe surse. Pentru a efectua o analiză, trebuie îmbina două cadre de date împreună cu unul sau mai multe variabile cheie comune.
Tipuri de îmbinare (join) în R
Înainte de a parcurge exemplele, este util să știți că merge() efectuează fiecare tip de joncțiune așteptat de un utilizator SQL. Comportamentul este controlat de argumentele all, all.x și all.y, mai degrabă decât de un nume de funcție diferit.
| Tipul de alăturare | Rânduri păstrate | apel merge() | echivalent dplyr |
|---|---|---|---|
| Îmbinare internă (implicită) | Doar tastele sunt prezente în ambele cadre | îmbinare(x, y, prin = „k”) | inner_join(x, y, by = „k”) |
| Îmbinare exterioară stângă | Toate rândurile lui x, NA unde y nu are nicio potrivire | merge(x, y, by = „k”, all.x = TRUE) | left_join(x, y, by = „k”) |
| Îmbinarea exterioară dreaptă | Toate rândurile lui y, NA unde x nu are nicio potrivire | merge(x, y, by = „k”, all.y = TRUE) | right_join(x, y, by = „k”) |
| Îmbinare exterioară completă | Fiecare rând din ambele cadre | îmbinare(x, y, prin = „k”, toate = ADEVĂRAT) | full_join(x, y, prin = „k”) |
| Alăturați-vă încrucișat | Fiecare combinație de rânduri | îmbinare(x, y, prin = NULL) | cross_join(x, y) |
Două detalii merită reținute înainte de primul apel:
- Omiterea lui `by` face ca R să se îmbine pe fiecare nume de coloană pe care îl au în comun cele două cadre, ceea ce este rareori ceea ce doriți.
- merge() sortează rezultatul după coloana cheie; pass sort = FALSE pentru a păstra ordinea de intrare.
Meci intreg
O potrivire completă returnează doar valorile care au o corespondență în tabelul de destinație. Rândurile fără potrivire sunt eliminate din noul cadru de date. O potrivire parțială, în schimb, păstrează acele rânduri și umple coloanele lipsă cu NA.
Vom vedea un simplu îmbinare interioară. Cuvântul cheie de unire interioară selectează înregistrările care au valori care se potrivesc în ambele tabele. Pentru a uni două seturi de date, putem folosi funcția merge(). Vom folosi trei argumente:
merge(x, y, by.x = x, by.y = y) Arguments: -x: The origin data frame -y: The data frame to merge -by.x: The column used for merging in x data frame. Column x to merge on -by.y: The column used for merging in y data frame. Column y to merge on
Exemplu:
Creați primul set de date cu variabile
- nume de familie
- naționalitate
Creați al doilea set de date cu variabile
- nume de familie
- filme
Variabila cheie comună este numele de familie. Le putem combina pe amândouă cadre de date și verificați dacă dimensionalitatea este 7×3.
Adăugăm stringsAsFactors=FALSE în cadrul de date deoarece nu dorim R pentru a converti șirurile de caractere într-o factor; variabila ar trebui să rămână un vector de caractere. Începând cu R 4.0.0, aceasta este deja valoarea implicită pentru data.frame(), deci argumentul este opțional în codul nou și inofensiv în codul vechi.
# Create origin dataframe( producers <- data.frame( surname = c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"), nationality = c("US","US","UK","US","Poland"), stringsAsFactors=FALSE) # Create destination dataframe movies <- data.frame( surname = c("Spielberg", "Scorsese", "Hitchcock", "Hitchcock", "Spielberg", "Tarantino", "Polanski"), title = c("Super 8", "Taxi Driver", "Psycho", "North by Northwest", "Catch Me If You Can", "Reservoir Dogs","Chinatown"), stringsAsFactors=FALSE) # Merge two datasets m1 <- merge(producers, movies, by.x = "surname") m1 dim(m1)
ieșire:
surname nationality title 1 Hitchcock UK Psycho 2 Hitchcock UK North by Northwest 3 Polanski Poland Chinatown 4 Scorsese US Taxi Driver 5 Spielberg US Super 8 6 Spielberg US Catch Me If You Can 7 Tarantino US Reservoir Dogs
Să îmbinăm cadrele de date când variabilele cheie comune au nume diferite.
Schimbăm numele de familie cu numele în cadrul de date al filmelor. Folosim funcția identical(x1, x2) pentru a verifica dacă ambele cadre de date sunt identice.
# Change name of ` movies ` dataframe colnames(movies)[colnames(movies) == 'surname'] <- 'name' # Merge with different key value m2 <- merge(producers, movies, by.x = "surname", by.y = "name") # Print head of the data head(m2)
ieșire:
##surname nationality title ## 1 Hitchcock UK Psycho ## 2 Hitchcock UK North by Northwest ## 3 Polanski Poland Chinatown ## 4 Scorsese US Taxi Driver ## 5 Spielberg US Super 8 ## 6 Spielberg US Catch Me If You Can
# Check if data are identical
identical(m1, m2)
ieșire:
## [1] TRUE
Aceasta arată că operația de îmbinare este efectuată chiar dacă numele coloanelor sunt diferite.
Potrivire parțială
Join-ul intern de mai sus a eliminat discret orice element fără o contrapartidă. Nu este surprinzător faptul că două cadre de date nu au aceleași variabile cheie comune. În potrivire completă, cadrul de date revine rânduri găsite în cadrul de date x și y. Cu contopirea parțială, este posibil să păstrați rândurile fără rânduri care se potrivesc în celălalt cadru de date. Aceste rânduri vor avea NA în acele coloane care sunt de obicei umplute cu valori de la y. Putem face asta setând all.x= TRUE.
De exemplu, putem adăuga un nou producător, Lucas, în cadrul de date al producătorului fără referințele la film din cadrul de date al filmelor. Dacă setăm all.x= FALSE, R va uni doar valorile corespondente din ambele seturi de date. În cazul nostru, producătorul Lucas nu va fi unit în rezultat, deoarece lipsește dintr-un set de date.
Să vedem dimensiunea fiecărei ieșiri atunci când specificăm all.x= TRUE și când nu.
# Create a new producer add_producer <- c('Lucas', 'US') # Append it to the ` producer` dataframe producers <- rbind(producers, add_producer) # Use a partial merge m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE) m3
ieșire:
Ieșirea consolei de mai jos arată rândul Lucas suplimentar, cu NA înlocuind titlul filmului lipsă.
# Compare the dimension of each data frame
dim(m1)
ieșire:
## [1] 7 3
dim(m2)
ieșire:
## [1] 7 3
dim(m3)
ieșire:
## [1] 8 3
După cum putem vedea, noul cadru de date este de 8×3, comparativ cu 7×3 pentru m1 și m2. R umple coloana de titlu cu NA pentru Lucas, producătorul care nu are un rând corespondent în cadrul de date al filmului.
merge() vs dplyr Join-uri în R
R de bază rezolvă fiecare joncțiune cu o singură funcție și un set de steaguri. dplyr În schimb, pachetul oferă fiecărei alături propriul verb, pe care multe echipe îl consideră mai ușor de citit într-o rețea de procesare.
| Criterii | Îmbinare de bază() | dplyr join-uri |
|---|---|---|
| Alegerea îmbinării | all.x / all.y / toate steagurile | Numit în verb: left_join(), full_join() |
| Ordinea rândurilor | Sortat după cheie, cu excepția cazului în care sort = FALSE | Ordinea tabelului din stânga este păstrată |
| Viteză pe cadre mari | Mai lent | În general mai rapid |
| Coloană cheie lipsă | Eșuează târziu sau îmbină pe coloanele greșite | Erori imediate |
| dependenţe | Baza R, nimic de instalat | Necesită pachetul dplyr |
Cele două îmbinări prezentate mai sus se traduc direct în verbe dplyr:
library(dplyr) # Same inner join as merge(producers, movies, by.x = "surname", by.y = "name") m4 <- inner_join(producers, movies, by = c("surname" = "name")) # Same partial merge as all.x = TRUE m5 <- left_join(producers, movies, by = c("surname" = "name"))
Funcția merge() de bază este alegerea mai sigură în cadrul unui pachet care nu ar trebui să conțină dependențe. dplyr este alegerea mai bună într-o analiză interactivă, unde lizibilitatea și viteza contează mai mult.
Erori frecvente de îmbinare în R și cum să le remediați
Majoritatea problemelor de îmbinare se anunță mai degrabă ca un număr neașteptat de rânduri decât ca un mesaj de eroare, așa că verificarea funcției dim() după fiecare îmbinare este un obicei care merită dezvoltat.
- Rezultatul are mai multe rânduri decât oricare dintre intrări. O cheie care se repetă în ambele cadre produce o joncțiune many-to-many, iar R returnează fiecare combinație. Verificați cheile cu table(duplicated(x$k)) înainte de îmbinare.
- Rezultatul este gol. Coloanele cheie diferă de obicei ca tip sau una conține spații la final. Rulați str() pe ambele cadre și curățați cheia cu trimws() înainte de îmbinare.
- Coloanele revin ca title.x și title.y. Ambele cadre au o coloană non-cheie cu același nume. Transmiteți sufixele = c(„_producer”, „_film”) pentru a face originea evidentă.
- Rândurile nu mai sunt în ordinea lor inițială. merge() sortează implicit după cheie. Adăugați sort = FALSE sau utilizați o sortare explicită după aceea.
- O comparație cheie eșuează din punct de vedere al factorilor. Comparați caracterele, nu nivelurile factorilor: încadrați cheia în as.character() înainte de a îmbina cadrele create cu setările implicite R mai vechi.
Când aceeași îmbinare trebuie executată în mod repetat, încadrați-o într-un funcţie definită de utilizator deci argumentele nu pot devia de la o rundă la alta.

