Skip to contents

execute() runs a sampling design against one or more data frames, producing a sampled dataset with appropriate weights and metadata.

Usage

execute(
  .data,
  ...,
  stages = NULL,
  seed = NULL,
  panels = NULL,
  panel_stage = NULL,
  small_pool = NULL,
  reps = NULL,
  wave = NULL,
  frame_digest = c("summary", "full", "none")
)

Arguments

.data

A sampling_design object to start a new execution, or a partially executed tbl_sample to continue the remaining stages of its stored design.

...

Data frame(s) to sample from: one frame for a single-stage design or a shared hierarchy, or one frame per stage in stage order. A tbl_sample passed here while .data is a new sampling_design starts a new sampling phase rather than continuing that sample's stages. Ordinary input frames must have unique column names and must not use columns reserved for execution output, such as .weight, .sample_id, .stage, .weight_k, or .fpc_k for stage k. Frames are matched by position, so a name given here is a label. A label resembling an argument below (seedd, or the singular stage, rep, panel) is refused, because those arguments follow ... and are matched exactly.

A single unnamed list of data frames is the same call, for code that already holds the frames, such as a loop over registers or replay_design(). Mixing it with separate frames is refused. Names inside the list are frame labels, so a misspelled argument must be written outside it to be reported as one. See frame_input_grammar.

stages

Integer vector of the stages to execute, or NULL (default) for all remaining stages. From a sampling_design it must start at stage 1, so an operational workflow can stop after its first contiguous batch of stages. From a partial tbl_sample it must start at the next unexecuted stage.

seed

Integer random seed, between -.Machine$integer.max and .Machine$integer.max. A given seed leaves the session's random number stream untouched. With seed = NULL, selection draws from the session stream and advances it, and replay_design() refuses the resulting sample because its receipt cannot reproduce it.

panels

Rotation groups (panels) to partition the sample into, as an integer count, a rotation schedule (a data frame with integer panel and wave columns and an optional logical active column), or an svyplan_schedule from svyplan::design_schedule(). The output gains a .panel column, and only a sample drawn with a schedule can be materialized by wave. Default NULL means no panels. Cannot be combined with reps, or redeclared on a sample that already carries an assignment. panel_assignment describes the assignment and the schedules.

panel_stage

Stage whose selected units are assigned to panels, as a single stage number, or NULL (the default) for the first executed stage. Accepted only alongside panels, and the stage must be one the execution completes. Later stages inherit their ancestor's panel, so assigning below stage 1 rotates units inside parents that stay in the survey. panel_assignment explains what that changes, including how it can bias estimates over time.

small_pool

What to do when a rotation schedule would leave a pool with no unit to activate at some wave. "error" (the default, reached by NULL) refuses the assignment, and "permanent" activates those units at every wave and warns with samplyr_warning_panel_small_pool. Meaningful only with a schedule. See panel_assignment.

reps

Integer number of independent replicate samples to draw (>= 2), or NULL (default) for a single sample. The replicates are stacked in one tbl_sample with a .replicate column (integer 1 through reps). Their seeds are drawn from seed, since consecutive seeds do not give independent draws in R, and recorded in the replicate_seeds element of the sample's metadata, so replicate r alone is execute(design, frame, seed = replicate_seeds[r]). Cannot be combined with panels or with stages that use permanent random numbers. as_svrepdesign(type = "random_groups") estimates variance from the spread of the replicates, for any selection method.

wave

Integer wave of a scheduled master to materialize, or NULL (default). execute(master, wave = t) activates the panels the stored schedule declares active at t and compounds the exact activation factor into .weight. A wave selects units the master already assigned, under the policy the master froze, so it takes no frame and none of seed, stages, panels, panel_stage, small_pool, reps or frame_digest. Each is refused by name rather than ignored.

frame_digest

Controls the frame digest, a compact execution manifest recorded with the sample and read by frame_summary(). The digest never affects selection, weights, or estimation. "summary" (default) records selection pools, resolved chances (exact for cluster stages, constant or quantile-compressed for element stages), and the selected-unit trace. "full" keeps exact per-unit chances for element stages too. "none" records no digest and skips trace construction for minimum execution overhead.

