仅为正数的累计和

Mat*_*ath 29 r

我有这个向量:

x = c(1,1,1,1,1,0,1,0,0,0,1,1)
Run Code Online (Sandbox Code Playgroud)

而且我只想为正数做累积求和.我应该有以下向量作为回报:

xc = (1,2,3,4,5,0,1,0,0,0,1,2)
Run Code Online (Sandbox Code Playgroud)

我怎么能这样做?

我已经尝试过了,cumsum(x)但是它会对所有值进行累积求和,并给出:

cumsum(x)
[1] 1 2 3 4 5 5 6 6 6 6 7 8
Run Code Online (Sandbox Code Playgroud)

akr*_*run 30

一种选择是

x1 <- inverse.rle(within.list(rle(x), values[!!values] <- 
                  (cumsum(values))[!!values]))
x[x1!=0] <- ave(x[x1!=0], x1[x1!=0], FUN=seq_along)
x
#[1] 1 2 3 4 5 0 1 0 0 0 1 2
Run Code Online (Sandbox Code Playgroud)

或者是一行代码

 x[x>0] <-  with(rle(x), sequence(lengths[!!values]))
 x
 #[1] 1 2 3 4 5 0 1 0 0 0 1 2
Run Code Online (Sandbox Code Playgroud)


Dav*_*urg 19

下面是使用一个可能的解决方案data.tableV> = 1.9.5及其新rleid功能可按

library(data.table)
as.data.table(x)[, cumsum(x), rleid(x)]$V1
## [1] 1 2 3 4 5 0 1 0 0 0 1 2
Run Code Online (Sandbox Code Playgroud)


Col*_*vel 10

基础R,一线解决方案Map Reduce:

> Reduce('c', Map(function(u,v) if(v==0) rep(0,u) else 1:u, rle(x)$lengths, rle(x)$values))
 [1] 1 2 3 4 5 0 1 0 0 0 1 2
Run Code Online (Sandbox Code Playgroud)

要么:

unlist(Map(function(u,v) if(v==0) rep(0,u) else 1:u, rle(x)$lengths, rle(x)$values))
Run Code Online (Sandbox Code Playgroud)


luk*_*keA 5

x=c(1,1,1,1,1,0,1,0,0,0,1,1)
cumsum_ <- function(x) {
  r <- rle(x)
  s <- split(x, rep(seq_along(r$values), rle(x)$lengths))
  return(unlist(sapply(s, cumsum), use.names = F))
}
(xc <- cumsum_(x))
# [1] 1 2 3 4 5 0 1 0 0 0 1 2
Run Code Online (Sandbox Code Playgroud)