Use inverse transform sampling for the categorical draw. Validate a finite nonnegative probability vector, allowing only a small rounding tolerance in its total, then compare a single uniform draw with the cumulative probabilities:
sim1 <- function(p) {
if (!is.numeric(p) || length(p) == 0L ||
any(!is.finite(p)) || any(p < 0) ||
abs(sum(p) - 1) > 1e-12) {
stop("p must be a nonempty finite probability vector")
}
p <- p / sum(p)
cumulative <- cumsum(p)
cumulative[length(p)] <- 1
u <- runif(1)
as.integer(which(u < cumulative)[1L])
}The returned value is when falls in the interval between the previous cumulative sum and the th one. That interval has length , so the output has the required probabilities. Strict comparison skips zero-probability categories even if a simulated uniform value equals an interval boundary. Exactly one call to
runif(1) is made. Articles by others on the same topic
There are currently no matching articles.