R语言统计逐小时时序满足双阈值持续要求的事件数
R语言实现逐小时温度时序跨阈值事件统计
需求定义
- 输入:逐小时采集的温度时序向量
- 通用统计规则:指定双阈值
level1(下阈值)、level2(上阈值),统计序列中独立的跨阈值事件总数量,单个事件要求过程中同时出现过温度低于level1、高于level2两类状态,且两类状态的持续时长均满足最小要求 - 本次测试固定参数:下阈值=10,上阈值=20,单状态最小持续时长=1小时,两组测试数据预期输出均为2
测试数据集
第一组测试向量a
a<-c(7.95, 7.8, 7.85, 7.6, 7.1, 5.55, 4.35, 4.1, 7.35, 10.7, 14.2, 17.25, 19.1, 19.8, 20.1, 20.15, 19.9, 18.95, 16.7, 14.4, 13.75, 12.1, 12.3, 11.4, 10.3, 8.55, 7.45, 7.05, 5.6, 5.95, 4.85, 5.3, 9.35, 12.7, 16.15, 19.1, 20.5, 21.05, 21.4, 21.4, 21.35, 20.1, 16.95, 15.8, 15.6, 14.95, 14.15, 13.85)

该组数据预期统计结果:2
第二组测试向量b
b<-c(20.2, 20.55, 20.85, 21.7, 20.7, 18.7, 17.5, 17.4, 16.65, 17.15, 15.8, 13.85, 12.55, 11.45, 10.2, 9.3, 8.2, 7.4, 7.25, 6.65, 5.9, 4.75, 4.5, 4.15, 4.4, 6.25, 8.1, 10.35, 12.4, 14.3, 15.3, 16.3, 17.25, 17.25, 16.85, 14.45, 12.85, 11.35, 10.2, 9.1, 8.6, 7.35, 5.9, 4.85, 3.65, 3.3, 2.95, 2.65, 2.45, 4.85, 6.45, 8.25, 9.95, 11.1, 12.3, 13.2, 13.95, 14.05, 13.15, 10.35, 8.15, 6.6, 6.3, 6, 7.55, 5.85, 5.05, 4.75, 4.5, 4.75, 4.75, 4.55, 5.15, 8.45, 12.05, 16.35, 18.9, 20.55, 21.6, 21.45, 21.75, 21.15, 20.05, 17.75, 16.5, 18.2, 18.05, 17.95, 17.8, 17.55, 17.25, 16.95, 16.6, 16.35, 16.1, 16.25, 16.4, 17.1, 17.8)

该组数据预期统计结果:2
实现代码
核心逻辑分三步:
- 给每个时间点打状态标签:低于下阈值标记为
low,高于上阈值标记为high,中间区间标记为mid - 识别连续同状态段,过滤掉持续时长不满足要求的段、以及中间状态段
- 按时间顺序遍历有效状态段,当一个连续周期内同时出现过
high和low状态,记为1个有效事件,计数后重置状态标记避免重复统计
注:代码依赖
dplyr包,首次运行前执行install.packages("dplyr")安装,运行前需加载包:library(dplyr)
count_threshold_events <- function(temp_vec, low_thresh = 10, high_thresh = 20, min_duration = 1) { # 打点位状态标签 state <- dplyr::case_when( temp_vec < low_thresh ~ "low", temp_vec > high_thresh ~ "high", TRUE ~ "mid" ) # 切分连续状态段 seg_id <- cumsum(c(1, diff(as.integer(factor(state))) != 0)) segments <- data.frame( seg_id = seg_id, state = state, duration = 1 ) |> dplyr::group_by(seg_id, state) |> dplyr::summarise(duration = n(), .groups = "drop") |> # 过滤无效段:中间状态、持续时长不足 dplyr::filter(state != "mid", duration >= min_duration) # 遍历统计有效事件 event_count <- 0 has_high <- FALSE has_low <- FALSE for (s in segments$state) { if (s == "high") has_high <- TRUE if (s == "low") has_low <- TRUE # 周期内同时出现高低状态,计数+1并重置标记 if (has_high && has_low) { event_count <- event_count + 1 has_high <- FALSE has_low <- FALSE } } return(event_count) }
结果验证
直接传入测试向量运行即可得到结果:
# 测试第一组数据 count_threshold_events(a) # 输出:[1] 2 # 测试第二组数据 count_threshold_events(b) # 输出:[1] 2
输出和预期结果完全一致。如果需要调整阈值、最小持续时长,直接修改函数入参即可;如果需要统计特定n小时窗口内的事件数,只需将对应时间窗口的时序切片传入函数。
内容的提问来源于stack exchange,提问作者Garn_R
相关产品推荐
相关产品推荐

