R语言统计时间序列步段 查找Step=1最长持续时段
R语言简洁实现时间序列连续步段统计
不需要手动写循环逐行判断0/1切换节点,利用相邻值变化生成分组ID的向量化技巧,几行代码就能完成全部统计,性能远高于手写迭代,逻辑也更清晰。
核心实现(data.table方案,适合大体积时序数据集)
首先读入数据并做时间格式转换:
library(data.table) # 读入示例数据 dt <- fread(text = " Time_TS Step 17:54:41 0 17:54:43 0 17:54:45 0 17:54:46 1 17:54:47 1 17:54:48 1 17:54:49 1 17:54:50 0 17:54:51 0 17:54:54 0 17:54:55 0 17:54:56 1 17:54:57 1 17:54:59 1 17:55:01 1 17:55:03 0 17:55:08 0 17:55:10 0 17:55:14 1 17:55:15 1 17:55:20 0 17:55:21 0 17:55:23 0 17:55:24 0 17:55:26 0 17:55:27 0 17:55:30 0 17:55:31 0 17:55:35 1 17:55:37 1 17:55:41 1 17:55:43 1 17:55:45 1 17:55:48 0 17:55:53 0 17:55:56 0 17:55:59 0 17:56:02 0 ") # 把时间字符串转为POSIXct时间类型 dt[, Time_TS := as.POSIXct(Time_TS, format = "%H:%M:%S")]
第一步:自动生成连续段ID
核心逻辑只需要1行:当当前行Step值和上一行不一致时,段ID累加1,自动完成所有连续同值段的分组标记,不需要手动判断切换方向:
dt[, seg_id := cumsum(Step != shift(Step, fill = first(Step)))]
第二步:按需计算统计指标
- 统计总步段数:段ID从0开始计数,总段数为最大ID+1
total_segments <- max(dt$seg_id) + 1
- 计算所有Step=1连续段的持续时长:按段ID分组,取每组首尾时间做差即可
seg_stats <- dt[, .( step_value = first(Step), start = min(Time_TS), end = max(Time_TS), duration_sec = as.numeric(difftime(max(Time_TS), min(Time_TS), units = "secs")) ), by = seg_id] step1_segments <- seg_stats[step_value == 1, .(seg_id, start, end, duration_sec)]
- 提取Step=1段的最大时长
max_step1_duration <- max(step1_segments$duration_sec)
示例数据运行结果
- 总连续步段数:9
- Step=1各段时长:
- 17:54:46 ~ 17:54:49:3秒
- 17:54:56 ~ 17:55:01:5秒
- 17:55:14 ~ 17:55:15:1秒
- 17:55:35 ~ 17:55:45:10秒
- Step=1段最大持续时长:10秒
dplyr/tidyverse 等价实现
如果习惯用tidyverse语法,逻辑完全一致:
library(dplyr) df <- dt %>% mutate(seg_id = cumsum(Step != lag(Step, default = first(Step)))) total_segments <- max(df$seg_id) + 1 seg_stats <- df %>% group_by(seg_id) %>% summarise( step_value = first(Step), start = min(Time_TS), end = max(Time_TS), duration_sec = as.numeric(difftime(end, start, units = "secs")), .groups = "drop" ) step1_segments <- seg_stats %>% filter(step_value == 1) max_step1_duration <- max(step1_segments$duration_sec)
方案优势
- 全程向量化运算,没有逐行循环逻辑,百万行级数据也能秒级出结果
- 通用性强,不管Step是二值还是多分类取值,都能自动识别连续分段,不需要针对特定值写切换判断
- 扩展灵活,后续如果需要统计0段时长、段内采样点数、段间隔等指标,直接在分组统计部分加计算逻辑即可
内容的提问来源于stack exchange,提问作者thentangler
相关产品推荐
相关产品推荐

