Unisci frame di dati in R: corrispondenza completa e parziale

โšก Riepilogo intelligente

In R, l'unione di data frame consente di combinare due tabelle in base a una o piรน colonne chiave condivise. La funzione merge() supporta le unioni interne, a sinistra, a destra e complete, e questa guida illustra sia una corrispondenza completa che una corrispondenza parziale.

  • ๐Ÿ”‘ Colonne chiave: merge() unisce in base a by, oppure in base a by.x e by.y quando la chiave ha un nome diverso in ogni frame.
  • ๐Ÿ”— Partita completa: L'inner join predefinito mantiene solo le righe la cui chiave compare in entrambi i dataframe.
  • ๐Ÿงฉ Corrispondenza parziale: Impostando all.x = TRUE, vengono mantenute tutte le righe del primo frame e gli spazi vuoti vengono riempiti con NA.
  • ๐Ÿ“ Controllo delle dimensioni: Confronta la dimensione (dim) prima e dopo un'unione per individuare le righe perse o duplicate dall'operazione di join.
  • โš™๏ธ Partecipa al controllo: I flag all, all.x e all.y selezionano il comportamento interno, sinistro, destro o completamente esterno.
  • ๏ธ Alternativa moderna: dplyr assegna un nome a ciascuna unione nel verbo stesso e preserva l'ordine originale delle righe.

Unisci frame di dati in R

Molto spesso disponiamo di dati provenienti da piรน fonti. Per eseguire un'analisi, dobbiamo unire due dataframe insieme ad uno o piรน variabili chiave comuni.

Tipi di unione (unione) in R

Prima di passare agli esempi, รจ utile sapere che merge() esegue ogni tipo di join che un utente SQL si aspetta. Il comportamento รจ controllato dagli argomenti all, all.x e all.y, anzichรฉ da un nome di funzione diverso.

Tipo di unione file mantenute chiamata merge() equivalente di dplyr
Unione interna (predefinita) Sono presenti solo le chiavi in โ€‹โ€‹entrambi i frame unisci(x, y, per = โ€œkโ€) inner_join(x, y, by = โ€œkโ€)
Giunto esterno sinistro Tutte le righe di x, NA dove y non ha corrispondenza merge(x, y, by = โ€œkโ€, all.x = TRUE) left_join(x, y, by = โ€œkโ€)
Giunto esterno destro Tutte le righe di y, NA dove x non ha corrispondenza merge(x, y, by = โ€œkโ€, all.y = TRUE) right_join(x, y, by = โ€œkโ€)
Unione esterna completa Ogni riga da entrambi i frame unisci(x, y, per = โ€œkโ€, tutti = VERO) full_join(x, y, by = โ€œkโ€)
Unione incrociata Ogni combinazione di righe unisci(x, y, per = NULL) cross_join(x, y)

Prima della prima chiamata, รจ bene tenere a mente due dettagli:

  • Omettendo "by", R esegue l'unione in base a ogni nome di colonna condiviso dai due frame, il che raramente รจ ciรฒ che si desidera.
  • La funzione merge() ordina il risultato in base alla colonna chiave; passare sort = FALSE per mantenere l'ordine originale.

Partita intera

Una corrispondenza completa restituisce solo i valori che hanno un corrispettivo nella tabella di destinazione. Le righe senza corrispondenza vengono eliminate dal nuovo dataframe. Una corrispondenza parziale, al contrario, mantiene tali righe e riempie le colonne mancanti con NA.

Ne vedremo una semplice join interno. La parola chiave inner join seleziona i record che presentano valori corrispondenti in entrambe le tabelle. Per unire due set di dati, possiamo usare la funzione merge(). Utilizzeremo tre argomenti:

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

Esempio:

Crea il primo set di dati con variabili

  • cognome
  • nazionalitร 

Crea un secondo set di dati con variabili

  • cognome
  • film

