Это немного философский вопрос о синтаксисе соединения data.table. Я нахожу все больше и больше использования для data.tables, но все еще учась...
Формат соединения X[Y]
для data.tables очень краткий, удобный и эффективный, но, насколько я могу судить, он поддерживает только внутренние соединения и внешние внешние соединения. Чтобы получить левое или полное внешнее соединение, мне нужно использовать merge
:
-
X[Y, nomatch = NA]
- все строки в Y - правое внешнее соединение (по умолчанию) -
X[Y, nomatch = 0]
- только строки с совпадениями в X и Y - внутреннее соединение -
merge(X, Y, all = TRUE)
- все строки из X и Y - полное внешнее соединение -
merge(X, Y, all.x = TRUE)
- все строки в X-левом внешнем соединении
Мне кажется, что было бы удобно, если формат объединения X[Y]
поддерживал все 4 типа объединений. Есть ли причина, по которой поддерживаются только два типа соединений?
Для меня значения параметров nomatch = 0
и nomatch = NA
не очень интуитивно понятны для выполняемых действий. Мне легче понять и запомнить синтаксис merge
: all = TRUE
, all.x = TRUE
и all.y = TRUE
. Поскольку операция X[Y]
напоминает merge
намного больше, чем match
, почему бы не использовать синтаксис merge
для объединений, а не параметр match
nomatch
параметр <
Вот примеры кода из 4 типов соединений:
# 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
Обновление: data.table v1.9.6 представил синтаксис on=
, который позволяет ad hoc присоединяться к полям, отличным от первичного ключа. jangorecki answer на вопрос Как объединить (объединить) кадры данных (внутренний, внешний, левый, правый)? содержит некоторые примеры дополнительных типов соединений, которые может обрабатывать data.table.