如何跳过一个步骤并增加R中for循环中的迭代次数

时间:2016-08-16 18:34:48

标签: r loops for-loop

我们在for loop中有一个很大的R用于模拟各种数据,对于某些迭代,数据生成的方式是数量在循环内变为0,这是不可取的,我们应该跳过那个数据生成步骤。但与此同时,由于这种跳过,我们还需要将迭代次数增加一步,否则我们将观察到的观察数量少于所需数量。

例如,在运行以下代码时,我们在迭代1,8和9中得到 z = 0

rm(list=ls())
n <- 10
z <- NULL
for(i in 1:n){
  set.seed(i)
  a <- rbinom(1,1,0.5)
  b <- rbinom(1,1,0.5)
  z[i] <- a+b
}
z
[1] 0 1 1 1 1 2 1 0 0 1

我们希望跳过这些步骤,以便我们没有任何 z = 0 ,但我们也想要一个长度为10的向量 z 。可以在很多步骤中完成方法。但我特别想看到的是当遇到 z = 0 时我们如何停止迭代并跳过当前步骤并进入下一步,最终获得 z的10个观测值

1 个答案:

答案 0 :(得分:4)

通常我们通过while循环执行此操作,因为事先不知道所需的迭代次数。

n <- 10L
z <- integer(n)
m <- 1L; i <- 0L
while (m <= n) {
  set.seed(i)
  z_i <- sum(rbinom(2L, 1, 0.5))
  if (z_i > 0L)  {z[m] <- z_i; m <- m + 1L}
  i <- i + 1L
  }

输出:

z
# [1] 1 1 1 1 1 2 1 1 1 1

i
# [1] 14

因此,我们抽样14次,其中4次为0,其余10次保留。

更高效的矢量化方法

set.seed(0)
n <- 10L
z <- rbinom(n, 1, 0.5) + rbinom(n, 1, 0.5)
m <- length(z <- z[z > 0L])  ## filtered samples
p <- m / n  ## estimated success probability
k <- round(1.5 * (n - m) / p)   ## further number of samples to ensure successful (n - m) non-zero samples
z_more <- rbinom(k, 1, 0.5) + rbinom(k, 1, 0.5)
z <- c(z, z_more[which(z_more > 0)[seq_len(n - m)]])

这里使用了一些几何分布的概率论。最初,我们会对n个样本进行抽样,保留m个样本。因此,接受样本成功的估计概率为p <- m/n。根据几何分布理论,平均而言,我们需要至少1/p个样本来观察成功。因此,我们至少应该(n-m)/p次采样(n-m)以期望1.5成功。 (n-m)只是一个通胀因素。通过抽样1.5倍的样本,我们希望能够确保p成功。

根据大数定律,当n很大时,n的估计更精确。因此,这种方法对于大{{1}}来说是稳定的。

如果您认为1.5不够大,请使用2或3.但我的感觉是它已足够。