You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于累计器状态重置的运行计数变量实现问题求助

问题:计算燃气流量累计值的连续未变化时长(gap_length)

我有一个以15分钟为间隔、跟踪燃气流量累计值的时间序列数据集,示例如下:

Date          Time       engine_totalizer
12/25/2021  9:30:00        187304950
12/25/2021  9:15:00        187304854
12/25/2021  9:00:00        187304854
12/25/2021  8:45:00        187304854
12/25/2021  8:30:00        187304854
12/25/2021  8:15:00        187304854
12/25/2021  8:00:00        187304854
12/25/2021  7:45:00        187304854
12/25/2021  7:30:00        187304854
12/25/2021  7:15:00        187304854
12/25/2021  7:00:00        187304854

其中engine_totalizer字段会周期性“卡住”(如7:00:00-9:15:00时段数值未变化)。需要创建gap_length变量:

  • 当累计值在相邻时间戳间变化时,gap_length为0;
  • 当累计值连续未变化时,从0开始递增计数(目标效果如下):
Date          Time       engine_totalizer   gap_length
12/25/2021  9:30:00        187304950        0
12/25/2021  9:15:00        187304854        10      
12/25/2021  9:00:00        187304854        9
12/25/2021  8:45:00        187304854        8
12/25/2021  8:30:00        187304854        7
12/25/2021  8:15:00        187304854        6
12/25/2021  8:00:00        187304854        5
12/25/2021  7:45:00        187304854        4
12/25/2021  7:30:00        187304854        3
12/25/2021  7:15:00        187304854        2
12/25/2021  7:00:00        187304854        1
12/25/2021  6:45:00        187304700        0

我尝试用dplyr的case_when和lead函数实现,但结果中gap_length全为0:

# Initialize gap_length 
df$gap_length <- 0
df<-df%>%
  mutate(gap_length = case_when(engine_totalizer == lead(engine_totalizer) ~ lead(gap_length) + 1,
                         TRUE ~ 0))

求正确实现方式。


解决方案

你的代码失效原因是**lead(gap_length)引用的是未更新的初始值(全0)**,导致计算结果始终为0。要实现目标需求,需要先标记连续相同值的区块,再在区块内倒序生成计数。

正确代码实现

library(dplyr)

# 第一步:确保数据按时间降序排列(匹配示例的顺序)
df <- df %>%
  mutate(datetime = as.POSIXct(paste(Date, Time), format = "%m/%d/%Y %H:%M:%S")) %>%
  arrange(desc(datetime)) %>%
  select(-datetime)  # 可选:移除临时生成的datetime列

# 第二步:计算gap_length
df <- df %>%
  # 生成连续相同engine_totalizer的分组ID
  mutate(group_id = cumsum(engine_totalizer != lag(engine_totalizer, default = first(engine_totalizer) + 1))) %>%
  group_by(group_id) %>%
  # 组内第一行(值变化的位置)为0,后续行依次递增
  mutate(gap_length = row_number() - 1) %>%
  ungroup() %>%
  select(-group_id)  # 移除临时分组ID列

关键逻辑说明

  1. 分组标识group_id:通过cumsum(engine_totalizer != lag(...)),每当engine_totalizer发生变化时,分组ID自动加1,把连续相同值的行归为同一组;
  2. 倒序计数:在每个分组内,row_number() - 1让组内第一行(最新的、值刚变化的行)为0,时间更早的行依次递增,完全匹配目标效果;
  3. 默认值处理:lag(..., default = first(engine_totalizer) + 1)确保第一行能正确生成第一个分组ID,避免逻辑错误。

如果你的原始数据是按时间升序排列的,只需将arrange(desc(datetime))改为arrange(datetime),并将gap_length = row_number() - 1替换为gap_length = n() - row_number(),即可实现从变化点往前递增的计数。


内容的提问来源于stack exchange,提问作者Bryan Stolzenburg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:03:39