为了账号安全,请及时绑定邮箱和手机立即绑定

为什么data.tables的X [Y]联接不允许完全外部联接或左联接?

为什么data.tables的X [Y]联接不允许完全外部联接或左联接?

守着星空守着你 2019-12-06 11:06:05
这是关于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.tableslibrary(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 16Y <- 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 joinX[Y]  # default#  t  a  b# 1: 3  9  9# 2: 4 16 16# 3: 5 NA 25# 4: 6 NA 36X[Y, nomatch = NA]  # same as above#    t  a  b# 1: 3  9  9# 2: 4 16 16# 3: 5 NA 25# 4: 6 NA 36merge(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 36identical(X[Y], merge(X, Y, by = "t", all.y = TRUE))# [1] TRUE# only rows in both X and Y - inner joinX[Y, nomatch = 0]  #    t  a  b# 1: 3  9  9# 2: 4 16 16merge(X, Y, by = "t")  # same as above#    t  a  b# 1: 3  9  9# 2: 4 16 16merge(X, Y, by = "t", all = FALSE)  # same as above#    t  a  b# 1: 3  9  9# 2: 4 16 16identical( X[Y, nomatch = 0], merge(X, Y, by = "t", all = FALSE) )# [1] TRUE# all rows from X - left outer joinmerge(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 joinmerge(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可以处理的其他联接类型的一些示例。
查看完整描述

3 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

引用data.table FAQ 1.11 X[Y]和之间有什么区别merge(X, Y)?


X[Y] 是联接,使用Y(或Y的键,如果有的话)作为索引查找X的行。


Y[X] 是一个联接,使用X(或X的键,如果有的话)查找Y的行


merge(X,Y)同时执行两种方式。X[Y]和的行数Y[X]通常不同,而merge(X,Y)和返回的行数merge(Y,X)相同。


但是错过了要点。大多数任务需要在连接或合并后对数据执行某些操作。为什么合并所有数据列,然后只使用它们的一小部分?您可能会建议  merge(X[,ColsNeeded1],Y[,ColsNeeded2]),但这要求程序员确定需要哪些列。X[Y,jdata.table中的]为您完成所有这些工作。在编写时X[Y,sum(foo*bar)],data.table会自动检查j表达式以查看其使用的列。它只会将这些列作为子集;其他被忽略。仅为j使用的列创建内存,并且Y列在每个组的上下文中均享受标准的R回收规则。假设fooin中X,bar在中Y(以及中的20个其他列Y)。是不是X[Y,sum(foo*bar)] 比合并所有浪费的子集更快地编写程序和更快地运行?


如果您想要左外连接 X[Y]


le <- Y[X]

mallx <- merge(X, Y, all.x = T)

# the column order is different so change to be the same as `merge`

setcolorder(le, names(mallx))

identical(le, mallx)

# [1] TRUE

如果要完全外部联接


# the unique values for the keys over both data sets

unique_keys <- unique(c(X[,t], Y[,t]))

Y[X[J(unique_keys)]]

##   t  b  a

## 1: 1 NA  1

## 2: 2 NA  4

## 3: 3  9  9

## 4: 4 16 16

## 5: 5 25 NA

## 6: 6 36 NA


# The following will give the same with the column order X,Y

X[Y[J(unique_keys)]]



查看完整回答
反对 回复 2019-12-07
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

作为MNEL说,左/右外连接是通过交换获得Y和X:Y[X]航班吗X[Y]。因此,该语法支持4种连接类型中的3种,而不是2种iiuc。


添加第四似乎是个好主意。假设我们添加full=TRUE或both=TRUE或merge=TRUE(不确定最佳的参数名称?),那么X[Y,j,merge=TRUE]在FAQ 1.12中BUT之后的原因对我来说是没有用的。现在已添加了新功能请求,并已链接回这里,谢谢:


FR#2301:像merge()一样,为X [Y]和Y [X]联接添加merge = TRUE参数。


最近的版本已经加快了速度merge.data.table(例如,通过在内部进行浅表复制来更有效地设置密钥)。因此,我们正试图把merge()和X[Y]密切,并提供给用户的所有选项充分的灵活性。两者都有优点和缺点。另一个出色的功能要求是:


FR#2033:将by.x和by.y添加到merge.data.table


如果还有其他人,请让他们继续前来。


通过问题的这一部分:


为什么不对联接使用合并语法,而不是对match函数的nomatch参数使用?


如果你喜欢merge()的语法和它的3个参数all,all.x并且all.y然后就用这个来代替X[Y]。认为它应该涵盖所有情况。还是您的意思是为什么论点是单一nomatch的[.data.table?如果是这样的话,这对于FAQ 2.14来说似乎就是自然的方式:“您能进一步解释一下为什么data.table受到base中A [B]语法的启发吗?”。而且,nomatch当前0和仅接受两个值NA。可以扩展该值,例如,负值表示某种含义,或者12表示使用第12行的值来填充NA,或者nomatch将来可能是向量,甚至可能是本身data.table。


嗯 怎么会通过,而无需按与合并交互= TRUE?也许我们应该把它交给datatable-help。



查看完整回答
反对 回复 2019-12-07
  • 3 回答
  • 0 关注
  • 419 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信