我正在编写蒙特卡罗模拟,应该给用户一些灵活性。因此,我希望用户能够指定 模拟运行前随机数的具体概率分布。但是,此时用户不知道 需要多少随机数。
我的想法是从用户那里获得一个调用对象,创建一个随机数,然后根据需要在内部创建尽可能多的随机数。然而, 除了一个循环我不能得到任何其他解决方案,但感觉这是因为我错过了一些东西。基本上,我有 两个问题:
1)调用对象的想法是好的吗?我仍在研究这个项目,所以我仍然可以改变设置,但我需要一个非常直观的 为用户提供解决方案。
2)如果这是一个好主意,是否有更优雅的方法将随机数扩展为大小为nrMCS的向量?
我们举个例子:
#That's what I would get from the user with my current set-up:
rnd_call <- call("rnorm", 1, mean=0.1, sd=0.01)
#To create nrMCS random numbers, that's my best shot so far:
nrMCS <- 100
rnd_vec <- as.numeric(nrMCS)
for (i in 1:nrMCS){rnd_vec[i] <- eval(rnd_call)}
rnd_vec
[1] 0.09695170 0.11752132 0.11548925 0.11205948 0.10657986 0.12017120 0.09518435
...
#Question: Is there are more elegant way?
#I tried the following, but it fails for certain reasons
rep(eval(rnd_call), nrMCS) #DOES NOT WORK: Repeats ONE random number
[1] 0.1105464 0.1105464 0.1105464 0.1105464 0.1105464 0.1105464 0.1105464 0.1105464
...
eval(rep(rnd_call, nrMCS)) #DOES NOT WORK
Error in rnorm(1, mean = 0.1, sd = 0.01, rnorm, 1, mean = 0.1, sd = 0.01, :
formal argument "mean" matched by multiple actual arguments
答案 0 :(得分:5)
我认为更为惯用的方法是采用r*
函数和参数列表。每当你可以避免调用eval
时,你应该。像这样:
rnd_fun <- rnorm
rnd_args <- list(mean=0.1,sd=0.01)
nrMCS <- 100
rnd_vec <- do.call(rnd_fun,c(list(n=nrMCS),rnd_args))
(这依赖于R中的约定,r*
(随机偏差生成器)函数的第一个参数总是n
,即所需的偏差数。 。)
此外,使用rnd_fun
调用n=nrMCS
一次通常比调用nrMCS
次更有效...
library(rbenchmark)
nrMCS <- 10000
benchmark(single_call=do.call(rnd_fun,c(list(n=nrMCS),rnd_args)),
mult_call=replicate(nrMCS,do.call(rnd_fun,c(list(n=1),rnd_args))))
test replications elapsed relative user.self sys.self
2 mult_call 100 11.135 91.27049 11.084 0.004
1 single_call 100 0.122 1.00000 0.080 0.036