【问题标题】:Reset cumulative sum after 10 values在 10 个值后重置累积和
【发布时间】:2020-03-20 10:48:56
【问题描述】:

我在 h 中有数据,我想在 bw 中求和,在 10 步后我想重置 cumsum。我怎么得到这个?

   h bw
1  0  0
2  0  0
3  1  1
4  0  1
5  1  2
6  0  2
7  0  2
8  1  3
9  1  4
10 1  5
11 0  0
12 0  0
13 0  0
14 0  0
15 1  1
16 1  2
17 1  3
18 0  3
19 0  3
20 1  4
21 1  1
22 0  1

目前我正在处理这个:

ff = function(x)
{
  cs = cumsum(x)
  cs - cummax((x == 0) * cs)
}

但它会在 h 为 0 而不是在 10 个值之后重置。

非常感谢!

【问题讨论】:

    标签: r cumsum


    【解决方案1】:

    您可以按每个元素的位置对向量进行模 10 分割,以将其作为单线来执行。

    as.numeric(unlist(sapply(split(df$bw, (seq_along(df$bw)-1) %/% 10), cumsum)))
    # [1]  0  0  1  2  4  6  8 11 15 20  0  0  0  0  1  3  6  9 12 16  1  2
    

    【讨论】:

      【解决方案2】:

      使用ave 你可以做到

      bw <- ave(h, rep(1:ceiling(length(h)/10), each=10)[seq(h)], FUN=cumsum)
      bw
      # [1] 0 0 1 1 2 2 2 3 4 5 0 0 0 0 1 2 3 3 3 4 1 1
      

      数据

      h <- c(0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0)
      

      【讨论】:

        【解决方案3】:
        df <- structure(list(h = c(0L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 
        0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 0L), bw = c(0L, 0L, 
        1L, 1L, 2L, 2L, 2L, 3L, 4L, 5L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 3L, 
        3L, 4L, 1L, 1L), cs = c(0L, 0L, 1L, 1L, 2L, 2L, 2L, 3L, 4L, 5L, 
        0L, 0L, 0L, 0L, 1L, 2L, 3L, 3L, 3L, 4L, 1L, 1L)), row.names = c("1", 
        "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
        "14", "15", "16", "17", "18", "19", "20", "21", "22"), class = "data.frame")
        
        cumsum10 <- function(x){
          idx <- seq(x)%%10
          starts <- c(1, which(idx == 0)+1)
          stops <- c(which(idx == 0), length(x))
        
          res <- vector("list", length(starts))
          for(i in seq(res)){
            res[[i]] <- cumsum(x[starts[i]:stops[i]])
          }
          res <- do.call("c", res)
          return(res)
        }
        
        
        df$cs <- cumsum10(df$bw)
        df
        
        
        #    h bw cs
        # 1  0  0  0
        # 2  0  0  0
        # 3  1  1  1
        # 4  0  1  2
        # 5  1  2  4
        # 6  0  2  6
        # 7  0  2  8
        # 8  1  3 11
        # 9  1  4 15
        # 10 1  5 20
        # 11 0  0  0
        # 12 0  0  0
        # 13 0  0  0
        # 14 0  0  0
        # 15 1  1  1
        # 16 1  2  3
        # 17 1  3  6
        # 18 0  3  9
        # 19 0  3 12
        # 20 1  4 16
        # 21 1  1  1
        # 22 0  1  2
        

        【讨论】:

        • 输出中的 cs 和 bw 不一样吗?
        • 抱歉,返回的是 x 而不是 res。现在应该是正确的。
        【解决方案4】:

        使用 dplyr 的另一个选项

        library(tidyverse)
        df %>% 
          mutate(id = (row_number()-1)%/%10) %>% 
          group_by(id) %>% 
          mutate(cs = cumsum(bw)) %>% 
          select(-id)
        

        【讨论】:

          猜你喜欢
          • 2016-02-07
          • 1970-01-01
          • 2018-01-26
          • 2021-05-22
          • 2021-04-10
          • 1970-01-01
          • 1970-01-01
          • 2021-07-27
          • 2020-11-18
          相关资源
          最近更新 更多