Due tabelle, una chiave
I dati reali raramente stanno in una sola tabella. I clienti stanno in un data frame, i loro ordini in un altro, e la domanda "quanto ha speso ogni cliente?" ha bisogno di entrambi. Ciò che li collega è una chiave: una colonna presente in ciascuna tabella che identifica la stessa entità. Combinare tabelle su una chiave si chiama join (il termine di SQL) o merge (il termine di R base); l'operazione è la stessa.
Ecco la coppia di tabelle usata nel resto della pagina. Nota che il cliente 5 ha fatto un ordine ma non è nella tabella dei clienti, e i clienti 2 e 4 non hanno mai ordinato:
Le mancate corrispondenze sono volute: ciò che un join fa con le righe senza corrispondenza è proprio ciò che distingue i tipi di join.
merge(): inner join di default
merge(x, y, by = "key") abbina le righe con chiavi uguali e ne unisce le colonne. Di default mantiene solo le chiavi presenti in entrambe le tabelle: un inner join.
Tornano tre righe. Ana compare due volte: ha due ordini, e un join produce una riga di output per ogni coppia che corrisponde. Ben e Dana sono spariti (nessun ordine), e così anche l'ordine misterioso del cliente 5 (nessun cliente). Un inner join scarta in silenzio le righe senza corrispondenza di entrambe le tabelle: esattamente ciò che serve quando ti interessano solo le coppie complete, e un bug silenzioso di perdita di dati quando non è così.
Left, right e full join: all.x, all.y, all
Per mantenere le righe senza corrispondenza, di' quale tabella ha righe intoccabili. all.x = TRUE mantiene ogni riga della prima tabella: è il left join, il join più usato nella pratica.
Ora Ben e Dana sopravvivono, con NA in amount, cioè "questo cliente esiste, ma nessun ordine corrisponde". Quegli NA sono informativi, non spazzatura: is.na(result$amount) è esattamente l'elenco dei clienti che non hanno mai ordinato (la guida ai valori mancanti spiega come lavorarci). Le altre varianti sono la stessa idea puntata altrove: all.y = TRUE mantiene ogni riga della seconda tabella (right join: l'ordine del cliente sconosciuto 5 sopravvivrebbe con NA in name), e all = TRUE mantiene tutto da entrambi i lati (full join).
Scegli chiedendoti: di chi sono le righe che non posso permettermi di perdere? Arricchire una tabella principale con dati di consultazione: left join, con la tabella principale per prima. Verificare in entrambe le direzioni: full join.
Chiavi con nomi diversi: by.x e by.y
Le tabelle raramente si mettono d'accordo sui nomi: id in una, customer_id nell'altra. Non rinominare; indica a merge() entrambi i nomi:
L'output mantiene per la chiave il nome della prima tabella. Una cosa collegata: se le due tabelle condividono nomi di colonna non chiave (per esempio entrambe hanno una date), merge aggiunge i suffissi date.x e date.y; rinominale subito, si leggono malissimo.
I join di dplyr
dplyr dà a ogni tipo di join il suo verbo, così l'intenzione sta nel nome della funzione invece che negli argomenti flag (statico; la sandbox esegue solo R base):
library(dplyr)
left_join(customers, orders, by = "id")
inner_join(customers, orders, by = "id")
full_join(customers, orders, by = "id")
left_join(customers, orders, by = c("id" = "customer_id")) # different names
Oltre alla leggibilità, left_join() conserva l'ordine delle righe della prima tabella (merge() riordina per chiave) e avvisa in modo chiaro in caso di corrispondenze molti a molti; vedi l'introduzione a dplyr per la famiglia dei verbi.
Il membro sottovalutato è anti_join(): restituisce le righe della prima tabella che non hanno corrispondenza nella seconda, senza aggiungere colonne, solo gli avanzi:
anti_join(customers, orders, by = "id") # customers who never ordered
Quella domanda, "quali righe non hanno trovato corrispondenza?", salta fuori di continuo nella pulizia dei dati (ID senza corrispondenza, record orfani, ricerche fallite), e anti_join() risponde in una sola chiamata dove R base ha bisogno di customers[!(customers$id %in% orders$id), ].
Impilare righe: rbind()
Un join combina le colonne di due tabelle. Quando invece hai due lotti dello stesso tipo di righe, per esempio gli ordini di gennaio e quelli di febbraio, li impili con rbind():
Il requisito è rigido: entrambi i data frame devono avere gli stessi nomi di colonna (in qualsiasi ordine, perché rbind abbina per nome). Una colonna mancante o in più è un errore, non un riempimento con NA. Quando le colonne dei lotti sono cambiate nel tempo, bind_rows() di dplyr è più tollerante: allinea per nome e riempie i buchi con NA.
L'esplosione delle chiavi duplicate
Il classico incidente da join: chiavi che credevi uniche ma non lo sono, in entrambe le tabelle. Ogni corrispondenza si accoppia con ogni corrispondenza, moltiplicando le righe:
Due righe unite a due righe danno quattro righe: ogni x accoppiata con ogni y. Sui dati reali è così che una tabella da 10,000 righe diventa di 3 milioni di righe e un totale di ricavi raddoppia. merge() lo fa in silenzio. La difesa è un'abitudine: prima del join, controlla la chiave che presumi unica (anyDuplicated(customers$id) dovrebbe dare 0), e dopo il join verifica che nrow() corrisponda a quello che ti aspettavi.
Cosa ti porti a casa
merge(x, y, by = "key")è un inner join: le righe senza corrispondenza spariscono in silenzio.all.x = TRUE(left),all.y = TRUE(right),all = TRUE(full) mantengono le righe senza corrispondenza, riempiendole conNA.- Chiavi con nomi diversi:
by.x/by.yin R base,by = c("a" = "b")in dplyr. - dplyr dà un nome a ogni join;
anti_join(), cioè le righe che non hanno trovato corrispondenza, è quello sottovalutato. rbind()impila tabelle con la stessa forma; le colonne devono corrispondere per nome.- Le chiavi duplicate moltiplicano le righe in silenzio: controlla
anyDuplicated()prima,nrow()dopo.
Prossimo passo: trasformare i dati tra formato largo e lungo con pivot_longer() e pivot_wider().
Domande frequenti
Come si uniscono due data frame in R?
Usa merge(x, y, by = "key") con la colonna chiave in comune. Di default esegue un inner join: sopravvivono solo le righe la cui chiave compare in entrambi i data frame. Aggiungi all.x = TRUE per un left join, all.y = TRUE per un right join o all = TRUE per un full join.
Come si fa un left join in R?
In R base: merge(x, y, by = "key", all.x = TRUE) mantiene ogni riga di x e riempie le colonne di y con NA dove non c'è corrispondenza. In dplyr: left_join(x, y, by = "key"), stesso risultato, e in più conserva l'ordine originale delle righe di x, cosa che merge() non fa.
Come si uniscono data frame quando le colonne chiave hanno nomi diversi?
Indica a merge() entrambi i nomi: merge(x, y, by.x = "id", by.y = "customer_id"). In dplyr l'equivalente è left_join(x, y, by = c("id" = "customer_id")), oppure, con l'helper moderno, by = join_by(id == customer_id).
Qual è la differenza tra merge e rbind in R?
Combinano in dimensioni diverse. merge() abbina le righe di due tabelle tramite una chiave e ne combina le colonne: è un join. rbind() impila le righe di una tabella sotto quelle di un'altra, e le due devono avere gli stessi nomi di colonna. File mensili con colonne identiche vogliono rbind(); clienti più ordini vogliono merge().