When one universe frame feeds every stage, later stages also record the pools their realization never reached, with chances resolved from the design (chance_status = "design_resolved"), which gives complete universe denominators without the frame. A stage continuation extends the digest of its input sample, and an input without a valid digest yields none. Replicates share one population structure with their own traces. A replicated multi-stage execution keeps only the stage prefix shared by all replicates, with status "partial", as frame_summary() describes. Replicated multi-phase and replicated-continuation executions do not record a digest yet.

A digest is not anonymized. Its selection trace keeps the identifiers of realized units (frame-derived cluster keys or row indices), even under "summary", so treat the sample and any serialized execution receipt as potentially confidential.

Value

A tbl_sample: a data frame subclass carrying the selected rows, the design that produced them, and generated columns recording the selection. Those are .sample_id, .weight, the per-stage .weight_k, .fpc_k, .draw_k and .certainty_k, .zone_1 and .pair_1 for a zoned certainty plan, and .replicate or .panel when reps or panels is used. sample_columns documents what each one holds.

Details

Multi-stage with a single frame

For hierarchical data where all stages are in one frame, pass that one frame. It must contain all clustering variables and represent the stage hierarchy correctly. Lower-stage IDs may repeat across different parents, because samplyr resolves them using the full ancestry from earlier stages.

Multi-stage with one frame per stage

When each stage has its own register, pass one frame per stage. The number of frames schedules the stages: one frame is a shared hierarchy covering all of them, one frame per stage gives each its own, and any other count is samplyr_error_frame_count.

Registers are supplied whole. Each is restricted to the units its parent stage selected, and the variables earlier stages introduced are carried onto it, so a lower register need not be pre-filtered or duplicate the upper stages' stratification columns. A register may legitimately omit a carried stratum, but one whose own copy of it disagrees is an error.

Before any stage draws, every later stage is checked on all the units it could reach, as validate_frame() checks them, so a defect in a unit the seed happens to skip is still refused.

This form, the single-hierarchy form, and the stage continuation below run the same stage transition. Under one shared RNG stream, and with stages given on every intermediate call, all three draw the same sample.

Partial execution (operational sampling)

stages executes only the stages named, returning a partial tbl_sample. Fieldwork then produces the next stage's frame, and passing the partial sample back as .data continues the same design. frame_input_grammar states how a continuation reads its frame, when it asks for stages, and how it differs from starting a new phase on a sample.

Multi-phase sampling

execute(new_design, previous_sample) starts a new phase, with the earlier sample as the frame of a new design rather than .data carrying unexecuted stages. Weights compound across phases, and as_svydesign() exports this path through survey::twophase().

Weights

.weight is the product of the per-stage weights and of the phase weights across phases. sample_columns gives the formulas.

When a design cannot be realized as written

A pool holding fewer units than the stage asks for is selected whole, which makes the design non-self-weighting. execute() reports this and four related outcomes as classed conditions carrying a payload. With the default digest, the capped column of frame_summary(sample, detail = "pool") shows capping after the fact. execution_conditions gives the five classes, their payload fields, and how to capture one when no digest is kept.

See also

sampling_design() for creating designs, frame_input_grammar for the frame forms every verb accepts, sample_columns for what the generated columns hold, execution_conditions for what execute() signals when a design cannot be realized as written, get_design() for extracting metadata

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

Examples

# Basic SRS execution
sample <- sampling_design() |>
  draw(n = 100) |>
  execute(bfa_eas, seed = 1234)
sample
#> # A tbl_sample: 100 × 18
#> # Sampling:     1 stage | 100/44,570 units
#> # Weights:      445.7 [445.7, 445.7]
#>    ea_id region      province commune urban_rural population households area_km2
#>  * <int> <fct>       <fct>    <fct>   <fct>            <int>      <int>    <dbl>
#>  1  6473 Sahel       Soum     Koutou… Rural              133         23    19.4 
#>  2  6543 Sahel       Soum     Koutou… Rural              183         32     6.15
#>  3 10735 Sahel       Yagha    Tankou… Rural               36          5    16.7 
#>  4 36151 Centre-Nord Namente… Boulsa  Rural              526         75     3.75
#>  5 10510 Nord        Loroum   Sollé   Rural              239         28     5.45
#>  6 23624 Nord        Yatenga  Senguè… Rural              555         59     8.84
#>  7 33774 Centre-Nord Sanmate… Pissila Rural              857        110     4.94
#>  8  1118 Centre-Nord Namente… Boala   Rural              830        137    10.2 
#>  9 29691 Centre-Oue… Sissili  Bieha   Rural              190         28     8.83
#> 10 10559 Boucle du … Kossi    Sônô    Rural               69         10     8.89
#> # ℹ 90 more rows
#> # ℹ 10 more variables: pop_density <dbl>, longitude <dbl>, latitude <dbl>,
#> #   remoteness <fct>, fieldwork_cost <int>, .weight <dbl>, .sample_id <int>,
#> #   .stage <int>, .weight_1 <dbl>, .fpc_1 <int>

