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.

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

