Questa è una domanda un po 'filosofica sulla sintassi del join di data.table. Sto trovando sempre più usi per data.tables, ma sto ancora imparando ...
Il formato di join X[Y]
per data.tables è molto conciso, pratico ed efficiente, ma per quanto ne so, supporta solo inner join e right outer join. Per ottenere un join esterno sinistro o completo, devo usare merge
:
X[Y, nomatch = NA]
- tutte le righe in Y - join esterno destro (predefinito)X[Y, nomatch = 0]
- solo righe con corrispondenze sia in X che in Y - join internomerge(X, Y, all = TRUE)
- tutte le righe da X e Y - join esterno completomerge(X, Y, all.x = TRUE)
- tutte le righe in X - join esterno sinistro
Mi sembra che sarebbe utile se il X[Y]
formato di join supportasse tutti e 4 i tipi di join. C'è un motivo per cui sono supportati solo due tipi di join?
Per me, i valori dei parametri nomatch = 0
e nomatch = NA
non sono molto intuitivi per le azioni eseguite. E 'più facile per me capire e ricordo la merge
sintassi: all = TRUE
, all.x = TRUE
e all.y = TRUE
. Poiché l' X[Y]
operazione assomiglia merge
molto di più a match
, perché non utilizzare la merge
sintassi per i join anziché il parametro match
della funzione nomatch
?
Di seguito sono riportati esempi di codice dei 4 tipi di join:
# sample X and Y data.tables
library(data.table)
X <- data.table(t = 1:4, a = (1:4)^2)
setkey(X, t)
X
# t a
# 1: 1 1
# 2: 2 4
# 3: 3 9
# 4: 4 16
Y <- data.table(t = 3:6, b = (3:6)^2)
setkey(Y, t)
Y
# t b
# 1: 3 9
# 2: 4 16
# 3: 5 25
# 4: 6 36
# all rows from Y - right outer join
X[Y] # default
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
X[Y, nomatch = NA] # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
merge(X, Y, by = "t", all.y = TRUE) # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
identical(X[Y], merge(X, Y, by = "t", all.y = TRUE))
# [1] TRUE
# only rows in both X and Y - inner join
X[Y, nomatch = 0]
# t a b
# 1: 3 9 9
# 2: 4 16 16
merge(X, Y, by = "t") # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
merge(X, Y, by = "t", all = FALSE) # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
identical( X[Y, nomatch = 0], merge(X, Y, by = "t", all = FALSE) )
# [1] TRUE
# all rows from X - left outer join
merge(X, Y, by = "t", all.x = TRUE)
# t a b
# 1: 1 1 NA
# 2: 2 4 NA
# 3: 3 9 9
# 4: 4 16 16
# all rows from both X and Y - full outer join
merge(X, Y, by = "t", all = TRUE)
# t a b
# 1: 1 1 NA
# 2: 2 4 NA
# 3: 3 9 9
# 4: 4 16 16
# 5: 5 NA 25
# 6: 6 NA 36
Aggiornamento: data.table v1.9.6 ha introdotto la on=
sintassi, che consente join ad hoc su campi diversi dalla chiave primaria. La risposta di jangorecki alla domanda Come unire (unire) frame di dati (interno, esterno, sinistro, destro)? fornisce alcuni esempi di tipi di join aggiuntivi che data.table può gestire.
unique()
approccio di seguito per il join completo sia preferibile a rbind(Y[X],X[Y])
, poiché rbind comporterebbe la copia della tabella. È giusto?
unique(c(unique(X[,t]), unique(Y[,t]))
, dovrebbe essere più efficiente in termini di memoria poiché combina solo due elenchi che saranno inferiori o uguali al numero di righe in X e Y .
Y[X]
se vuoi il join esterno sinistro diX[Y]
erbind(Y[X],X[Y])
se vuoi un join esterno completo