如何从DataFrame提取满足连续24小时阈值条件的起止日期
逐小时水强度数据的连续高值时段提取方案
需求
针对某站点数月的逐小时水强度采集数据,需自动完成以下操作:
- 定位首次出现水强度>900且连续24小时保持≥900的起始时间;
- 找到该连续高值时段结束后,水强度首次低于900的终止时间;
- 对后续所有符合条件的连续24小时以上高值/低值循环,重复上述逻辑,替代人工处理。
示例数据
先用以下代码生成测试数据框:
library(lubridate) ## 创建示例数据框 NoOfHours <- as.numeric(ymd_hms("2010-01-06 01:00:00") - ymd_hms("2010-01-01 07:00:00"))*24 dt <- ymd_hms("2010-01-01 00:00:00") + hours(0:NoOfHours) intensity <- c(rep(c(0),23),rep(c(901,904),12), rep(c(660,540),10), rep(c(905,3000),10), 550, rep(c(1000,1200),13),340) df <- data.frame(dt, intensity)
实现代码
使用dplyr和lubridate包实现自动提取逻辑:
library(dplyr) # 标记高值状态(强度≥900) df <- df %>% mutate(is_high = intensity >= 900) # 对连续的高/低值时段分组 df <- df %>% mutate(group = cumsum(c(1, diff(is_high) != 0))) # 计算每个时段的关键信息:起始/结束时间、持续时长 period_summary <- df %>% group_by(group, is_high) %>% summarise( start_dt = first(dt), end_dt = last(dt), duration = as.numeric(end_dt - start_dt, units = "hours") + 1 # 包含首尾小时,计算总时长 ) %>% ungroup() # 筛选出符合条件的连续高值时段(时长≥24小时) valid_high_periods <- period_summary %>% filter(is_high, duration >= 24) # 生成最终结果:匹配每个高值时段的start和对应的stop时间 output <- data.frame(dt1 = character(), status = character()) for (idx in seq(nrow(valid_high_periods))) { current_group <- valid_high_periods$group[idx] # 添加start记录 output <- rbind(output, data.frame( dt1 = as.character(valid_high_periods$start_dt[idx]), status = "start" )) # 找到当前高值时段之后的第一个低值时段的起始时间作为stop next_low <- period_summary %>% filter(group > current_group, !is_high) %>% slice_head(n=1) if (nrow(next_low) > 0) { output <- rbind(output, data.frame( dt1 = as.character(next_low$start_dt), status = "stop" )) } } print(output)
预期输出
运行代码后将得到如下结果:
dt1 status 1 2010-01-01 23:00:00 start 2 2010-01-02 23:00:00 stop 3 2010-01-04 16:00:00 start 4 2010-01-05 18:00:00 stop
内容的提问来源于stack exchange,提问作者Amanda Goldberg
相关产品推荐
相关产品推荐

