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

我希望这能够分组testt评估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

似乎by适用于jonly 而不是i。这里有什么建议吗?

4

1 回答 1

5

对或错,i首先j运行,然后by在所有通过的行上运行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]

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

如果在整个数据集上j运行,然后在结果上运行(如您所料),那么它会导致效率问题。考虑一下它是否以这种方式工作。然后,首先需要对结果进行分组的过滤器需要分成两个调用:. 然后看不到(within ) 并且不知道它需要哪些列。将其组合为一个允许在评估之前进行检查,并且只对需要的列进行子集化。这对使用一小部分列的查询的大型数据集产生了很大的影响。byi[DT[i][,j,by]ij[.data.tableDT[i,j,by]ijj


要查看发生了什么,请带上你的i并制作它j

test[,length(unique(id))>1]  
# [1] TRUE

然后单曲TRUE被回收。DT[TRUE] == DT. 你总是可以这样进行i测试j

于 2012-08-20T16:38:37.710 回答