R 高效创建向量编码另一个向量的合计位置权重

R 高效创建向量编码另一个向量的合计位置权重,r,vector,sum,position,R,Vector,Sum,Position,假设我有一个向量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) 我想出了一个方法,但它看起来很难看,我担心它的时间/内存效率不高-我需要在巨大的向量上这样做。有改进的想法吗 fun <- function(v){ res <- NULL s = 0

假设我有一个向量
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)

我想出了一个方法,但它看起来很难看,我担心它的时间/内存效率不高-我需要在巨大的向量上这样做。有改进的想法吗

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)
}
更新:


如何反转此函数的输出,即从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

w这么紧凑!你能解释一下,
*+(!!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