【问题标题】:i argument in data.table (expression that evaluates to logical)data.table 中的 i 参数(计算结果为逻辑的表达式)
【发布时间】:2012-08-20 15:53:25
【问题描述】:

我有以下几点:

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 分组 test,评估每个组上的 j 语句,并返回 i 为 true 的行(即有超过 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。这里有什么建议吗?

【问题讨论】:

    标签: r group-by subset data.table


    【解决方案1】:

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

    一个常见的习语是这样的(类似于 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&gt;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。您始终可以像这样设置j 来测试i

    【讨论】:

      猜你喜欢
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 2018-11-20
      • 2019-06-29
      相关资源
      最近更新 更多