如何用R的dplyr按降雨持续时长区间统计年降雨事件数?
解决连续降雨事件按区间统计的R实现方案
我来帮你搞定这个统计需求!你的核心目标是把每年中降雨量>1mm的连续降雨事件,按指定的四个时长区间汇总计数,最终得到「年份+四个区间计数」的宽格式数据框对吧?咱们用dplyr+tidyr就能完美实现,步骤清晰,我给你一步步拆解:
第一步:准备数据与标记降雨日
首先,先把分散的Year/Month/Day字段合并成完整日期(这一步是为了更准确判断连续性,避免跨月/跨年的天数计算误差),同时标记出降雨量>1mm的降雨日:
library(dplyr) library(tidyr) # 假设你的原始数据框叫做 rain_data processed_data <- rain_data %>% # 合并日期字段,确保日期格式正确 mutate(date = as.Date(paste(Year, Month, Day, sep = "-")), # 标记降雨日:1=降雨(>1mm),0=无降雨 rain_flag = ifelse(Rainfall > 1, 1, 0))
第二步:识别连续降雨事件并计算时长
接下来,给每一段连续的降雨事件分配唯一ID,然后计算每个事件的连续天数:
event_data <- processed_data %>% # 按年份分组,确保跨年度的降雨事件不会被误判为连续 group_by(Year) %>% # 生成连续降雨事件的ID:当rain_flag从0变1时,事件ID自动+1 mutate(event_id = cumsum(rain_flag != lag(rain_flag, default = 0))) %>% # 只保留有降雨的日期数据 filter(rain_flag == 1) %>% # 按年份和事件ID分组,计算每个降雨事件的连续天数 group_by(Year, event_id) %>% summarise(duration = n(), .groups = "drop")
第三步:将时长映射到指定区间
现在把每个事件的时长,对应到你指定的四个区间里:
binned_data <- event_data %>% mutate(duration_bin = case_when( duration >= 1 & duration <= 3 ~ "1-3天", duration >= 4 & duration <= 7 ~ "4-7天", duration >= 8 & duration <= 14 ~ "8-14天", duration > 14 ~ "14天以上", # 兜底处理(理论上不会触发,因为只保留了降雨日) TRUE ~ "其他" ))
第四步:按年份+区间汇总并转为宽格式
最后一步就是统计每年每个区间的事件数量,并转成你需要的宽格式,同时给没有事件的区间补0:
final_result <- binned_data %>% # 按年份和区间分组,统计事件数量 count(Year, duration_bin, name = "count") %>% # 补全所有年份的所有区间,确保无事件的区间显示0 complete(Year, duration_bin = c("1-3天", "4-7天", "8-14天", "14天以上"), fill = list(count = 0)) %>% # 转为宽格式:每个区间作为单独一列 pivot_wider(names_from = duration_bin, values_from = count) %>% # 按年份排序,让结果更规整 arrange(Year)
关键细节说明
- 用
group_by(Year)能彻底避免跨年度的降雨事件被错误合并; cumsum(rain_flag != lag(rain_flag))是识别连续事件的核心技巧,自动捕捉降雨的起止节点;complete()函数用来补全缺失的区间,不会因为某年份没有对应区间的事件就出现空值;- 最终的
final_result就是你想要的结构:每一行对应一个年份,四列分别是四个区间的事件计数。
如果你的原始数据已经严格按日期排序,合并日期这一步也可以简化,但建议保留,避免数据乱序导致的连续事件判断错误。
内容的提问来源于stack exchange,提问作者Lyndz
相关产品推荐
相关产品推荐

