R中的条件累加?

3

你好,这是一个与以下问题相关的扩展: 条件累积和

假设我有以下向量。我想计算零块内的累加运行总数。

d <- c(0,0,0,1,3,4,5,-1,2,3,-5,8,0,0,-2,-3,3,5,0,0,0,-1,-1,-1,-1);

Ans d <- c(0,0,0,1,4,8,13,12,14,17,12,20,0,0,-2,-5,-2,3,0,0,0,-1,-2,-3,-4).

我希望以向量化的方式完成操作,因为我的向量相当大。到目前为止,我一直在尝试使用rle来实现这一点,但没有取得太多成功。
非常感谢。

第二个向量中可能应该有“...,20,0,0,-2,-5,...”吗? - Julius Vainora
2个回答

5

这样会起作用:

aux <- split(d, cumsum(d == 0))
v <- unlist(sapply(aux, cumsum))
1   2  31  32  33  34  35  36  37  38  39 310   4  51  52  53  54  55   6   7  81  82  83  84  85 
0   0   0   1   4   8  13  12  14  17  12  20   0   0  -2  -5  -2   3   0   0   0  -1  -2  -3  -4  
as.vector(v)
[1]  0  0  0  1  4  8 13 12 14 17 12 20  0  0 -2 -5 -2  3  0  0  0 -1 -2 -3 -4

这里as.vector()只是隐藏了元素的数量。


嗨 @Julius,我的理解是sapply是应用for循环的更好的方式。没有任何"apply"函数族可以做到吗? - user1480926
2
如果在unlist调用中设置了use.names=FALSE,则不需要使用as.vector。@user1480926:您必须对非零元素的组进行cumsum,因此无法避免循环(显式或隐式)。 - Joshua Ulrich
哦,完全没有考虑向量化.. @JoshuaUlrich,好观点,谢谢。 - Julius Vainora

0

这应该可以工作。没有循环。 非常快,因为所有的工作都在 R 外部进行。

sum_from<-function(value,from)
{
  i  <- cummax(seq_along(value)*from)
  cv <- cumsum(value*cummax(from))  
  cv - c(0,0,cv[-length(cv)])[i+1] 
}

d <- c(0,0,0,1,3,4,5,-1,2,3,-5,8,0,0,-2,-3,3,5,0,0,0,-1,-1,-1,-1)

all(sum_from(d,d==0)==c(0,0,0,1,4,8,13,12,14,17,12,20,0,0,-2,-5,-2,3,0,0,0,-1,-2,-3,-4))

结果匹配:

> all(sum_from(d,d==0)==c(0,0,0,1,4,8,13,12,14,17,12,20,0,0,-2,-5,-2,3,0,0,0,-1,-2,-3,-4))
[1] TRUE
> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接