如何在R语言中统计连续n天超出阈值x的事件次数
统计R语言中连续多天超出阈值的事件次数
要解决统计每年内连续至少N天(比如30天)数值超出特定阈值的事件次数问题,核心是先识别连续的超出区间,再统计符合长度要求的区间数量。以下是具体实现方案:
完整解决方案代码
library(tidyverse) library(lubridate) library(data.table) # 用rleid快速识别连续区间 # 生成示例数据(设随机种子保证结果可复现) set.seed(123) value = sample(0:25, 1461, replace=T) date = seq(as.Date("2018-01-01"), as.Date("2021-12-31"), by = "1 day") dat = data.frame(date = date, year = year(date), value = value) # 核心统计逻辑 result <- dat %>% # 1. 标记当天数值是否超出阈值 mutate(exceed = ifelse(value >= 10, 1, 0)) %>% # 2. 为连续的超出/未超出区间分配唯一分组ID mutate(group_id = rleid(exceed)) %>% # 3. 按年和分组ID聚合,计算每个连续段的天数 group_by(year, group_id, exceed) %>% summarize(days_in_group = n(), .groups = "drop") %>% # 4. 筛选出超出阈值且连续天数≥30的区间 filter(exceed == 1 & days_in_group >= 30) %>% # 5. 按年统计符合条件的事件数量 group_by(year) %>% summarize(n_exceedances_30_consec = n(), .groups = "drop") # 查看结果 result
代码分步解释
- 标记超出状态:新增
exceed列,用1/0标记当天数值是否≥10,为后续识别连续区间做准备。 - 识别连续区间:
data.table包的rleid()函数会为连续相同的exceed值分配唯一ID,每个连续的超出/未超出段都会有独立的分组ID。如果不想依赖data.table,可以用dplyr原生方法替代:mutate(group_id = cumsum(exceed != lag(exceed, default = 0))) - 计算连续段长度:按年份和分组ID聚合,统计每个连续段的天数。
- 筛选目标区间:只保留超出阈值且连续天数≥30的区间,排除短于30天的零散超出。
- 统计事件数:按年份统计符合条件的区间数量,连续40天这类长区间只会被计为1次事件,完全匹配需求。
示例输出(基于set.seed(123)的随机数据)
# A tibble: 4 x 2 year n_exceedances_30_consec <dbl> <int> 1 2018 0 2 2019 1 3 2020 0 4 2021 0
关键注意事项
- 如果原始数据存在日期缺失,需要先补全日期(比如用
complete(date = seq(min(date), max(date), by="day"))),否则会误判非连续的日期为连续区间。
内容的提问来源于stack exchange,提问作者CyanoSloughth
相关产品推荐
相关产品推荐

