如何在R中按spread_event分组计算连续5小时以上干燥时段
解决方法:按分组检测连续5小时干燥时段
核心思路
要实现需求,我们需要:
- 标记每行的干燥状态(
leaf_wetness_duration == 0) - 识别连续的干燥/非干燥时段
- 计算每个干燥时段的持续行数(对应时长)
- 判断每个
spread_event分组内是否存在连续20行及以上的干燥时段(20×15分钟=5小时),并将结果应用到分组内所有行
代码实现(dplyr原生方案)
适用于dplyr 1.1.0及以上版本(自带consecutive_id函数):
library(dplyr) # 先确保数据按时间排序(关键!连续时段判断依赖行顺序) df <- df %>% arrange(spread_event, date) %>% group_by(spread_event) %>% # 标记当前行是否为干燥状态 mutate(dry_flag = leaf_wetness_duration == 0, # 给连续相同状态的行分配唯一时段ID segment_id = consecutive_id(dry_flag)) %>% # 计算每个时段的行数 group_by(spread_event, segment_id, .add = TRUE) %>% mutate(segment_length = n()) %>% # 回到spread_event分组,判断是否存在达标干燥时段 group_by(spread_event) %>% mutate(dry_period = any(dry_flag & segment_length >= 20)) %>% # 清理辅助列(可选) select(-dry_flag, -segment_id, -segment_length) %>% ungroup()
兼容旧版dplyr的方案(使用data.table)
如果你的dplyr版本低于1.1.0,可以用data.table的rleid函数实现时段标记:
library(dplyr) library(data.table) df <- df %>% arrange(spread_event, date) %>% group_by(spread_event) %>% mutate(dry_flag = leaf_wetness_duration == 0, segment_id = rleid(dry_flag)) %>% group_by(spread_event, segment_id, .add = TRUE) %>% mutate(segment_length = n()) %>% group_by(spread_event) %>% mutate(dry_period = any(dry_flag & segment_length >= 20)) %>% select(-dry_flag, -segment_id, -segment_length) %>% ungroup()
关键细节说明
- 行顺序必须正确:一定要先按
spread_event和date排序,否则连续时段的判断会出错 - 缺失行处理:如果数据存在时间间隔缺失(比如某15分钟的记录没了),需要先补全时间序列,否则连续干燥时段的计算会被中断
- 结果逻辑:只要该
spread_event内存在任意一段连续5小时的干燥,整个分组的dry_period都会设为TRUE,否则为FALSE
示例数据验证
你提供的示例数据中,连续干燥段只有12行(对应3小时),所以处理后该分组的dry_period会是FALSE,符合预期。
内容的提问来源于stack exchange,提问作者Ahsk
相关产品推荐
相关产品推荐

