Quick summary
Summarize this blog with AI
Introduction
stats::rbinom(n, size, prob) generates n simulated counts of successes, each from size independent trials with a common success probability prob. The number of simulated experiments and the number of trials per experiment are different arguments. No package named rbinom needs to be loaded.
Tested with R 4.5.1. Run the following code blocks in order. All inputs are included.
State the model before simulating
For a teaching model of ten independent trials with success probability 0.3, the expected count is 3 and the variance is 2.1. A simulated count is not a prediction guaranteed to occur in the next real experiment.
trials <- 10L
probability <- 0.3
expected_mean <- trials * probability
expected_variance <- trials * probability * (1 - probability)
stopifnot(expected_mean == 3, isTRUE(all.equal(expected_variance, 2.1)))
Dependence between trials or changing success probabilities can make a binomial model unsuitable. Sampling without replacement from a small finite population generally calls for a different model, such as a hypergeometric distribution.
Generate repeated experiments reproducibly
Here there are eight simulated experiments, each containing ten trials. Set the seed once at the start and record the RNG settings and R version.
RNGkind("Mersenne-Twister", "Inversion", "Rejection")
set.seed(42)
counts <- stats::rbinom(n = 8, size = trials, prob = probability)
print(counts) # 5 5 2 4 3 3 4 1
stopifnot(length(counts) == 8, all(counts >= 0 & counts <= trials))
set.seed(42)
stopifnot(identical(counts, stats::rbinom(8, trials, probability)))
Setting size to 1 instead produces Bernoulli outcomes, each either zero or one. Resetting the same seed before separate groups reproduces a shared random stream; it does not create independent replications.
Calculate exact probabilities and compare a simulation
Use dbinom for an exact count and pbinom for cumulative probabilities. “At least five” means greater than four, not greater than five.
p_exactly_three <- dbinom(3, size = 10, prob = 0.3)
p_at_least_five <- pbinom(4, size = 10, prob = 0.3, lower.tail = FALSE)
print(round(c(exactly_three = p_exactly_three,
at_least_five = p_at_least_five), 6))
# 0.266828 and 0.150268
stopifnot(isTRUE(all.equal(p_at_least_five, sum(dbinom(5:10, 10, 0.3)))))
set.seed(2026)
simulated <- rbinom(10000, size = 10, prob = 0.3)
print(round(c(mean = mean(simulated), at_least_five = mean(simulated >= 5)), 4))
stopifnot(length(simulated) == 10000)
The simulated summaries approximate model quantities and vary by seed. Use the exact distribution functions when they already answer the question; a simulation is useful for checking understanding or building a larger model.
Keep boundary behavior and scale explicit
Small in-memory simulations are enough to test the model. Validate caller-supplied parameters before allocating a large result.
stopifnot(length(rbinom(0, 10, 0.3)) == 0)
stopifnot(identical(rbinom(3, 0, 0.3), c(0L, 0L, 0L)))
stopifnot(identical(rbinom(3, 10, 0), c(0L, 0L, 0L)))
stopifnot(identical(rbinom(3, 10, 1), c(10L, 10L, 10L)))
valid_size <- function(x) is.numeric(x) && length(x) == 1L &&
!is.na(x) && is.finite(x) && x >= 0 && x == floor(x)
stopifnot(valid_size(10), !valid_size(2.5), !valid_size(NA_real_))
stopifnot(is.finite(probability), probability >= 0, probability <= 1)
For a real workload, estimate output size and measure before introducing parallel workers or disk-backed arrays. A parameter vector can also be recycled across draws; keep scalar size/probability unless varying them is intentional. See continuous versus discrete random sampling for a related distinction.