我在data.table中的参数(计算结果为逻辑的表达式)

Ale*_*lex 3 group-by r subset data.table

我有以下内容:

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
Run Code Online (Sandbox Code Playgroud)

我预计这组test通过t,评估j每个组语句,返回其中的行i是真实的(即有超过1个唯一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
Run Code Online (Sandbox Code Playgroud)

似乎by适用于j唯一而不是适用于i。有什么建议吗?

Mat*_*wle 5

对或错,i首先j运行,然后by在所有通过的行上运行i

常见的用法是这样的(类似于SQL中的HAVING):

test[,list(id, u=length(unique(id))), by=t][u>1]
Run Code Online (Sandbox Code Playgroud)

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

test[,list(id, u=length(unique(id))), by=t][u>1][,u:=NULL]
Run Code Online (Sandbox Code Playgroud)

顺便说一句,i对(小得多的)汇总结果(例如u>1上面的行)进行矢量扫描比对(大得多的)原始数据进行矢量扫描要高效得多。

如果对整个数据集依次j运行by,然后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
Run Code Online (Sandbox Code Playgroud)

然后单身TRUE被回收。DT[TRUE] == DT。您始终可以i通过这样进行测试j