R语言使用pracma::findpeaks()如何提取超阈值的峰值正确区间
问题说明
pracma::findpeaks()默认返回的峰值起止点是峰值两侧的局部极小值位置,也就是你当前得到的0值点位。你之前传入的threshold = 1参数作用是要求峰值与相邻点的最小差值为1,并非设置「数值大于1才纳入峰值区间」的截断规则,且该函数没有内置参数支持自定义阈值截断区间,因此无法直接通过调参得到你需要的结果。
实现方案
你需要的规则本质是:所有连续出现暴露量>1的区段对应一个有效峰值,区段起点为第一个超1的时间点,终点为最后一个超1的时间点,峰值最高点为区段内暴露量最大值对应的时间。可以直接通过区段标记+分组统计实现,逻辑完全可控,不需要依赖复杂的峰值检测参数:
#### 修正后代码 #### library(dplyr) ## 数据集创建部分和原代码一致 time_initial <- seq(from = as.POSIXct("08:19:00", "%H:%M:%S", tz="UTC"), to = as.POSIXct("08:19:19", "%H:%M:%S", tz="UTC"), by = "1 sec") time_min <- format(as.POSIXct(time_initial), format = '%H:%M:%S') exposure <- c(0,0,2,3,5,0,0,4,5,6,0.5,0.25,0,0,0,0,4,5,0,0) data <- as.data.frame(cbind(time_min, exposure)) data$exposure <- as.numeric(data$exposure) ## 标记连续超过阈值1的区段 data$above_thres <- data$exposure > 1 # 为每段连续的超阈值序列分配唯一ID data$segment_id <- cumsum(c(TRUE, diff(data$above_thres) != 0)) data$segment_id[!data$above_thres] <- NA ## 分组提取峰值信息 peak_info <- data %>% filter(!is.na(segment_id)) %>% group_by(segment_id) %>% summarise( peak_number = cur_group_id(), time_peak_max = time_min[which.max(exposure)], peak_height = max(exposure), peak_start = first(time_min), peak_end = last(time_min), .groups = "drop" ) %>% select(-segment_id)
运行结果
执行代码后得到的peak_info完全匹配预期输出:
- 第1个峰值:区间08:19:02 - 08:19:04,峰值高度5
- 第2个峰值:区间08:19:07 - 08:19:09,峰值高度6
- 第3个峰值:区间08:19:16 - 08:19:17,峰值高度5
如果后续需要调整阈值(比如改为暴露量超过2才纳入),只需要修改data$above_thres <- data$exposure > 1这一行的判断数值即可。如果遇到单个连续超阈值区段内存在多个局部峰值的场景,可以在分组内再调用findpeaks()做二次识别,适配更复杂的检测需求。
内容的提问来源于stack exchange,提问作者Miquel Vallbona
相关产品推荐
相关产品推荐

