我有以下内容:
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
我希望这可以按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
似乎by
仅适用于j
而不适用于i
。这里有什么建议吗?
答案 0 :(得分:4)
正确或错误地,i
先运行j
然后by
在i
的所有行上test[,list(id, u=length(unique(id))), by=t][u>1]
运行。
一个常见的习语是这样的(类似于SQL中的HAVING):
u
并从结果中排除test[,list(id, u=length(unique(id))), by=t][u>1][,u:=NULL]
(每个组中唯一ID的数量):
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
:
TRUE
然后单个DT[TRUE] == DT
被回收。 i
。您始终可以j
进行{{1}}测试{。}}。