高效创建向量编码求和另一个向量的位置权重

Efficient create vector encoding summed position-weight of another vector

假设我有一个向量 v 并想创建另一个相同长度的向量 p 来编码 v 中每个位置的总位置权重(和 0 v 中的 0)。例如,对于 v = c(0,1,3,0,1),我得到 p = c(0, 2, 11, 0, 16)。换句话说,p 中的第 i 个元素(非 0)变为 v[i]*i 加上 p 中的前一个元素(非 0)。

我想出了一个方法,但它看起来很丑,我担心它不是很 time/memory 有效 - 我需要在巨大的向量上执行此操作。有什么改进的想法吗?

fun <- function(v){ 
  res <- NULL
      s = 0
      for(i in 1:length(v)){   
        ifelse(v[i] == 0, res[i] <- 0, {res[i] <- v[i]*i + s; s <- res[i]}) 
      }
      return(res)
}

然后:

> fun(c(0,1,3,0,1))
[1]  0  2 11  0 16

更新:

如何反转此函数的输出,即从 c(0,2,11,0,16) 返回到 c(0,1,3,0,1)?

一种方法是在将向量乘以位置编号的同时获得 v 的累加和。零将保持不变,其余的将正确计算。最后,我们可以将该向量乘以由 1 和 0 组成的变换向量,以强制强制要求的零值:

cumsum(v*seq_along(v))*+(!!v)
[1]  0  2 11  0 16

为了可读性,我们还可以写出:

cumsum(v * seq_along(v)) * as.integer(as.logical(v))

更新

试试这个反转:

w <- as.logical(r)
r[w] <- c(r[w][1], diff(r[w]))
r / seq_along(r)
[1] 0 1 3 0 1