我们在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个观测值。
答案 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.但我的感觉是它已足够。