Skip to contents

execute() signals five conditions when a design cannot be realized as written. Each is a classed condition carrying a payload, so it can be caught and inspected rather than only read. They are reported once per stage per distinct finding, not once per capped pool and not once per replicate.

Details

A pool holding fewer units than the stage asks for is selected whole, which makes the design non-self-weighting. execute() reports this once per stage for each distinct finding, however many pools capped, however many parent pools the stage ran inside, and however many replicates ran. Which condition you get depends on what happened, not on which part of the package noticed:

samplyr_warning_size_capped

Some pools ran short. The stage left units behind in the pools it did not exhaust.

samplyr_warning_census

The stage selected every unit available in the pools it executed, so it contributes no sampling variance. This is a claim about the stage: above the first stage those pools are the ones a sampled ancestor supplied, and the design as a whole is a census only if every stage is.

samplyr_warning_nominal_cap

A random-size method asked for more units than the pool holds. Clamping every chance at one caps the target the stage aims at. It does not select that many units, and the realized size usually lands below the cap.

samplyr_warning_poisson_shortfall

A pps_poisson pool resolved to an expectation more than 5% below what it could have reached, because dominant units saturated at probability 1. Measured against the reachable target, so a pool whose target the population already reduced is charged only for the further reduction saturation caused. See draw().

samplyr_message_allocation_capped

A feasible allocation was redistributed past a saturated stratum. A message, not a warning: nothing went wrong, and simulation loops can silence it with suppressMessages().

Every condition carries stage, an operation naming the detected event, and a payload of aggregated detail. Payload fields mean the same thing wherever the event was detected:

pool_keys

The pools affected, qualified by their parent, so a stratum capping inside three clusters reports three pools rather than one.

n_capped, n_pools

Pools affected, out of pools executed.

n_requested

Units the stage asked for.

n_actual

Units selected.

n_available

Units the stage could have reached.

n_reachable

The target after any population bound, which is what a pps_poisson shortfall is measured against.

n_expected

The resolved expectation of a random-size stage.

n_clipped

Units whose computed chance exceeded one. Units taken by an explicit certainty_size/certainty_prop rule sit at one by instruction and are not counted here.

n_moved

Units redistributed by an allocation method.

n_replicates, varied

How many replicates reported this finding, and whether they reported it identically. When varied is TRUE the pool list is the union across those replicates while the counts describe one of them, and the printed message says so.

Replicates are classified before they are merged, so a replicated execution whose replicates reach genuinely different outcomes reports each one. A design that exhausts its clusters in some replicates and merely runs short in others emits both samplyr_warning_census and samplyr_warning_size_capped, each naming only the pools that produced it. The count of conditions tracks distinct findings, not replicate count.

A field the event does not record is NA, never zero.

frame_digest defaults to "summary", so the ordinary way to read capping is the capped column of frame_summary(sample, detail = "pool"). It compares the executable target with the pool population, so a random-size method realizing below its target is never reported as capped. Reading a digest against a design that does not record the stage leaves capped as NA where a shortfall appears, because which of the two it is cannot be told without the design.

capped marks pools that could not supply the target they were given, so it agrees with samplyr_warning_size_capped pool for pool. It does not mark a stratum whose target an allocation method had already reduced to the stratum population: the digest records the post-cap target, and the two are equal by the time the pool is written. Read the conditions for allocation capping and for a stage census. The column reports what selection could not deliver.

Under frame_digest = "none" there is no digest to read and the condition is the only record. Capturing it needs a calling handler, because tryCatch() unwinds and loses the sample, suppressWarnings() loses the payload, and rlang::catch_cnd() loses the sample:

capped <- NULL
sample <- withCallingHandlers(
  design |> execute(frame, seed = 1, frame_digest = "none"),
  samplyr_warning_size_capped = function(w) {
    capped <<- w$payload$pool_keys
    invokeRestart("muffleWarning")
  }
)

See also

execute() which raises them, frame_summary() whose capped column is the ordinary way to read capping, validate_frame() to catch frame problems before executing

Other execution: execute(), rotation_program(), validate_frame()