当前位置: 首页 > 知识库问答 >
问题:

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

李光华
2023-03-14

这是一个关于data.table连接语法的哲学问题。我发现越来越多的数据.表的用途,但仍在学习...

data.tables的联接格式x[Y]非常简洁、方便和高效,但据我所知,它只支持内部联接和右外部联接。要获得左或完全的外部联接,我需要使用merge:

  • x[Y,nomatch=NA]--Y中的所有行--右外部联接(默认)
  • X[Y,nomatch=0]--仅限在X和Y中都匹配的行--内部联接
  • 合并(X,Y,all=TRUE)--来自X和Y的所有行--完全外部联接
  • 合并(X,Y,all.X=TRUE)--X中的所有行--左外部联接

在我看来,如果x[Y]联接格式支持所有4种类型的联接,这将是非常方便的。有没有原因只支持两种类型的连接?

对我来说,nomatch=0nomatch=na参数值对于正在执行的操作不是很直观。我更容易理解和记住merge语法:all=trueall.x=trueall.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.tableV1.9.6引入了on=语法,它允许在主键以外的字段上进行特别连接。Jangorecki对如何连接(合并)数据帧(内、外、左、右)的问题的回答?提供Data.Table可以处理的附加联接类型的一些示例。

共有1个答案

郭思淼
2023-03-14

引用data.table常见问题解答1.11X[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]),但这需要程序员确定需要哪些列。data.table中的x[Y,j]在一个步骤中完成了所有这些。当您编写x[Y,sum(foo*bar)]时,data.table会自动检查j表达式,以查看它使用了哪些列。它将只对这些列进行子集;其他的被忽略了。内存只为j使用的列创建,而y列在每个组的上下文中享有标准的R循环规则。假设foox中,而bar在y中(还有y中的其他20列)。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)]]
 类似资料:
  • LEFT OUTER JOIN 左外连接 [ ] 需求:查询所有分类,如果该分类下没有商品,则不显示该分类 [ ] 实现: SELECT `goods`.`id`, `goods`.`title`, `goods`.`price`, `goods`.`cate_id`, `cate`.`id`, `cate`, `cate.title` F

  • 内连接,显示两个表中有联系的所有数据; 左链接,以左表为参照,显示所有数据,右表中没有则以null显示 右链接,以右表为参照显示数据,,左表中没有则以null显示

  • 本文向大家介绍MySQL 的内连接、左连接、右连接有什么区别?相关面试题,主要包含被问及MySQL 的内连接、左连接、右连接有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 内连接关键字:inner join;左连接:left join;右连接:right join。 内连接是把匹配的关联数据显示出来;左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;右连接正好相反。

  • 我在AWS中有三个Kubernetes集群--这些集群都是由脚本构建的,所以应该是完全相同的。生成的K8配置允许Kubernetes仪表板连接和kubectl命令没有任何问题。 然而,对其中一个集群进行编程连接并不起作用,我也不知道为什么。 有什么方法可以获得更多关于为什么API不能连接的信息吗?谢谢

  • MariaDB 用于返回条件中指定的左侧表中的所有行,并仅返回满足连接条件的其他表中的行。 也被称为。 语法: 图形表示如下: 注: 上图中,两个图形的左侧表(table1)和右侧表(table2)中间交叉蓝色部分,以及左侧表(table1)就是连接返回的结果集。 为了方便演示,我们需要创建两个表,并插入一些数据 - 插入数据 - 当前表中的行记录如下 - 当前表中的行记录如下 - 示例1 使用以

  • 我有一个db2查询,今天我意识到需要扩展该查询。 我的表使用联接已经相当复杂了,所以我并不想添加联合查询。我想做一个完整的外部连接。 我想是因为另一个左联接。