在R中使用data.table进行滚动连接

47

我想更好地了解滚动连接的工作方式,但有些困惑,希望有人能为我澄清。以下是一个具体的示例:

dt1 <- data.table(id=rep(1:5, 10), t=1:50, val1=1:50, key="id,t")
dt2 <- data.table(id=rep(1:5, 2), t=1:10, val2=1:10, key="id,t")

我期望这个操作可以生成一个很长的 data.table,其中 dt2 中的值会被滚动处理:
dt1[dt2,roll=TRUE]

相反,正确的做法似乎是:

dt2[dt1,roll=TRUE]

有人能够更详细地解释一下如何在data.table中进行连接吗?我显然没有正确理解。我以为dt1[dt2,roll=TRUE]对应于sql中的select * from dt1 right join dt2 on (dt1.id = dt2.id and dt1.t = dt2.t),除了增加了locf功能。

此外,文档还说:

X[Y] is a join, looking up X's rows using Y (or Y's key if it has one) 
as an index.

这使得似乎只有 X 中的内容应该被返回,而所做的连接是内连接,而不是外连接。那么当 roll=T 但是在 dt1 中不存在特定的 id 的情况下怎么办?再试验一下,我无法理解将什么值放入该列中。

14
我已经写了一篇博客文章,描述了滚动连接的工作原理。您可以在这里阅读:http://gormanalysis.com/r-data-table-rolling-joins/ - Ben
1个回答

29

这篇文档中的引用似乎来自FAQ 1.12 X[Y]和merge(X,Y)之间有什么区别。您在?data.table中是否找到了以下内容,并且它有所帮助?

  

roll应用于最后一个联接列,通常是日期,但可以是任何有序变量、不规则的并包括间隙的变量。如果roll=TRUE,并且i的行与所有但最后一个x联接列匹配,且其在最后一个i联接列中的值落在间隙中(包括该组x中的最后一个观察值之后),则x中的优势值向前滚动。该操作使用修改过的二进制搜索特别快。该操作也称为术语最后观察结果向前(LOCF)。通常,x的键中不应该有重复项,最后一个键列是日期(或时间,或日期时间),并且所有x的键列都已连接。一个常见的惯用法是在一组标识符(ids)中选择同时发生的常规时间序列(dts):DT[CJ(ids,dts),roll=TRUE],其中DT具有2列键(id,date),CJ表示交叉连接。

  

rolltolast类似于roll,但是数据不会在由联接列定义的每个组中最后一个观察之后向前滚动。i的值必须落在x中的间隙中,但不能超过数据的末尾,该组由除最后一个联接列以外的所有联接列定义。roll和rolltolast不能同时为TRUE。

关于SQL联接的左/右类比,我更喜欢在FAQ 2.14 你能否进一步解释一下为什么data.table受到基本A[B]语法的启发的背景下考虑这个问题。那是一个相当长的答案,所以我不会在这里粘贴它。


我没有看到那个,谢谢你的发布。让我困惑的是 x[y] 返回 y 中存在但 x 中不存在的行?这似乎不像等值连接... 特别是 x[y] 和 merge(x, y, all.y=TRUE) 看起来是一样的,不是吗? - Alex
1
哦,我明白你的意思了。nomatch默认为NA,因此默认情况下是外连接。将'nomatch'设置为0以进行内连接。术语等值连接旨在传达“=”出现在(类似的)where子句中,而不是roll,它类似于“<=”。Equi join不类似于_inner_ join。 - Matt Dowle
你是否看到并遵循了?data.table顶部的提示,运行example(data.table)并在提示符下逐个演示示例? - Matt Dowle
4
"rolltolast" 在 v1.9.6 版本中被 "rollends" 替换。自2013年3月3日 CRAN 发布的 v1.8.8 版本中,'rolltolast' 已被标记为 'deprecated',请使用更灵活的 'rollends'。'rolltolast' 将在下一个版本中被删除。 - swihart
2
@swihart +1 谢谢。你有没有直接编辑答案的机会,这样会更快一些。 - Matt Dowle
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接