如何用dplyr按PIT分组筛选data1生成data2:保留rx特定行
从data1生成符合规则的data2解决方案
原始数据与目标结果
data1 <- data.frame( PIT = c(20111002, 20111002, 20111002, 20111002, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111006, 20111006, 20111006, 20111006, 20111006), rx = c(39, 42, 101, 109, 39, 42, 101, 109, 138, 138, 138, 136, 138, 138, 139, 139, 39, 39, 39, 39, 42) ) # 目标结果(注:原data2中的2011102为输入笔误,实际应为20111002) data2 <- data.frame( PIT = c(20111002, 20111002, 20111003, 20111003, 20111006, 20111006), rx = c(39, 109, 39, 138, 39, 42) )
需求说明
按PIT字段分组,每组固定保留两行:
- 第一行:
rx字段第一个最小值对应的行 - 第二行:优先取
rx中第一个大于110的值对应的行;若组内无rx>110的记录,则取rx字段第一个最大值对应的行
解决方案代码
library(dplyr) result <- data1 %>% group_by(PIT) %>% slice( # 提取第一个最小值的行位置 which.min(rx), # 按规则提取第二行的位置:先找第一个>110的,没有则找第一个最大值 if (any(rx > 110)) which(rx > 110)[1] else which.max(rx) ) %>% ungroup() # 查看最终结果 result
结果验证
运行代码后输出与修正笔误后的data2完全一致:
# A tibble: 6 × 2 PIT rx <dbl> <dbl> 1 20111002 39 2 20111002 109 3 20111003 39 4 20111003 138 5 20111006 39 6 20111006 42
关键逻辑解释
group_by(PIT):按日期维度分组处理每组数据slice():通过行索引提取目标行,传入两个索引参数:which.min(rx):直接返回组内第一个rx最小值的位置- 条件判断:用
any(rx>110)检查组内是否存在符合阈值的记录,存在则取第一个匹配索引,否则取第一个最大值的索引
ungroup():取消分组,恢复为普通数据框结构
内容的提问来源于stack exchange,提问作者coreyeddy
相关产品推荐
相关产品推荐

