Це трохи філософське питання про синтаксис приєднання 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
?
Ось приклади коду чотирьох типів приєднання:
# 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 на питання Як з'єднати (об'єднати) кадри даних (внутрішні, зовнішні, ліві, праві)? наведено кілька прикладів додаткових типів з'єднання, з якими може працювати обробка даних.table.
unique()
підхід нижче для повного приєднання є кращим rbind(Y[X],X[Y])
, оскільки rbind передбачає копіювання таблиці. Це так?
unique(c(unique(X[,t]), unique(Y[,t]))
це має бути більш ефективною пам'яттю, оскільки це лише комбінування двох списків, що будуть меншими або рівними кількості рядків у X та Y .
Y[X]
якщо ви хочете, щоб ліве зовнішнє з'єднання зX[Y]
іrbind(Y[X],X[Y])
якщо ви хочете повне зовнішнє з'єднання