我已将此添加到此列表中,希望我们能按计划交付。
原因很可能是by=.EACHI
是最近的功能(自1.9.4以来),但它的作用并不是最近才有的。让我用一个示例解释一下。假设我们有两个数据表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
中的列)中找到相应的匹配行并返回。
X[Y]
现在假设我们想要针对Y
的关键列(这里只有一列关键列)中的每一行,获取X
中匹配项的计数。在data.table
版本< 1.9.4中,我们可以通过在j
中简单地指定.N
来实现:
X[Y, .N]
隐式地,在有j
的情况下,对于每个与X
中匹配的结果(对应于Y
中的行),评估j-expression
。这被称为by-without-by或implicit-by,因为它就像有一个隐藏的by
一样。
问题在于这将始终执行by
操作。所以,如果我们想知道连接后的行数,那么我们必须执行:X[Y][.N]
(或在这种情况下简单地执行nrow(X[Y])
)。也就是说,如果我们不想要一个by-without-by
,则不能在同一个调用中使用j
表达式。因此,当我们执行例如X[Y,list(z)]
时,它使用by-without-by
计算list(z)
,因此速度略慢。
另外,data.table
用户要求将其变得明确 - 有关更多上下文,请参见此处和此处。
因此,添加了by=.EACHI
。现在,当我们执行:
X[Y, .N]
它做它应该做的事情(避免混淆)。它返回连接后结果行的数量。
还有,
X[Y, .N, by=.EACHI]
对于Y
中的每一行(对应于这里Y
的键列的值),在匹配的行上评估j
表达式。使用which=TRUE
更容易看到这一点。
X[.(2), which=TRUE]
X[.(6), which=TRUE]
如果我们对每一个运行.N
,那么我们应该会得到2,1。
X[Y, .N, by=.EACHI]
现在我们已经拥有了这两个功能。
.EACHI
的内容。 - Alex.EACHI
的定义,它基于i
和DT
之间的合并方式来定义分组。也就是说,如果i
使用一个键进行合并,那么该键将为DT
定义分组。换句话说,i
中的每一行都代表一个分组(以及DT
返回的行)。如果软件包所有者能够确认这一点,那就太好了。在这种情况下,是否比指定by=
条件更快呢? - Alex