【问题标题】:How to reset cumsum at end of consecutive string [duplicate]如何在连续字符串的末尾重置 cumsum [重复]
【发布时间】:2016-04-06 04:32:55
【问题描述】:

如果我有以下向量:

x = c(1,1,1,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1)

如何计算所有连续 1 的累积总和,每次击中 0 时重置?

因此,所需的输出将如下所示:

> y
[1] 1 2 3 0 0 0 0 1 2 0 0 1 2 3 0 0 1 2 3 4 0 0 0 0 1 2 3

【问题讨论】:

  • 今天有人碰到了这个问题的旧版本。标记为骗子。 (虽然我不得不说我认为你的标题更具描述性。)

标签: r


【解决方案1】:

这行得通:

unlist(lapply(rle(x)$lengths, FUN = function(z) 1:z)) * x
# [1] 1 2 3 0 0 0 0 1 2 0 0 1 2 3 0 0 1 2 3 4 0 0 0 0 1 2 3

它在很大程度上依赖于您只有 1 和 0 的特殊情况,但对于这种情况,它工作得很好!更好的是,@nicola 提出了改进建议:

sequence(rle(x)$lengths) * x
# [1] 1 2 3 0 0 0 0 1 2 0 0 1 2 3 0 0 1 2 3 4 0 0 0 0 1 2 3

【讨论】:

    【解决方案2】:

    我阅读了 this post 关于如何拆分向量,并使用 @Calimo 的 splitAt2

    原来是这样的:

    splitAt2 <- function(x, pos) {
            out <- list()
            pos2 <- c(1, pos, length(x)+1)
            for (i in seq_along(pos2[-1])) {
                    out[[i]] <- x[pos2[i]:(pos2[i+1]-1)]
            }
            return(out)
    }
    
    x = c(1,1,1,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1)
    
    where_split = which(x == 0)
    
    x_split = splitAt2(x, where_split)
    
    unlist(sapply(x_split, cumsum))
    # [1] 1 2 3 0 0 0 0 1 2 0 0 1 2 3 0 0 1 2 3 4 0 0 0 0 1 2 3
    

    【讨论】:

      【解决方案3】:

      这是另一个选择

      library(data.table)
      ave(x, rleid(x), FUN=seq_along)*x
      #[1] 1 2 3 0 0 0 0 1 2 0 0 1 2 3 0 0 1 2 3 4 0 0 0 0 1 2 3
      

      或者没有任何包

      ave(x, cumsum(c(TRUE, x[-1]!= x[-length(x)])), FUN=seq_along)*x
      #[1] 1 2 3 0 0 0 0 1 2 0 0 1 2 3 0 0 1 2 3 4 0 0 0 0 1 2 3
      

      【讨论】:

        猜你喜欢
        • 2014-09-18
        • 1970-01-01
        • 2016-03-21
        • 1970-01-01
        • 1970-01-01
        • 2012-10-04
        • 1970-01-01
        • 1970-01-01
        • 2014-05-14
        相关资源
        最近更新 更多