Создать вектор случайных чисел (размер вектора неизвестен во время выполнения) - PullRequest
5 голосов
/ 24 октября 2011

Я программирую симуляцию Монте-Карло, которая должна дать пользователю достаточно гибкости. Следовательно, я хочу, чтобы пользователь мог указать конкретное распределение вероятностей случайных чисел перед запуском моделирования. Тем не менее, в настоящее время это не известно пользователю сколько нужно случайных чисел.

Моя идея теперь состоит в том, чтобы получить объект вызова от пользователя, который создает ОДНО случайное число, а затем создать столько случайных чисел, сколько необходимо для внутреннего использования. Тем не мение, кроме цикла, я не могу заставить работать какое-то другое решение, но у меня такое ощущение, что это из-за того, что я что-то упустил. Так что в основном у меня есть два вопроса:

1) Хороша ли идея с call-объектом? Я все еще работаю над проектом, поэтому я могу изменить настройки, но мне нужен очень интуитивный решение для пользователя.

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 Ответ

5 голосов
/ 24 октября 2011

Я думаю, что более идиотский способ сделать это - взять функцию 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 о том, что аргумент first для функции 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...