在 R 中使用 lapply 从二项分布创建样本时出错
Error in creating samples from the binomial distributions with lapply in R
为了执行蒙特卡洛模拟,我需要 5000 个二项分布和正态分布样本,样本大小不同(20,30 和 50)。我的代码与正态分布(以及我测试过的其他分布)完美配合,但与二项式分布不兼容。它说我没有指定 prob 参数,但我指定了。
它给我这个错误:
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)
}
这是我在 Whosebug 中的第一个问题,如果我解释得不够好,请告诉我,我会更正。谢谢。
为什么不简化流程,例如像这样:
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))))
这为每个 rnorm 和 rbinom 提供了 3 个列表(n 为 20、30 和 50)。
您的代码有一些错误。首先,您对 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
为了执行蒙特卡洛模拟,我需要 5000 个二项分布和正态分布样本,样本大小不同(20,30 和 50)。我的代码与正态分布(以及我测试过的其他分布)完美配合,但与二项式分布不兼容。它说我没有指定 prob 参数,但我指定了。
它给我这个错误:
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)
}
这是我在 Whosebug 中的第一个问题,如果我解释得不够好,请告诉我,我会更正。谢谢。
为什么不简化流程,例如像这样:
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))))
这为每个 rnorm 和 rbinom 提供了 3 个列表(n 为 20、30 和 50)。
您的代码有一些错误。首先,您对 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