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