data.table中的.EACHI?

时间:2014-11-18 21:03:38

标签: r performance group-by data.table

我似乎无法找到有关.EACHI data.table的确切内容的任何文档。我在文档中看到它的简要提及:

  

已知组子集的聚合特别有效   在i中传递这些组并设置by=.EACHI时。当i是   data.table,DT[i,j,by=.EACHI]j的{​​{1}}组评估DT   i中的每一行都加入。我们将每个i称为分组。

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

1 个答案:

答案 0 :(得分:99)

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


原因很可能是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")

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

X[Y]
#    x y z
# 1: 2 4 b
# 2: 2 5 b
# 3: 6 7 a

现在让我们说,对于来自Y的关键列(此处只有一个关键列)的每一行,我们希望获得匹配的计数X。在data.table 的版本中&lt; 1.9.4 ,我们只需在.N中指定j,即可完成此操作:

# < 1.9.4
X[Y, .N]
#    x N
# 1: 2 2
# 2: 6 1

这个隐式所做的是,在j出现的情况下,评估j-expression的每个匹配结果的X(对应Y中的行{1}})。这被称为 by-without-by implicit-by ,因为它就好像有一个隐藏的。

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

此外,data.table用户要求此明确 - 有关详情,请参阅thisthis

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

X[Y, .N]
# [1] 3

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

X[Y, .N, by=.EACHI]

评估j - Y中每一行的匹配行的表达式(对应于Y的关键列的值)。使用which=TRUE可以更容易地看到这一点。

X[.(2), which=TRUE] # [1] 4 5
X[.(6), which=TRUE] # [1] 7

如果我们为每个人运行.N,那么我们应该得到2,1。

X[Y, .N, by=.EACHI]
#    x N
# 1: 2 2
# 2: 6 1

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