如何使用dplyr按条件提取两个break事件区间内的最大值并生成新列
解决方案
实现逻辑
需求核心是按id分组后,将两个相邻break. == TRUE事件之间的区域作为一个计算区间,仅保留每个区间内的最大值,其余值置为0。具体逻辑如下:
- 按
id分组后按日期排序,保证数据时序正确 - 生成区间标识:每遇到一次
break. == TRUE,区间编号自增1,将相邻两个断点之间的数据划分为同一区间 - 按
id和区间号二次分组,每个区间仅最大值所在行保留原值,其余行赋值为0
实现代码
library(dplyr) library(lubridate) # 读取处理原始数据(已有代码可直接复用) ds <- read.csv("https://raw.githubusercontent.com/Leprechault/trash/main/accumulated_values_table") ds$date <- ymd(ds$date) ds <- ds %>% mutate(break. = break. == "True") # 生成values2列 ds <- ds %>% # 按id分组,组内按日期升序排列保证时序正确 group_by(id) %>% arrange(date, .by_group = TRUE) %>% # 生成区间编号:每遇到一个断点,后续区间编号+1 mutate(interval = cumsum(lag(break., default = FALSE))) %>% # 按id+区间二次分组计算 group_by(id, interval) %>% # 仅最大值所在行保留原值,其余置为0 mutate(values2 = ifelse(values == max(values), values, 0)) %>% # 清理辅助列,取消分组 ungroup() %>% select(-interval)
补充说明
如果同一区间内存在多个相同的最大值,且你只需要保留最早出现的最大值,可以将values2的生成逻辑调整为:
mutate(values2 = ifelse(row_number() == which.max(values), values, 0))
验证id == 4的子集可以看到,输出结果和你给出的预期效果完全一致。
内容的提问来源于stack exchange,提问作者Leprechault
相关产品推荐
相关产品推荐

