2016-02-11 21 views
2

假設我有一個矢量v和想創建相同長度的另一矢量p編碼的每個位置的在v(和0相加的位置權重爲0的中v )。例如,對於v = c(0,1,3,0,1),我得到p = c(0,2,11,0,16)。換句話說,p(即不是0)中的第i個元素變成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 

UPDATE:

如何扭轉這個函數的輸出,即回到C(0,1,3,0,1)從c(0,2,11,0,16)?

回答

3

一種方法是在將矢量與位置編號相乘的同時獲得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 
+0

A so c ompact!你能解釋一下,'* +(!! v)'在做什麼? – user3375672

+0

它相當於'as.integer(as.logical(v))' –

+0

你是雙重沾染 –