Î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ă.

  • 🔑 Coloane cheie: merge() face o unire pe by sau pe by.x și by.y atunci când cheia poartă un nume diferit în fiecare cadru.
  • 🔗 Meci complet: Join-ul intern implicit păstrează doar rândurile a căror cheie apare în ambele cadre de date.
  • 🧩 Potrivire parțială: Setarea all.x = TRUE păstrează fiecare rând al primului cadru și umple golurile cu NA.
  • 📐 Verificare dimensiuni: Comparați dim() înainte și după o îmbinare pentru a detecta rândurile pierdute sau duplicate de îmbinare.
  • ⚙️ Control al alăturării: Indicatoarele all, all.x și all.y selectează comportamentul intern, stâng, drept sau complet extern.
  • 🛠️ Alternativă modernă: dplyr denumește fiecare joncțiune din verb și păstrează ordinea originală a rândurilor.

Îmbinați cadre de date în R

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ă.

Rezultatul consolei pentru îmbinarea parțială afișează Lucas cu NA în coloana de titlu

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

Întrebări frecvente

R fuzionează fiecare nume de coloană pe care cele două cadre îl au în comun. Cu o coloană partajată, acest lucru este convenabil; cu mai multe, restrânge în mod silențios rezultatul, iar cu niciuna nu returnează o joncțiune încrucișată. Denumirea cheii evită explicit toate cele trei surprize.

Nu într-un singur apel merge(). Înlănțuiți apelurile sau pliați o listă cu Reduce(function(x, y) merge(x, y, by = “k”), list(df1, df2, df3)). Verificați numărul de rânduri după fiecare pas, deoarece cheile duplicate se compun rapid.

Ambele cadre conțineau o coloană non-cheie cu același nume, așa că R le dezambiguizează. Transmiteți sufixele = c(„_producer”, „_film”) pentru a da copiilor nume semnificative sau eliminați coloana redundantă înainte de îmbinare.

Nu. merge() sortează rezultatul în coloana cheie în mod implicit. Transmiteți sort = FALSE pentru a păstra ordinea de intrare sau utilizați un dplyr join, care păstrează ordinea cadrului din stânga.

Furnizați un vector: merge(x, y, by = c(„nume de familie”, „an”)). Când numele diferă, transmiteți vectorii potriviți către by.x și by.y. Ambii vectori trebuie să listeze coloanele în aceeași ordine.

Folosește by = „row.names” sau prescurtarea by = 0. R adaugă numele rândurilor înapoi ca o coloană numită Row.names, pe care de obicei vrei să o redenumești sau să o elimini înainte de a continua analiza.

Descrieți cele două cadre și numărul de rânduri, iar un asistent de inteligență artificială va indica cheile duplicate ca fiind cauza probabilă și va sugera o verificare duplicated(). Confirmați diagnosticul cu propriile date înainte de a modifica joncțiunea.

Da. RStudio Versiunea Desktop 2023.09.0 și versiunile ulterioare includ o opțiune de înscriere Copilotul GitHub integrare care schițează o îmbinare dintr-un comentariu. Verifică tipul de îmbinare pe care îl alege, deoarece un semnalizator greșit modifică numărul de rânduri în mod silențios.

Rezumați această postare cu: