data.table中的i参数(评估为逻辑表达式的表达式)

3

我有以下内容:

test <- data.table(id=1:11, t=c(rep(1:2,5), 3))
test[length(unique(id))>1,list(id, t), by=t]

    id t
 1:  1 1
 2:  2 2
 3:  3 1
 4:  4 2
 5:  5 1
 6:  6 2
 7:  7 1
 8:  8 2
 9:  9 1
10: 10 2
11: 11 3

我希望将这个查询按t分组,对每组运行j语句,并返回i为真(即有多个唯一的id)的行。但实际返回的结果是:

> test
     id t
 1:  1 1
 2:  2 2
 3:  3 1
 4:  4 2
 5:  5 1
 6:  6 2
 7:  7 1
 8:  8 2
 9:  9 1
10: 10 2  
11: 11 3

看起来by只适用于j,而不是i。有什么建议吗?

1个回答

5

无论对错,i先运行,然后j在所有通过 i 的行上依次运行。

常见的习语类似于以下内容(类似于SQL中的HAVING):

test[,list(id, u=length(unique(id))), by=t][u>1]

并且从结果中排除u(每个组内唯一ID的数量):

test[,list(id, u=length(unique(id))), by=t][u>1][,u:=NULL]

顺便提一下,在 (比如上面行中的 u>1) 聚合结果上在 i 中进行矢量扫描要比在(较大的)原始数据上进行矢量扫描更有效率。
如果在整个数据集上运行 j,然后在结果上运行 i(正如您所期望的那样),那么这会对效率造成问题。考虑如果它按这种方式工作。 那么首先进行过滤,然后在结果上进行分组需要被拆分为两个 [ 调用: DT[i][,j,by]。然后 i 不会看到 j (在 [.data.table 内),也不知道它需要哪些列。将其组合成一个 DT[i,j,by] 允许 i 在评估之前检查 j 并仅对 j 需要的列进行子集筛选。这对于在查询中使用少量列的大型数据集非常有用。
要了解发生了什么,请将您的 i 更改为 j
test[,length(unique(id))>1]  
# [1] TRUE

然后单个 TRUE 被回收了。 DT[TRUE] == DT。你总是可以通过像这样将它变成 j 来测试 i


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