有条件的累加重置 [英] Conditional cumsum with reset
问题描述
我有一个数据框,该数据框已根据需要进行排序,但是现在我想按组切片。
I have a data frame, the data frame is already sorted as needed, but now I will like to "slice it" in groups.
此组的最大累计值应为10。当累计值> 10时,应重置累计和并重新开始
This groups should have a max cumulative value of 10. When the cumulative value is > 10, it should reset the cumulative sum and start over again
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
所以我有2个问题
- 如何创建一个累积变量,每次通过上限时都会重置限制(在这种情况下为10)
- 如何对每个组进行计数/分组
对于第一部分,我尝试了一些组合group_by和没有运气的cumsum
For the first part I was trying some combinations of group_by and cumsum with no luck
df1 <- df %>% group_by(cumsum(c(False, value < 10)))
我希望使用管道(%>%)解决方案而不是for循环
I would prefer a pipe (%>%) solution instead of a for loop
谢谢
推荐答案
我认为这不容易实现矢量化...
I think this is not easily vectorizable.... at least i do not know how.
您可以通过以下方式手动完成
:
You can do it by hand
via:
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循环?我觉得非常有用
As @Khashaa pointed out this can be implementet more efficiently via Rcpp
. He linked to this answer How to speed up or vectorize a for loop? which i find very useful
这篇关于有条件的累加重置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!