首页 > 解决方案 > 仅获取具有给定行数的 data.table 组

问题描述

我有以下数据表:

dt = data.table(year=c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2),
                quar=c(1, 1, 1, 2, 2, 3, 4, 4, 4, 1, 1, 1),
                item=c(1, 2, 3, 1, 2, 1, 1, 2, 3, 1, 2, 3))

某些时期(按年份和季度定义)包含三个项目:

其他时期不:

我怎样才能只获得包含所有三个项目的行?

到目前为止我所管理的是

dt[dt[, "i" := nrow(.SD) == 3, .(year, quar)]$i]
> year | quar | item | i
> -----+------+------+-----
> 1    | 1    | 1    | TRUE
> 1    | 1    | 2    | TRUE
> 1    | 1    | 3    | TRUE
> 1    | 4    | 1    | TRUE
> 1    | 4    | 2    | TRUE
> 1    | 4    | 3    | TRUE
> 2    | 1    | 1    | TRUE
> 2    | 1    | 2    | TRUE
> 2    | 1    | 3    | TRUE

which group byyear然后quar设置一列i,说明该组是否有效。组中的所有行都得到 的计算值i

哪个工作得很好。i但是,它具有向表中添加真实列的副作用。

我尝试使用用 声明的临时列.(i =...),但是该i列具有较短的分组表的长度,我们得到

dt[dt[, .(i = nrow(.SD) == 3), .(year, quar)]$i]
> Error in `[.data.table`(dt, dt[, .(i = nrow(.SD) == 3), .(year, quar)]$i) :
> i evaluates to a logical vector length 5 but there are 12 rows. [...]

那么,有没有更优雅的方法来解决这个问题?还是我应该只使用它然后丢弃i

标签: rdata.table

解决方案


如果我们需要子集,使用.I来获取行索引和子集

dt[dt[, .I[.N == 3], .(year, quar)]$V1]
#    year quar item
#1:    1    1    1
#2:    1    1    2
#3:    1    1    3
#4:    1    4    1
#5:    1    4    2
#6:    1    4    3
#7:    2    1    1
#8:    2    1    2
#9:    2    1    3

或与.SD,但可能会很慢

dt[, .SD[.N == 3], .(year, quar)]

或者另一种选择是if/else

dt[, if(.N == 3) .SD, .(year, quar)]

推荐阅读