dplyr / R cumulative sum with reset

前端 未结 2 1978
臣服心动
臣服心动 2020-12-01 22:51

I\'d like to generate cumulative sums with a reset if the \"current\" sum exceeds some threshold, using dplyr. In the below, I want to cumsum over \'a\'.

lib         


        
相关标签:
2条回答
  • 2020-12-01 23:17

    if you're interested in the group building based on cumsum < threshold

    You can use the following base:: function:

    cumSumReset <- function(x, thresh = 4) {
        ans    <- numeric()
        i      <- 0
    
        while(length(x) > 0) {
            cs_over <- cumsum(x)
            ntimes <- sum( cs_over <= thresh )
            x      <- x[-(1:ntimes)]
            ans <- c(ans, rep(i, ntimes))
            i   <- i + 1
        }
        return(ans)
    }
    

    call:

    tib %>% mutate(g = cumSumReset(a, 5))
    

    result:

    #   A tibble: 6 x 3
    #      t     a     g
    #  <dbl> <dbl> <dbl>
    #1     1     2     0
    #2     2     3     0
    #3     3     1     1
    #4     4     2     1
    #5     5     2     1
    #6     6     3     2
    

    • with the group g you can now do whatever you like.
    0 讨论(0)
  • 2020-12-01 23:23

    I think you can use accumulate() here to help. And i've also made a wrapper function to use for different thresholds

    sum_reset_at <- function(thresh) {
      function(x) {
        accumulate(x, ~if_else(.x>=thresh, .y, .x+.y))
      }  
    }
    
    tib %>% mutate(c = sum_reset_at(5)(a))
    #       t     a     c
    #   <dbl> <dbl> <dbl>
    # 1     1     2     2
    # 2     2     3     5
    # 3     3     1     1
    # 4     4     2     3
    # 5     5     2     5
    # 6     6     3     3
    tib %>% mutate(c = sum_reset_at(4)(a))
    #       t     a     c
    #   <dbl> <dbl> <dbl>
    # 1     1     2     2
    # 2     2     3     5
    # 3     3     1     1
    # 4     4     2     3
    # 5     5     2     5
    # 6     6     3     3
    tib %>% mutate(c = sum_reset_at(6)(a))
    #       t     a     c
    #   <dbl> <dbl> <dbl>
    # 1     1     2     2
    # 2     2     3     5
    # 3     3     1     6
    # 4     4     2     2
    # 5     5     2     4
    # 6     6     3     7
    
    0 讨论(0)
提交回复
热议问题