当前位置:  开发笔记 > 编程语言 > 正文

有条件的cumsum与重置

如何解决《有条件的cumsum与重置》经验,为你挑选了1个好方法。

我有一个数据框,数据框已按需要排序,但现在我想在组中"切片".

此组的最大累计值应为10.当累计值> 10时,它应重置累计总和并重新开始

library(dplyr)
id <- sample(1:15)
order <- 1:15
value  <- c(4, 5, 7, 3, 8, 1, 2, 5, 3, 6, 2, 6, 3, 1, 4)
df  <- data.frame(id, order, value)
df

这是我正在寻找的输出(我是"手动"完成的)

cumsum_10  <- c(4, 9, 7, 10, 8, 9, 2, 7, 10, 6, 8, 6, 9, 10, 4)
group_10 <- c(1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7)
df1  <- data.frame(df, cumsum_10, group_10)
df1

所以我遇到了两个问题

    如何创建一个累积变量,每当它超过上限时重置(在这种情况下为10)

    如何计算/分组每个组

对于第一部分,我尝试了group_by和cumsum的一些组合而没有运气

df1 <- df %>% group_by(cumsum(c(False, value < 10)))

我更喜欢管道(%>%)解决方案而不是for循环

谢谢



1> Rentrop..:

我认为这不容易矢量化......至少我不知道如何.

你可以by hand通过以下方式完成:

my_cumsum <- function(x){
  grp = integer(length(x))
  grp[1] = 1
  for(i in 2:length(x)){
    if(x[i-1] + x[i] <= 10){
      grp[i] = grp[i-1]
      x[i] = x[i-1] + x[i]
    } else {
      grp[i] = grp[i-1] + 1
    }
  }
  data.frame(grp, x)
}

对于您的数据,这给出:

> my_cumsum(df$value)
   grp  x
1    1  4
2    1  9
3    2  7
4    2 10
5    3  8
6    3  9
7    4  2
8    4  7
9    4 10
10   5  6
11   5  8
12   6  6
13   6  9
14   6 10
15   7  4

同样对于我的"反例",这给出了:

> my_cumsum(c(10,6,4))
  grp  x
1   1 10
2   2  6
3   2 10

正如@Khashaa所指出的,这可以通过更有效的方式实现Rcpp.他链接到这个答案如何加速或矢量化for循环?我觉得非常有用

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有