R:创建一个运行计数变量,根据前一行的值计算,根据条件重置

问题描述 投票:0回答:2

我有一个时间序列数据集,它使用总值以 15 分钟为间隔跟踪气体流量。下面的示例数据框(df)。

 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

周期性地,累加器值会“卡住”一段时间。从 7:00:00 - 9:15:00 查看上面的“engine_totalizer”列。

我希望能够使用运行中的计数器变量(以下示例数据框中的“gap_length”)跟踪累加器“卡住”的这些间隙,如果累加器从一个时间戳更改为另一个时间戳,则该变量将为零,但会计数对于累加器不会从一个时间戳更改为另一个时间戳的每个连续时间戳,从零开始。

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 来完成此操作:

# 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))

但是当我使用上面的代码时,gap_length 只是为每个时间戳返回零。

我不确定我是否错误地使用了 lead() 函数,或者是否有更有效的方法来完成此任务。

谢谢!

r dplyr time-series
2个回答
0
投票

对我来说,似乎 mutate() 在使用后续行中更新的间隙值时遇到了问题(即,它似乎认为 lead(gap) 无论如何仍然是 0)。不是这方面的专家,但这是我想出的解决方案(注意:您必须按时间 降序 对数据进行排序——从最早到最新——这样才能按照你想要的方式工作):

#sort data first
df <- df %>% arrange(desc(date))

new_vect <- vector()

for (i in 1:nrow(df)) {
  if (i != 1){
    if(df$totalizer[i] == df$totalizer[i-1]) {
      new_vect <- append(new_vect, new_vect[i-1] + 1)
    } else {
      new_vect <- append(new_vect, 0)
    }
  }else {
    new_vect <- append(new_vect, 0)
  }
}

df$gap <- new_vect

#can always re-arrange the data after
df <- df %>% arrange(date)

0
投票

我无法用 R 或 T-SQL 回答这个问题,但这正是 Kaskada 的目标——处理时间和基于事件的数据。

您可以从 Parquet 或其他各种格式加载数据。

因为 Kaskada 要求基于事件的数据按时间排序并按用户分组,所以编写这些类型的查询要容易得多:

# Create a sequence of booleans indicating unchanged values.
let changed = lag(Table.engine_totalizer) != Table.engine_totalizer
in {
  gap_length: count(Table, window=since(changed))
}

免责声明:我是Kaskada团队的一员。

© www.soinside.com 2019 - 2024. All rights reserved.