根据累计和使变量,并根据条件进行重置

时间:2018-10-19 10:57:09

标签: r

我想要一个基于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方法,则将获得奖励。

3 个答案:

答案 0 :(得分:2)

在基数R中,我们可以使用cut,将breaks用作thresh,将labels用作letters,其长度与thresh相同。 / p>

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

答案 1 :(得分:0)

这是另一种解决方案:

数据:

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"

答案 2 :(得分:0)

使用.bincode,您可以这样做:

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

.bincodecut使用,基本上可以添加标签和检查,因此效率更高:

 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