2017-10-11 86 views
0

我需要向量化Rrt t分佈採樣器中的非中心性參數。然而,當我給:向量化R中的t分佈

rt(2, df = 1, ncp = c(1,2)) 

我得到

Warning message: 
In if (is.na(ncp)) { : 
    the condition has length > 1 and only the first element will be used 

其他功能,如rbinomrgamma沒有類似的問題(在rbinomprob參數可以被矢量一樣可以規模參數的rgamma)。

有沒有辦法做到這一點(沒有循環)?

回答

2

可以使用sapply

sapply(1:3, function(x) rt(2, df = 1, ncp = x)) 
#   [,1]  [,2]  [,3] 
# [1,] 0.3881308 1.905535 1.781836 
# [2,] -0.7950962 2.905824 1.633683 

每一列中所得到的矩陣對應於ncp不同的值。

1

您可以使用lapply,sapplyvapply具有類似的性能。 lapplyvapplysapply快一點,因爲sapplylapply的包裝,它試圖使結果更漂亮/更簡單。

microbenchmark::microbenchmark(
    vapply(c(1,2, 3), function(x) rt(2, df = 1, ncp=x), numeric(2L)), 
    sapply(1:3, function(x) rt(2, df = 1, ncp = x)), 
    lapply(1:3, function(x) rt(2, df = 1, ncp = x)), 
    vec.rt(2, df=1, ncp=1:3)) 

#Unit: microseconds 
# expr min  lq  mean median  uq  max neval cld 
#vapply 27.121 37.6095 51.61055 39.8825 42.4570 1226.199 100 a 
#sapply 51.438 58.1725 72.89417 60.9150 63.4850 1255.270 100 ab 
#lapply 29.484 34.0670 59.78256 36.8160 39.0755 2326.401 100 ab 
#vec.rt 95.511 101.6985 106.15785 105.0770 108.2700 189.312 100 b 
+1

感謝您的比較!要記住的一點是'sapply'是'lapply'的封裝,並且有一個額外的簡化步驟,將輸出轉換爲矩陣,這就增加了它的運行時間。 –

3

另一種選擇是用Vectorize創建一個僞向量化函數。例如,向量化rt關於ncp說法,你可以這樣做:

vec.rt <- Vectorize(rt, "ncp") 

該功能可用於在您之前嘗試過的代碼。

vec.rt(2, df=1, ncp=c(1,2)) 
#   [,1]  [,2] 
# [1,] 3.314060 5.300499 
# [2,] 2.423883 1.299248 

注意,這不會給你一個真正的矢量功能,也不會sapplylapply。所有這些函數都在內部使用循環,因此與簡潔明瞭的for構造相比,您不會注意到性能會提高。