La variabile chiave comune รจ il cognome. Possiamo unire entrambi frame di dati e verificare che la dimensionalitร  sia 7ร—3.

Aggiungiamo stringsAsFactors=FALSE nel data frame perchรฉ non vogliamo R per convertire le stringhe in un fattore; la variabile deve rimanere un vettore di caratteri. Dalla versione 4.0.0 di R, questo รจ giร  il comportamento predefinito per data.frame(), quindi l'argomento รจ opzionale nel codice nuovo e innocuo nel codice vecchio.

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

Produzione:

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

Uniamo i frame di dati quando le variabili chiave comuni hanno nomi diversi.

Cambiamo il cognome in nome nel frame dati del film. Usiamo la funzione identico(x1, x2) per verificare se entrambi i frame di dati sono identici.

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

Produzione:

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

Produzione:

## [1] TRUE

Ciรฒ dimostra che l'operazione di unione viene eseguita anche se i nomi delle colonne sono diversi.

Corrispondenza parziale

L'inner join sopra ha eliminato silenziosamente tutto ciรฒ che non aveva una controparte. Non sorprende che due dataframe non abbiano le stesse variabili chiave comuni. Nel corrispondenza completa, il dataframe restituisce esclusivamente righe trovate in entrambi i frame di dati x e y. Con fusione parziale, รจ possibile mantenere le righe senza righe corrispondenti nell'altro frame di dati. Queste righe avranno NA in quelle colonne che solitamente sono riempite con valori da y. Possiamo farlo impostando all.x= TRUE.

Ad esempio, possiamo aggiungere un nuovo produttore, Lucas, al dataframe dei produttori senza i riferimenti ai film nel dataframe dei film. Se impostiamo all.x = FALSE, R unirร  solo i valori corrispondenti in entrambi i dataset. Nel nostro caso, il produttore Lucas non verrร  unito al risultato, perchรฉ manca in uno dei dataset.

Vediamo la dimensione di ciascun output quando specifichiamo all.x= TRUE e quando non lo facciamo.

# 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

Produzione:

L'output della console qui sotto mostra la riga aggiuntiva di Lucas, dove NA sta per il titolo del film mancante.

Output della console della fusione parziale che mostra Lucas con NA nella colonna del titolo

# Compare the dimension of each data frame
dim(m1)

Produzione:

## [1] 7 3
dim(m2)

Produzione:

## [1] 7 3
dim(m3)

Produzione:

## [1] 8 3

Come possiamo vedere, il nuovo dataframe รจ 8ร—3, rispetto a 7ร—3 per m1 e m2. R riempie la colonna del titolo con NA per Lucas, il produttore che non ha una riga corrispondente nel dataframe dei film.

merge() vs dplyr Join in R

Base R risolve ogni join con una funzione e un insieme di flag. dplyr Il pacchetto, invece, assegna a ogni join un proprio verbo, che molti team trovano piรน facile da leggere all'interno di una pipeline.

Criteri Unione di base() dplyr si unisce
Scegliendo l'unione tutte le x / tutte le y / tutte le bandiere Denominati nel verbo: left_join(), full_join()
Ordine delle righe Ordinato in base alla chiave a meno che sort = FALSE L'ordine della tabella di sinistra viene mantenuto
Velocitร  su telai di grandi dimensioni Piรน lentamente Generalmente piรน veloce
Colonna chiave mancante Fallisce in ritardo o si unisce sulle colonne sbagliate Errori immediatamente
dipendenze Base R, niente da installare Richiede il pacchetto dplyr

Le due fusioni mostrate sopra si traducono direttamente in verbi 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"))

`base merge()` รจ la scelta piรน sicura all'interno di un pacchetto che non dovrebbe avere dipendenze. `dplyr` รจ la scelta migliore in un'analisi interattiva, dove leggibilitร  e velocitร  sono piรน importanti.

Errori comuni di unione in R e come risolverli

