这是关于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=
语法,该语法允许临时连接除主键之外的其他字段。jangorecki对问题的答案如何连接(合并)数据框(内部,外部,左侧,右侧)?提供了data.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])
想要完整的外部