我需要对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
rbinom
或rgamma
等其他函数没有类似的问题(即prob
中的rbinom
参数可以被矢量化,因为rgamma
的比例参数可以1}})。
有没有办法做到这一点(没有循环)?
答案 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
请注意,这不会为您提供真实的矢量化功能,sapply
或lapply
也不会。所有这些函数都在内部使用循环,因此与干净编写的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)
您可以使用性能相似的lapply
,sapply
或vapply
。 lapply
和vapply
比sapply
快一点,因为sapply
是lapply
的包装器,试图使结果更漂亮/更简单。
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