最佳答案
这是一个关于 data.table 连接语法的哲学问题。我发现 data.tables 的用途越来越多,但仍在学习..。
Table 的联接格式 X[Y]
非常简洁、方便和高效,但据我所知,它只支持内部联接和右外部联接。为了获得左连接或完全外连接,我需要使用 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 = NA
1参数进行连接呢?
下面是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=
语法,该语法允许在主键以外的字段上进行即席连接。Jangorecki 的回答向问题 如何连接(合并)数据帧(内部,外部,左,右) ?提供了一些 data.table 可以处理的其他联接类型的示例。