r - 带重置的条件累加

标签 r dplyr reset cumsum

我有一个数据框,该数据框已经根据需要进行了排序,但现在我想将其“切片”成组。

此组的最大累积值应为 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 更有效地实现。 .他链接到这个答案 How to speed up or vectorize a for loop?我觉得这非常有用

    关于r - 带重置的条件累加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34531568/

    相关文章:

    r - r 中的 Order() 函数排序不正确

    R对连续的重复行求和并删除除第一个以外的所有行

    c - 如何构造一个命名列表(一个 SEXP)以从使用 .Call() 调用的 C 函数中返回?

    r - 在 R 中使用 dplyr::if_else() 根据另一个变量的值更改 POSIXct 时间戳的时区

    android - 如何在 Kiosk 模式下运行 Android 应用程序,禁用安全模式并防止设备硬重置?

    r - 使用 SparkR 查找生成主键的变量

    r - 具有多个条件和 OR 的 dplyr 过滤器

    r - 按非缺失值分组 Dplyr

    git - 如何回滚之前的两次提交?

    mysql - 在没有 mysql_data_seek 的情况下重置结果指针