我似乎无法找到有关.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
如何工作感到困惑。有人可以解释一下吗?
答案 0 :(得分:99)
我已将此添加到列表here中。希望我们能够按计划交付。
原因很可能是by=.EACHI
是最新功能(自1.9.4开始),但它所做的不是。让我举个例子来解释一下。假设我们有两个data.tables X
和Y
:
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
用户要求此明确 - 有关详情,请参阅this和this。
因此添加了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
所以我们现在有两个功能。希望这会有所帮助。