此问题在此处已有答案:
Subset data frame based on number of rows per group(4个答案)
三年前关闭了。
我有以下数据.表:
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))
某些期间(按年和季度定义)有三个项目:
- Y1Q1、Y1Q4、Y2Q1
其他时期则不会:
- Y1Q2有2个项目
- Y1Q3有1项
我如何才能只得到包含所有三个项目的行?
目前为止我所做的
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
它按year
和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
?
3条答案
按热度按时间mkh04yzy1#
如果我们需要子集,使用
.I
来获取行索引和子集或者使用
.SD
,但可能会很慢或者另一个选项是
if/else
lskq00tm2#
使用join的另一个选项:
edit:为了解决akrun注解,速度确实取决于数据集的特征。以下是示例数据集的计时:
计时:
wh6knrhe3#
当然,这是一个
data.table
问题,@akrun的答案涵盖了它,但为了完成;dplyr
解决方案:在
Base
中:或