dplyr::filter执行顺序控制:无需拆分语句的分组过滤实现方法
差异原因
dplyr的filter在同一条语句内执行时,所有判断条件的计算基准都是未经过当前filter过滤的原始数据集,不存在从左到右先筛一部分再计算后续条件的逻辑:
- 你写的单条语句
filter(fy <= 2017 & sum(val) >= 1)中,sum(val)是对整个分组的所有行的val值求和,b组全组val总和为0+0+1=1,满足>=1的条件,因此b组中fy<=2017的两行都会被保留,最终结果不符合预期。 - 拆分两条filter时,第一条先过滤掉所有fy>2017的行,第二条filter的
sum(val)是基于筛选后的分组内剩余行计算,b组剩余行的val总和为0,会被过滤,因此结果正确。
单条filter实现方案
不需要拆分多条filter,只需要在聚合计算时手动限定计算范围即可,代码如下:
dat %>% filter(fy <= 2017, sum(val[fy <= 2017]) >= 1)
上述代码中sum(val[fy <= 2017])会直接提取分组内所有fy<=2017的val值求和,不会用到2018年的数值,最终返回结果和两条filter的写法完全一致。
如果你的需求是保留符合条件的组的所有行(包含2018年的行),去掉fy <= 2017的行筛选条件即可:
# 保留a组所有3行数据 dat %>% filter(sum(val[fy <= 2017]) >= 1)
内容的提问来源于stack exchange,提问作者DJC
相关产品推荐
相关产品推荐

