【问题标题】:Efficient create vector encoding summed position-weight of another vector高效创建向量编码另一个向量的总位置权重
【发布时间】:2016-05-22 20:06:12
【问题描述】:

假设我有一个向量v,并想创建另一个长度相同的向量p,它编码v 中每个位置的总位置权重(v 中的 0 代表 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)
}

然后:

> 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) ?

【问题讨论】:

    标签: r vector sum position


    【解决方案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
    

    【讨论】:

    • 如此紧凑!你能解释一下,*+(!!v) 在做什么吗?
    • 相当于as.integer(as.logical(v))
    • 你是双重的
    • 谢谢您,非常高兴您将更新移至链接的帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 2019-05-24
    • 2016-08-18
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多