R语言时间序列中多次提取value=1首次出现对应时间的方法咨询
R 时间序列多段特定值首次出现位置实现方案
核心思路
基于data.table自带的游程编码函数rleid()识别连续值段,所有过滤、合并操作均基于连续段批量处理,无需逐行遍历,处理效率高且扩展性强。
前置依赖
需提前安装加载data.table包,示例数据如下:
library(data.table) data <- data.table::data.table( value = c(0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1), time = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) )
基础需求实现
返回所有连续值为1的段的第一个对应time值,预期输出4 14 18:
# 按连续值分组,提取每个1段的首个time,过滤空值 base_res <- data[, .SD[value == 1, time[1]], by = rleid(value)][!is.na(V1), V1] print(base_res) # 输出:4 14 18
进阶需求实现(支持跳过短连续0段)
封装为可自定义参数的函数,参数skip_zero_max为允许跳过的最大连续0长度,例如设置为2时,连续0长度≤2的段会被视为和前后1段同组,预期输出4 18:
get_first_one_time <- function(dt, skip_zero_max = 0) { # 复制数据避免修改原对象 dt_tmp <- copy(dt) # 标记每个连续段的id和段长度 dt_tmp[, `:=`( rid = rleid(value), seg_len = .N ), by = rid] # 替换长度<=阈值的0段为1,合并相邻1段 dt_tmp[value == 0 & seg_len <= skip_zero_max, value := 1] # 重新分组提取1段的首个time res <- dt_tmp[, .SD[value == 1, time[1]], by = rleid(value)][!is.na(V1), V1] return(res) } # 测试效果 print(get_first_one_time(data)) # 输出:4 14 18 print(get_first_one_time(data, skip_zero_max = 2)) # 输出:4 18
内容的提问来源于stack exchange,提问作者Bolle
相关产品推荐
相关产品推荐

