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构造相比,您不会注意到性能会提高。