R 仅适用于正数的累积和

R 仅适用于正数的累积和,r,R,我有这个向量: x = c(1,1,1,1,1,0,1,0,0,0,1,1) 我只想对正数做一个累加。我应该得到以下向量作为回报: xc = (1,2,3,4,5,0,1,0,0,0,1,2) 我怎么做呢 我尝试过:cumsum(x),但这会对所有值进行累积和,并给出: cumsum(x) [1] 1 2 3 4 5 5 6 6 6 6 7 8 我对R不太了解,但我已经用Python编写了一段小代码。逻辑在所有语言中都是一样的。希望这对你有帮助 x=[1,1,1,1,1,0,1,0,0,0

我有这个向量:

x = c(1,1,1,1,1,0,1,0,0,0,1,1)
我只想对正数做一个累加。我应该得到以下向量作为回报:

xc = (1,2,3,4,5,0,1,0,0,0,1,2)
我怎么做呢

我尝试过:
cumsum(x)
,但这会对所有值进行累积和,并给出:

cumsum(x)
[1] 1 2 3 4 5 5 6 6 6 6 7 8

我对R不太了解,但我已经用Python编写了一段小代码。逻辑在所有语言中都是一样的。希望这对你有帮助

x=[1,1,1,1,1,0,1,0,0,0,1,1]
tot=0
for i in range(0,len(x)):
    if x[i]!=0:
        tot=tot+x[i]
        x[i]=tot
    else:
        tot=0
print x
一个选择是

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
x1
x=c(1,1,1,1,1,0,1,0,0,1,1)

cumsum\uup>这里有一个可能的解决方案,使用及其新的
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

基本
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
或:


xsplit和lappy版本:

x <- c(1,1,1,1,1,0,1,0,0,0,1,1)
unlist(lapply(split(x, cumsum(x==0)), cumsum))

下面是另一个使用
aggregate
的base R解决方案。我们的想法是用
x
和一个名为
x.1
的新列创建一个数据框,通过它我们可以应用
aggregate
函数(
cumsum
):

x试试这一行

Reduce(function(x,y) (x+y)*(y!=0), x, accumulate=T)

通常不推荐从函数内修改全局环境。如果使用这个函数,最好将它转换成C++并使用RCPP。kid可能比较慢,但是ave(x,rleid(x),FUN=cumsum)
也可以工作。这很好,实际上可以更快。
unlist(Map(function(u,v) if(v==0) rep(0,u) else 1:u, rle(x)$lengths, rle(x)$values))
x<-c(1,1,1,1,1,0,1,0,0,0,1,1)

skumulowana<-function(x) {
  dl<-length(x)
  xx<-numeric(dl+1)
  for (i in 1:dl){
    ifelse (x[i]==0,xx[i+1]<-0,xx[i+1]<-xx[i]+x[i])
  }
wynik<<-xx[1:dl+1]
return (wynik)
}

skumulowana(x)
## [1] 1 2 3 4 5 0 1 0 0 0 1 2
x <- c(1,1,1,1,1,0,1,0,0,0,1,1)
unlist(lapply(split(x, cumsum(x==0)), cumsum))
a <- split(x, cumsum(x==0)) # divides x into pieces where each 0 starts a new piece
b <- lapply(a, cumsum)  # calculates cumsum in each piece
unlist(b)  # rejoins the pieces 
# 01 02 03 04 05 11 12  2  3 41 42 43 
#  1  2  3  4  5  0  1  0  0  0  1  2 
x <- c(1,1,1,1,1,0,1,0,0,0,1,1)
r <- rle(x)
df <- data.frame(x, 
x.1=unlist(sapply(1:length(r$lengths), function(i) rep(i, r$lengths[i]))))

# df

   # x x.1
# 1  1   1
# 2  1   1
# 3  1   1
# 4  1   1
# 5  1   1
# 6  0   2
# 7  1   3
# 8  0   4
# 9  0   4
# 10 0   4
# 11 1   5
# 12 1   5

agg <- aggregate(df$x~df$x.1, df, cumsum)
as.vector(unlist(agg$`df$x`))

# [1] 1 2 3 4 5 0 1 0 0 0 1 2
Reduce(function(x,y) (x+y)*(y!=0), x, accumulate=T)