我有一个数据框,数据框已按需要排序,但现在我想在组中"切片".
此组的最大累计值应为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循环
谢谢
我认为这不容易矢量化......至少我不知道如何.
你可以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循环?我觉得非常有用