La maggior parte dei problemi di unione si manifesta con un numero di righe inatteso piuttosto che con un messaggio di errore, quindi controllare la funzione dim() dopo ogni join รจ un'abitudine che vale la pena acquisire.

  • Il risultato ha piรน righe di entrambi gli input. Una chiave che si ripete in entrambi i frame produce un join molti-a-molti e R restituisce tutte le combinazioni. Ispeziona le chiavi con table(duplicated(x$k)) prima di unire.
  • Il risultato รจ vuoto. Le colonne chiave di solito differiscono per tipo, oppure una contiene spazi finali. Esegui str() su entrambi i frame e pulisci la chiave con trimws() prima dell'unione.
  • Le colonne vengono restituite come title.x e title.y. Entrambi i frame contengono una colonna non chiave con lo stesso nome. Passa suffissi = c("_producer", "_film") per rendere evidente l'origine.
  • Le file non sono piรน nell'ordine originale. merge() ordina in base alla chiave per impostazione predefinita. Aggiungi sort = FALSE oppure usa un tipo esplicito successivamente.
  • Un confronto chiave fallisce per diversi motivi. Confronta i caratteri, non i livelli dei fattori: racchiudi la chiave in as.character() prima di unire i frame creati con le impostazioni predefinite di R precedenti.

Quando la stessa unione deve essere eseguita ripetutamente, racchiudila in un funzione definita dall'utente quindi gli argomenti non possono variare tra un'esecuzione e l'altra.

DOMANDE FREQUENTI

R esegue l'unione in base al nome di ogni colonna condivisa dai due frame. Con una sola colonna condivisa, questo รจ comodo; con diverse colonne, restringe silenziosamente il risultato, e senza colonne condivise restituisce un cross join. Specificare esplicitamente la chiave evita tutte e tre queste situazioni inaspettate.

Non in una singola chiamata merge(). Concatena le chiamate oppure riduci una lista con Reduce(function(x, y) merge(x, y, by = โ€œkโ€), list(df1, df2, df3)). Verifica il conteggio delle righe dopo ogni passaggio, perchรฉ le chiavi duplicate si accumulano rapidamente.

Entrambi i frame contenevano una colonna non chiave con lo stesso nome, quindi R li disambigua. Passa suffixes = c("_producer", "_film") per assegnare nomi significativi alle copie, oppure elimina la colonna ridondante prima dell'unione.

No. merge() ordina il risultato sulla colonna chiave per impostazione predefinita. Passa sort = FALSE per mantenere l'ordine in ingresso oppure usa un dplyr unisci, che preserva l'ordine del riquadro di sinistra.

Fornisci un vettore: merge(x, y, by = c("cognome", "anno")). Se i nomi sono diversi, passa i vettori corrispondenti a by.x e by.y. Entrambi i vettori devono elencare le colonne nello stesso ordine.

Utilizzare by = โ€œrow.namesโ€, oppure la forma abbreviata by = 0. R aggiunge nuovamente i nomi delle righe come colonna chiamata Row.names, che in genere si desidera rinominare o eliminare prima di continuare l'analisi.

Descrivi i due frame e il numero di righe, e un assistente AI indicherร  le chiavi duplicate come probabile causa e suggerirร  un controllo `duplicated()`. Conferma la diagnosi con i tuoi dati prima di modificare l'unione.

Sรฌ. Le serrature scorrevoli portatili e i catenacci a superficie possono essere usati per mettere in sicurezza una porta a scomparsa dall'esterno. Alcuni kit con catena di sicurezza consentono anche il bloccaggio esterno con chiave o manopola girevole. RStudio Desktop 2023.09.0 e versioni successive includono un'opzione di adesione Copilota GitHub Integrazione che crea una bozza di unione a partire da un commento. Verifica il tipo di join scelto, poichรฉ un flag errato modifica silenziosamente il conteggio delle righe.

Riassumi questo post con: