data.table中的.EACHI?

Ale*_*lex 63 performance group-by r data.table

我似乎无法找到关于究竟.EACHI做什么的任何文档data.table.我在文档中看到它的简要提及:

在i和设置中传递这些组时,已知组子集的聚合特别有效by=.EACHI.何时i是data.table,DT[i,j,by=.EACHI]评估连接中每一行j的组.我们称之为每个i的分组.DTi

但是,"群体"在上下文中DT是什么意思?是否由设置的密钥确定的组DT?该组是否每个使用所有列作为键的不同行?我完全理解如何运行类似DT[i,j,by=my_grouping_variable]但是如何.EACHI工作的困惑.有人可以解释一下吗?

Aru*_*run 106

我已将此添加到此处的列表中.希望我们能够按计划交付.


原因很可能by=.EACHI是最近的一个特征(从1.9.4开始),但它的作用并非如此.让我举个例子来解释一下.假设我们有两个data.tables XY:

X = data.table(x = c(1,1,1,2,2,5,6), y = 1:7, key = "x")
Y = data.table(x = c(2,6), z = letters[2:1], key = "x")
Run Code Online (Sandbox Code Playgroud)

我们知道我们可以通过这样做来加入X[Y].这类似于子集操作,但使用data.tables(而不是整数/行名称或逻辑值).对于每一行Y,取其Y键列,它在X's键列(+列中Y)中查找并返回相应的匹配行.

X[Y]
#    x y z
# 1: 2 4 b
# 2: 2 5 b
# 3: 6 7 a
Run Code Online (Sandbox Code Playgroud)

现在让我们说,对于每一行Y的关键列(这里只有一个关键列),我们想得到匹配的数量X.在版本data.table <1.9.4,我们可以简单的通过指定做到这一点.Nj,如下所示:

# < 1.9.4
X[Y, .N]
#    x N
# 1: 2 2
# 2: 6 1
Run Code Online (Sandbox Code Playgroud)

隐含地做的是,在存在的情况下j,评估j-expression每个匹配的结果X(对应于行Y).这被称为by-without-byimplicit-by,因为它好像有一个隐藏的.

问题是这将始终执行by操作.因此,如果我们想知道连接后的行数,那么我们必须这样做:( X[Y][ .N]或者仅仅是nrow(X[Y])在这种情况下).也就是说,j如果我们不想要一个,我们就不能在同一个调用中使用表达式by-without-by.结果,当我们做了例如X[Y, list(z)],它list(z)使用评估by-without-by,因此稍慢.

此外data.table用户要求这是明确的 -看到这个这个更多的内容.

因此by=.EACHI被添加了.现在,当我们这样做时:

X[Y, .N]
# [1] 3
Run Code Online (Sandbox Code Playgroud)

它做了它的意图(避免混淆).它返回连接产生的行数.

和,

X[Y, .N, by=.EACHI]
Run Code Online (Sandbox Code Playgroud)

计算j每行的匹配行的表达式Y(对应于Y此处的键列的值).通过使用更容易看到这一点which=TRUE.

X[.(2), which=TRUE] # [1] 4 5
X[.(6), which=TRUE] # [1] 7
Run Code Online (Sandbox Code Playgroud)

如果我们.N为每个人奔跑,那么我们应该得到2,1.

X[Y, .N, by=.EACHI]
#    x N
# 1: 2 2
# 2: 6 1
Run Code Online (Sandbox Code Playgroud)

所以我们现在有两个功能.希望这可以帮助.

  • 谢谢.在下一个版本(1.9.6)中链接到这个Q可能是一个好主意,直​​到晕影出来.会做. (3认同)