在R中矢量化t分布

时间:2017-10-11 13:50:50

标签: r vectorization

我需要对R rt t-distribution采样器中的非中心性参数进行矢量化。但是,当我给出时:

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等其他函数没有类似的问题(即prob中的rbinom参数可以被矢量化,因为rgamma的比例参数可以1}})。

有没有办法做到这一点(没有循环)?

3 个答案:

答案 0 :(得分: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构造相比,您不会注意到任何性能提升。

答案 1 :(得分: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值。

答案 2 :(得分:1)

您可以使用性能相似的lapplysapplyvapplylapplyvapplysapply快一点,因为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