2010-11-23 27 views
0

假設我有兩個向量ba。後者的組成部分(a)幾乎總是零,只有少數幾個。具有R中另一個向量的分量函數的稀疏向量的分量乘積

如果我想計算的成分之積和一個逐個分量的功能(如EXP)的B,我可以做

a*exp(b) 

然而,對於的那些大部分零個組件,所述評價exp對b的相應組件將是一種浪費。

我想知道在這種情況下,是否可以在R中更高效地編程?或者沒有必要改變。謝謝!

回答

2

要擴大迪文的回答,並把它的評論,只要保持0的軌道,並添加回在瑣碎的答案:

## Dummy data 
set.seed(1) 
a <- sample(0:10, 100, replace = TRUE) 
b <- runif(100) 

## something to hold results 
out <- numeric(length(a)) 
## the computations you *want* to do 
want <- !a==0 
## fill in the wanted answers 
out[want] <- a[want] * exp(b[want]) 

其中給出正確的結果:

> all.equal(out, a * exp(b)) 
[1] TRUE 

如果你想,你可以把它包裝成一個函數:

myFun <- function(a, b) { 
    out <- numeric(length(a)) 
    want <- !a==0 
    out[want] <- a[want] * exp(b[want]) 
    return(out) 
} 

T母雞用它

> all.equal(out, myFun(a, b)) 
[1] TRUE 

沒有什麼是比直接使用a * exp(b)更有效。 *exp()都是矢量化的,因此運行速度非常快,比迄今爲止各種答案中使用的任何預訂保留措施快得多。

您是否需要書記解決方案取決於您的功能(Q中示例中的exp())在計算方面的費用。嘗試兩種方法在一個小樣本上,並評估時間(使用system.time()),看看是否值得額外的努力做子集跟蹤0.

0

您可以通過爲任何您認爲是浪費的情況編制一個測試索引來實現這一目標。如果函數的時間比EXP昂貴的,它可能會有所作爲:

a[ !b==0 ]*exp(b[!b==0]) 

也承認,有陷阱,以測試與數字模式的平等。你可能想看看zapsmall和all.equal作爲替代品,這取決於真正的問題是什麼。

> 3/10 == 0.1*3 
[1] FALSE 
+2

謝謝DWIN!但是[!b == 0] * exp(b [!b == 0])會給出* exp(b)的不同結果。 – Tim 2010-11-23 03:09:12

+0

-1它是'a',主要是0. – 2010-11-23 09:59:25

+0

是的。神經元串擾。應該是[!a == 0] * exp(b [!a == 0]),但是仍然不能提供完整的矢量。 – 2010-11-24 02:08:48

1

到迪文的建議類似:

> n <- 1e5 
> nonzero <- .01 
> b <- rnorm(n) 
> a <- rep(0, n) 
> a[1:(n*nonzero)] <- rnorm(n*nonzero) 
> 
> system.time(replicate(100, { 
+     c <- a*exp(b) 
+    })) 
    user  system  elapsed 
    1.19  0.05  1.23 
> system.time(replicate(100, { 
+     zero <- a < .Machine$double.eps 
+     c <- a 
+     c[!zero] <- a[!zero]*exp(b[!zero]) 
+    })) 
    user  system  elapsed 
    0.42  0.08  0.50 
2

只是代替你的表達:

ifelse(a==0,0,a*exp(b)) 

我會感到驚訝,如果這做了性能改進,不過,由於R解釋,運行ifelse的開銷可能比浪費exp調用更差。