创建随机数的向量(在运行时未知的向量的大小)

时间:2011-10-24 19:38:11

标签: r

我正在编写蒙特卡罗模拟,应该给用户一些灵活性。因此,我希望用户能够指定 模拟运行前随机数的具体概率分布。但是,此时用户不知道 需要多少随机数。

我的想法是从用户那里获得一个调用对象,创建一个随机数,然后根据需要在内部创建尽可能多的随机数。然而, 除了一个循环我不能得到任何其他解决方案,但感觉这是因为我错过了一些东西。基本上,我有 两个问题:

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

1 个答案:

答案 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