# Stratified execution with proportional allocation
sample <- sampling_design() |>
  stratify_by(region, alloc = "proportional") |>
  draw(n = 300) |>
  execute(bfa_eas, seed = 5789)
table(sample$region)
#> 
#> Boucle du Mouhoun          Cascades            Centre        Centre-Est 
#>                34                17                26                20 
#>       Centre-Nord      Centre-Ouest        Centre-Sud               Est 
#>                23                25                11                37 
#>     Hauts-Bassins              Nord   Plateau-Central             Sahel 
#>                32                20                11                28 
#>         Sud-Ouest 
#>                16 

# Two-stage cluster sample execution
zwe_frame <- zwe_eas |>
  dplyr::mutate(district_hh = sum(households), .by = district)

sample <- sampling_design() |>
  add_stage(label = "Districts") |>
    cluster_by(district) |>
    draw(n = 20, method = "pps_brewer", mos = district_hh) |>
  add_stage(label = "EAs") |>
    draw(n = 10) |>
  execute(zwe_frame, seed = 3)
length(unique(sample$district))  # 20 districts selected
#> [1] 20

# Partial execution: stage 1 only
design <- sampling_design() |>
  add_stage(label = "EAs") |>
    stratify_by(region) |>
    cluster_by(ea_id) |>
    draw(n = 5, method = "pps_brewer", mos = households) |>
  add_stage(label = "Households") |>
    draw(n = 12)

# Execute only stage 1 to get selected EAs
selected_eas <- execute(design, bfa_eas, stages = 1, seed = 2)
nrow(selected_eas)  # Number of selected EAs
#> [1] 65

# Continuation: the listing produced by fieldwork becomes the next frame,
# and the partial sample is passed back as `.data`
listing <- selected_eas |>
  as.data.frame() |>
  dplyr::reframe(hh_id = seq_len(20), .by = ea_id)
sample <- selected_eas |> execute(listing, seed = 43)
nrow(sample)  # 12 households in each selected EA
#> [1] 780

## One frame per stage
# Frames map to stages by position: districts first, then EAs
districts <- dplyr::distinct(zwe_eas, province, district)
two_stage <- sampling_design() |>
  add_stage(label = "Districts") |>
    cluster_by(district) |>
    draw(n = 8) |>
  add_stage(label = "EAs") |>
    draw(n = 3)
sample <- two_stage |> execute(districts, zwe_eas, seed = 424)
length(unique(sample$district))  # 8 districts, 3 EAs each
#> [1] 8

# The same call with the frames held as a list
registers <- list(districts, zwe_eas)
same <- two_stage |> execute(registers, seed = 424)
identical(sample$.sample_id, same$.sample_id)
#> [1] TRUE

## Multi-phase
# The previous phase's sample is the new phase's frame
phase1 <- sampling_design() |>
  draw(n = 200) |>
  execute(bfa_eas, seed = 42)
phase2 <- sampling_design() |>
  draw(n = 50) |>
  execute(phase1, seed = 123)
nrow(phase2)  # weights compound across both phases
#> [1] 50

# Replicated sampling: 5 independent draws
sample <- sampling_design() |>
  draw(n = 100) |>
  execute(bfa_eas, seed = 42, reps = 5)
table(sample$.replicate)  # 100 per replicate
#> 
#>   1   2   3   4   5 
#> 100 100 100 100 100 

# Rotating panel: 4 rotation groups
sample <- sampling_design() |>
  draw(n = 200) |>
  execute(bfa_eas, seed = 1, panels = 4)
table(sample$.panel)  # 50 per panel
#> 
#>  1  2  3  4 
#> 50 50 50 50