As @Frank suggested, a while
loop is your best approach, though I don't think if
is the best way to go.
NN <- 100
kk <- 100
lam <- 4
draws <- matrix(rpois(kk * NN, lam), ncol = NN)
while (!all(idx <- apply(draws, 2, all))){
draws[ , nidx] <- matrix(rpois(sum(nidx <- !idx) * NN, lam), ncol = NN)
}
Then to finish:
colMeans(draws)
An alternative is to use replicate
:
colMeans(replicate(NN, {draws <- rpois(kk, lam)
while (!all(draws)) draws <- rpois(kk, lam)
draws}))
My quick benchmarks suggest this latter is actually faster.
Even more savvy would be to simply eliminate all bad draws from the start (and essentially draw from the truncated distribution).
We know that the probability of getting 0 on a given draw is exp(-lambda)
, so if we invert uniform draws on (exp(-lambda), 1]
, we'll be set:
colMeans(matrix(qpois(runif(kk * NN, min = exp(-lam)), lam), ncol = NN))
Also competitive with this is to use data.table
:
library(data.table)
grps <- rep(1:NN, each = kk)
data.table(qpois(runif(kk * NN, min = exp(-lam)), lam))[ , mean(V1), grps]