用for循环输出填充矩阵

时间:2019-04-18 19:13:33

标签: r for-loop matrix

我想用包含rbinom函数的for循环模拟的数据填充矩阵。该循环执行rbinom函数100次,因此每次运行都会产生不同的结果。但是,我找不到将这些结果汇总到矩阵中以进行进一步分析的方法。将for循环分配给对象时,该对象在环境中显示为空,因此无法在矩阵中使用。 (“数据”必须是向量类型,为“ NULL”。)

在for循环中不包含rbinom函数时,可以将其分配给一个对象,并且可以使用矩阵中的输出。但是,每一列都包含完全相同的数字序列。当只运行包含rbinom函数的for循环时,我得到了不同的序列,因为它运行rbinom函数的次数是100次而不是1次。我只是不知道如何将循环集成到te矩阵中。

我有两段代码:

n = 100                                                               
size = 7
loop_vill <- for (i in 1:100) {
  print(rbinom(n=n, size=size, prob=0.75))        #working for-loop                 
}


vill <- rbinom(n=n, size=size, prob=0.75)


sim_data_vill <- matrix(data=vill, nrow=length(loop_vill), ncol=100)   
#creates a matrix in which all columns are exact copies, should be solved 
when able to use outputs of loop_vill.

sim_data_vill

在调用sim_data_vill时,(逻辑上)它包含100行和100列的矩阵,所有列均相同。但是,我希望看到一个矩阵,其中所有列都不同(因此每次都包含新运行的rbinom函数的输出)。

1 个答案:

答案 0 :(得分:0)

据我所见,您好,您遇到了一些问题。

  1. 您当前未在每一列上运行for循环({1中仅保存了1个向量)
  2. 您没有遍历vill

现在有几种方法可以实现您想要的。 (滚动到最后一个示例以获取有效的方法)

方法1:rbinom

根据您的想法,我们可以使用For loop。最好的方法是先保存一个空矩阵,然后用for loop

填充
for loop

现在这可以工作,但是有点慢,并且需要跳3行代码作为仿真部分的代码!

方法2:nsim <- 100 #how many rbinom are w n <- 100000 size = 7 prob = 0.75 sim_data_vill_for_loop <- matrix(ncol = nsim, nrow = n) for(i in seq(nsim)) #iterate from 1 to nsim sim_data_vill_for_loop[, i] <- rbinom(n, size = size, prob = prob) #fill in 1 column at a time

我们可以使用众多类似apply的函数之一来删除for循环和预先分配的矩阵。 apply是其中一种功能。这将大量的三行代码减少为:

replicate

嗯..很短,但是我们可以做得更好吗?实际上多次运行诸如sim_data_vill_apply <- replicate(nsim, rbinom(n, size, prob)) 之类的函数可能会相当缓慢且成本很高。

方法3:使用向量化函数(非常快)

在R语言中进行编程时,您会听到耳语(或叫喊)的一句话是rbinom。基本上,调用函数会产生开销,如果使用向量化函数,则调用一次,将确保您只产生一次开销,而不是多次。 R中的所有分布函数(例如vectorized)都被向量化。那么,如果我们一次完成全部模拟该怎么办?

rbinom

因此,让我们快速检查一下与使用sim_data_vill_vectorized_functions <- matrix(rbinom(nsim * n, size, prob), ncol = nsim, nrow = n, byrow = FALSE) #perform all simulations in 1 rbinom call, and fill in 1 matrix. for loop相比,速度要快多少。可以使用microbenchmark软件包来完成此操作:

apply

看中间时间,一次运行所有模拟大约需要60毫秒。比使用for循环更快。因此,在这里并没有什么大不了的,但是在其他情况下则可能会。 (将library(microbenchmark) microbenchmark(for_loop = { sim_data_vill_for_loop <- matrix(ncol = nsim, nrow = n) for(i in seq(nsim)) #iterate from 1 to nsim sim_data_vill_for_loop[, i] <- rbinom(n, size = size, prob = prob) #fill in 1 column at a time }, apply = { sim_data_vill_apply <- replicate(nsim, rbinom(n, size, prob)) }, vectorized = { sim_data_vill_vectorized <- matrix(rbinom(nsim * n, size = size, prob = prob), ncol = nsim, nrow = n, byrow = FALSE) } ) Unit: milliseconds expr min lq mean median uq max neval for_loop 751.6121 792.5585 837.5512 812.7034 848.2479 1058.4144 100 apply 752.4156 781.3419 837.5626 803.7456 901.6601 1154.0365 100 vectorized 696.9429 720.2255 757.7248 737.6323 765.3453 921.3982 100 n取反,您将开始发现开销在计算中占很大的比例。)

即使不是什么大问题,在所有情况下,还是都倾向于使用矢量化计算来使它们弹出,以使代码更具可读性,并避免已经在实现的代码中进行优化的不必要的瓶颈。