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
。有什么建议吗?
对或错,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
。