Ошибка при создании выборок из биномиальных распределений с перекрытием в R

Для выполнения моделирования Монте-Карло мне нужно 5000 выборок биномиального и нормального распределений с разными размерами выборок (20, 30 и 50). Мой код отлично работает с обычным (и другими дистрибутивами, которые я тестировал), но не с биномом. В нем говорится, что я не указывал аргумент вероятности, но я указал.

Это дает мне эту ошибку:

 Error in x(n, ...) : argument "prob" is missing, with no default 

Мой код такой:

distribuicoes <- list(normal = c(rnorm, c(mean = 0, sd=1)), 
    binomial = c(rbinom, c(size = 4, prob = 0.5)))

M <- 5000

as <- function(x,n,...){x(n,...)}

for (j in c(20,30,50)){
    dados <- lapply( distribuicoes, function(FUN,M){replicate(M,as(FUN[[1]],FUN[[2]],n=j))},M)
}

Это мой первый вопрос здесь, в stackoverflow, если я что-то недостаточно хорошо объяснил, дайте мне знать, и я исправлю это. Спасибо.


person rodrigocaet    schedule 18.07.2020    source источник
comment
Ваш код также не работает для rnorm. Попробуйте mean = 100, sd = 100.   -  person Edward    schedule 19.07.2020
comment
Он работает с rnorm, я только что здесь тестировал.   -  person rodrigocaet    schedule 19.07.2020
comment
Вы уверены? Выдает ли случайные числа со средним значением 100 и SD 100? Причина, по которой rnorm не возвращает ошибку, заключается в том, что аргументы имеют значения по умолчанию, а rbinom - нет.   -  person Edward    schedule 19.07.2020
comment
О, теперь я понимаю, это требует только среднего аргумента. Спасибо   -  person rodrigocaet    schedule 19.07.2020


Ответы (2)


В вашем коде есть несколько ошибок. Во-первых, ваше присвоение dados сохранит только последнюю итерацию цикла for. Поэтому, если вы хотите сохранить все итерации, лучше всего определить его как список, а затем назначить результаты каждому элементу с помощью [[]]. Во-вторых (и именно поэтому вы получаете ошибку), вы неправильно передаете именованные аргументы каждому вызову функции (rnorm, rbinom). В-третьих, я думаю, что лучше называть ваши данные следующим образом:

distribuicoes <- list(normal = list(dst=rnorm, args=list(mean=0, sd=1)),
                      binomial=list(dst=rbinom, args=list(size=4, prob=0.5)))

Затем функция as должна использовать do.call, объединяя список аргументов ... вместе с n в один именованный список.

as <- function(x, n, ...){
  args <- as.list(c(n=n, unlist(list(...))))
  do.call(x, args)
  }

Итак, вот последний код. Заменить M на 5000

set.seed(123) # remove this later, just for reproducibility here.
M <- 3        # just to see how the output looks.
n <- c(2,3,5) # to show easily on the screen. Replace with your sizes.

dados <- vector("list", length(n))
for(j in seq_along(n)) {
  dados[[j]] <- lapply(distribuicoes, function(f) {
    replicate(M, as(x=f$dst, n=n[j], f$args)) } )
}

dados

[[1]]
[[1]]$normal
        [,1]    [,2]   [,3]
[1,] -0.5605 1.55871 0.1293
[2,] -0.2302 0.07051 1.7151

[[1]]$binomial
     [,1] [,2] [,3]
[1,]    2    1    1
[2,]    2    3    0


[[2]]
[[2]]$normal
        [,1]    [,2]    [,3]
[1,] -0.4457  0.4008  1.7869
[2,]  1.2241  0.1107  0.4979
[3,]  0.3598 -0.5558 -1.9666

[[2]]$binomial
     [,1] [,2] [,3]
[1,]    3    1    2
[2,]    1    1    2
[3,]    2    2    1


[[3]]
[[3]]$normal
         [,1]    [,2]    [,3]
[1,] -1.08570 -0.8185 -0.1294
[2,] -0.08542  0.6849  0.8867
[3,]  1.07061 -0.3201 -0.1514
[4,] -0.14539 -1.3115  0.3298
[5,] -1.16554 -0.5996 -3.2273

[[3]]$binomial
     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    2    4
[3,]    2    2    3
[4,]    2    3    3
[5,]    1    1    1
person Edward    schedule 19.07.2020

Почему бы вам просто не упростить процесс, например нравится:

lapply(c(20, 30, 50), function(x) list(
    norm=replicate(M, rnorm(x, mean = 0, sd=1)),
    binom=replicate(M, rbinom(x, size = 4, prob = 0.5))))

Это дает вам 3 списка (для n 20, 30 и 50) для каждого rnorm и rbinom.

person user12728748    schedule 18.07.2020
comment
Спасибо за ваш комментарий! Но на самом деле я создал функцию со списком дистрибутивов в качестве входных данных, поэтому я не могу поместить их вручную. - person rodrigocaet; 19.07.2020