【问题标题】:Time series cumulative sum with two conditional resets [duplicate]具有两个条件重置的时间序列累积和[重复]
【发布时间】:2021-10-02 21:28:10
【问题描述】:

我正在寻找一种(最好是 tidyverse)解决方案来创建基于列 direction 的运行计数器(累积和),每次方向更改或停止时都会重置 counter

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union

df <- tibble::tribble(
    ~direction,             ~datetime, ~counter,
        "Left",  "2020-09-27 8:00:00",       1L,
        "Left",  "2020-09-27 9:00:00",       2L,
       "Right", "2020-09-27 10:00:00",       1L,
       "Right", "2020-09-27 11:00:00",       2L,
       "Right", "2020-09-27 12:00:00",       3L,
        "Stop", "2020-09-27 13:00:00",       1L,
        "Left", "2020-09-27 14:00:00",       1L,
       "Right", "2020-09-27 15:00:00",       1L,
        "Left", "2020-09-27 16:00:00",       1L,
        "Left", "2020-09-27 17:00:00",       2L
    ) %>% 
  mutate(datetime = as_datetime(datetime))
df
#> # A tibble: 10 x 3
#>    direction datetime            counter
#>    <chr>     <dttm>                <int>
#>  1 Left      2020-09-27 08:00:00       1
#>  2 Left      2020-09-27 09:00:00       2
#>  3 Right     2020-09-27 10:00:00       1
#>  4 Right     2020-09-27 11:00:00       2
#>  5 Right     2020-09-27 12:00:00       3
#>  6 Stop      2020-09-27 13:00:00       1
#>  7 Left      2020-09-27 14:00:00       1
#>  8 Right     2020-09-27 15:00:00       1
#>  9 Left      2020-09-27 16:00:00       1
#> 10 Left      2020-09-27 17:00:00       2

reprex package (v2.0.0) 于 2021-07-27 创建

我尝试调整来自 this solution 的代码,但无法让它在两次条件重置时工作。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    在基础 R 中,您可以使用 rlesequence -

    df$counter <- sequence(rle(df$direction)$lengths)
    

    如果你想在管道中使用它,你可以这样做 -

    library(dplyr)
    df %>% mutate(counter = sequence(rle(direction)$lengths))
    
    #  direction datetime            counter
    #   <chr>     <dttm>                <int>
    # 1 Left      2020-09-27 08:00:00       1
    # 2 Left      2020-09-27 09:00:00       2
    # 3 Right     2020-09-27 10:00:00       1
    # 4 Right     2020-09-27 11:00:00       2
    # 5 Right     2020-09-27 12:00:00       3
    # 6 Stop      2020-09-27 13:00:00       1
    # 7 Left      2020-09-27 14:00:00       1
    # 8 Right     2020-09-27 15:00:00       1
    # 9 Left      2020-09-27 16:00:00       1
    #10 Left      2020-09-27 17:00:00       2
    

    【讨论】:

      【解决方案2】:

      我们可以使用rowidrleid

      library(dplyr)
      library(data.table)
      df %>% 
          mutate(counter2 = rowid(rleid(direction)))
      

      -输出

      # A tibble: 10 x 4
         direction datetime            counter counter2
         <chr>     <dttm>                <int>    <int>
       1 Left      2020-09-27 08:00:00       1        1
       2 Left      2020-09-27 09:00:00       2        2
       3 Right     2020-09-27 10:00:00       1        1
       4 Right     2020-09-27 11:00:00       2        2
       5 Right     2020-09-27 12:00:00       3        3
       6 Stop      2020-09-27 13:00:00       1        1
       7 Left      2020-09-27 14:00:00       1        1
       8 Right     2020-09-27 15:00:00       1        1
       9 Left      2020-09-27 16:00:00       1        1
      10 Left      2020-09-27 17:00:00       2        2
      

      或者只使用dplyr

      df %>% 
          group_by(grp = cumsum(direction != 
              lag(direction, default = first(direction)))) %>% 
          mutate(counter2 = row_number()) %>%
          ungroup %>% 
          select(-grp)
      # A tibble: 10 x 4
         direction datetime            counter counter2
         <chr>     <dttm>                <int>    <int>
       1 Left      2020-09-27 08:00:00       1        1
       2 Left      2020-09-27 09:00:00       2        2
       3 Right     2020-09-27 10:00:00       1        1
       4 Right     2020-09-27 11:00:00       2        2
       5 Right     2020-09-27 12:00:00       3        3
       6 Stop      2020-09-27 13:00:00       1        1
       7 Left      2020-09-27 14:00:00       1        1
       8 Right     2020-09-27 15:00:00       1        1
       9 Left      2020-09-27 16:00:00       1        1
      10 Left      2020-09-27 17:00:00       2        2
      

      【讨论】:

        猜你喜欢
        • 2019-10-16
        • 2018-05-02
        • 1970-01-01
        • 2018-08-09
        • 2020-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多