【问题标题】:make a variable based on a cumulative sum with reset based on condition基于累积和创建变量,并根据条件重置
【发布时间】:2019-03-24 06:23:25
【问题描述】:

我想要一个变量,例如desired_output,它基于cumsumover 的累积和,其中cumsum 函数每次到达thresh 中的下一个数字时都会重置。

cumsumover <- c(1, 2, 7, 4, 2, 5)
thresh <- c(3, 7, 11)
desired_output <- c(3, 3 ,7 ,11 ,11 ,11) # same length as cumsumover

这个问题很相似,但我无法理解代码。 dplyr / R cumulative sum with reset

与类似的问题相比,我的条件是在与cumsumover 不同长度的向量中指定的。

任何帮助将不胜感激。如果同时提供了基础 R 和 tidyverse 方法,则会获得奖励。

【问题讨论】:

    标签: r


    【解决方案1】:

    使用.bincode 你可以这样做:

    thresh[.bincode(cumsum(cumsumover), c(-Inf,thresh[-1],Inf))]
    [1]  3  3  7 11 11 11
    

    .bincode被cut使用,基本上是加了标签和检查,所以效率更高:

     x <-rep(cumsum(cumsumover),10000)
    microbenchmark::microbenchmark(
      bincode   = thresh[.bincode(x, c(-Inf,thresh[-1],Inf))],
      cut       = cut(x,breaks = c(-Inf, thresh[-1], Inf),labels = thresh))
    # Unit: microseconds
    #     expr    min      lq     mean  median      uq     max neval
    #  bincode  450.2  459.75  654.794  482.10  642.20  5028.4   100
    #      cut 1739.3 1864.90 2622.593 2215.15 2713.25 12194.8   100
    

    【讨论】:

      【解决方案2】:

      在基础 R 中,我们可以使用 cut 和 breaks 作为 thresh 和 labels 作为 letters 的长度与 thresh 相同。

      cut(cumsum(cumsumover),breaks = c(0, thresh[-1], max(cumsum(cumsumover))),
                labels = letters[seq_along(thresh)])
      
      #[1] a a b c c c
      

      将thresh 的最后一个元素替换为max(cumsum(cumsumover)),以便thresh 的最后一个元素之外的任何内容都被分配到最后一个label。


      如果我们想要 labels 为 thresh 而不是 letters

      cut(cumsum(cumsumover),breaks = c(0, thresh[-1], max(cumsum(cumsumover))),labels = thresh)
      #[1] 3  3  7  11 11 11
      

      【讨论】:

      • 我添加了一个更通用的示例,因为我得到了错误:'breaks' are not unique
      • @dzgreen 不建议不断更改您的问题。每个问题应该只解决一个独特的问题。我建议你问一个新问题。
      • 我会这样做的。感谢您的建议。
      【解决方案3】:

      这是另一个解决方案:

      数据:

      cumsumover <- c(1, 2, 7, 4, 2, 5)
      thresh     <- c(3, 7, 11)
      

      代码:

      outp <- letters[1:3] # to make solution more general
      cumsumover_copy <- cumsumover  # I use <<- inside sapply so therefore I make a copy to stay save
      
      unlist(
      sapply(seq_along(thresh), function(x) {
          cs_over <- cumsum(cumsumover_copy)
          ntimes = sum( cs_over <= thresh[x] )
          cumsumover_copy <<- cumsumover_copy[-(1:ntimes)]
          return( rep(outp[x], ntimes) )
                                   } )
      )
      

      结果:

      #[1] "a" "a" "b" "c" "c" "c"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 2020-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-16
        • 1970-01-01
        相关资源
        最近更新 更多