Esta es una pregunta un poco filosófica sobre la sintaxis de unión de data.table. Estoy encontrando cada vez más usos para data.tables, pero sigo aprendiendo ...
El formato X[Y]
de combinación para data.tables es muy conciso, práctico y eficiente, pero hasta donde yo sé, solo admite combinaciones internas y combinaciones externas derechas. Para obtener una combinación externa izquierda o completa, necesito usar merge
:
X[Y, nomatch = NA]
- todas las filas en Y - unión externa derecha (predeterminado)X[Y, nomatch = 0]
- solo filas con coincidencias tanto en X como en Y - unión internamerge(X, Y, all = TRUE)
- todas las filas de X e Y - unión externa completamerge(X, Y, all.x = TRUE)
- todas las filas en X - unión exterior izquierda
Me parece que sería útil si el X[Y]
formato de combinación admitiera los 4 tipos de combinaciones. ¿Hay alguna razón por la que solo se admiten dos tipos de combinaciones?
Para mí, los valores de los parámetros nomatch = 0
y nomatch = NA
no son muy intuitivos para las acciones que se realizan. Es más fácil para mí entender y recordar la merge
sintaxis: all = TRUE
, all.x = TRUE
y all.y = TRUE
. Dado que la X[Y]
operación se parece merge
mucho más a match
, ¿por qué no usar la merge
sintaxis para las combinaciones en lugar match
del nomatch
parámetro de la función ?
Aquí hay ejemplos de código de los 4 tipos de combinación:
# 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
Actualización: data.table v1.9.6 introdujo la on=
sintaxis, que permite combinaciones ad hoc en campos distintos a la clave principal. La respuesta de jangorecki a la pregunta ¿Cómo unir (fusionar) marcos de datos (interno, externo, izquierdo, derecho)? proporciona algunos ejemplos de tipos de combinación adicionales que puede manejar data.table.
unique()
enfoque a continuación para la combinación completa es preferible rbind(Y[X],X[Y])
, ya que el rbind implicaría copiar la tabla. ¿Está bien?
unique(c(unique(X[,t]), unique(Y[,t]))
, esto debería ser más eficiente en memoria, ya que solo combina dos listas que serán menores o iguales que la cantidad de filas en X e Y .
Y[X]
si desea la combinación externa izquierda deX[Y]
yrbind(Y[X],X[Y])
si desea una combinación externa completa