An executed sample can carry a frame digest: a compact record of the
frames, selection pools, resolved selection chances, and allocation
that each stage encountered at execution time. frame_summary()
turns that record into documented tibbles, so the structure of the
selection remains intelligible after the original frame has gone
away.
Arguments
- x
A
tbl_sampleproduced byexecute()that carries a frame digest, or asampling_designrestored byread_design()whose file was written from an executed sample: the execution receipt carries the digest, so a shipped design file supports next-wave planning without the frame or the sample. Withframe, any completesampling_designwill do.- frame
Optional frame to preview the design against: one data frame for a shared hierarchy, or an ordered list of stage registers, as
execute()takes them. When supplied, the report describes what the design would do on that frame rather than what it did, and no sampling is performed: no random numbers are drawn and.Random.seedis left as it was. See "Previewing a design" below.- ...
These dots are for future extensions and must be empty.
stagesand the arguments after it follow..., so each must be named exactly: the singularstageis reported rather than prefix-matched.- stages
An integer vector of stage numbers to report, or
NULL(default) for all recorded stages.- scope
Denominator basis for population sizes and take rates. With
"eligible"(default), denominators cover the units that were eligible for the recorded execution. With"universe", denominators are reported only where the digest covers the full population hierarchy. Denominators that the recorded scope cannot support areNA, never invented.- detail
Resolution of the report:
"stage"(one row per stage),"pool"(one row per selection pool and realization), or"unit"(one row per population unit, only for stages that retained a unit-level representation).
Value
A tibble. The scope column always states how complete the
underlying representation is ("eligible", "universe",
"conditional", "partial", or "unknown").
For detail = "stage", one row per stage with stage,
unit_level, scope, chance_kind, probabilities, storage,
n_pools, N, n_target, n_expected, n_realized, and
take_rate.
For detail = "pool", one row per selection pool and realization
with stage, pool_id, replicate, parent_unit, any stratum
label columns, N, n_target, n_expected, n_realized, scope,
chance_status, chance (the constant per-unit chance where one
applies, NA otherwise), take_rate, and capped. replicate is
1 for an ordinary execution. In a replicated execution, pool_id
identifies the shared structural pool and the key is stage,
pool_id, and replicate. Stratum columns of stages that do not
use them are NA.
capped marks a pool that held fewer units than the stage asked
for. It is always FALSE on a random-size stage, which realizes a
count around its target rather than running out of units, and NA
where the target fell short but the design recording which kind of
stage it is was not available.
capped is a statement about selection: it marks a pool that could
not supply the executable target it was given. A stratum whose
target an allocation method had already reduced to the stratum
population is therefore FALSE, because n_target records the
post-redistribution target and the pool delivered it in full. That
event is reported by execute() instead, as a message of class
samplyr_message_allocation_capped or, when the stage ends up
taking everything within reach, samplyr_warning_census. The
digest does not retain the pre-redistribution allocation target,
so the distinction is available from the conditions rather than
from this table.
For detail = "unit", one row per population unit of each stage
that stored units, with stage, pool_id, unit_id,
unit_order, chance, is_certainty, n_descendants,
is_selected, and n_hits. Stages that stored only a constant or a
chance distribution contribute no rows. Requesting such a stage
explicitly is an error rather than a silently empty result.
Details
take_rate is n_realized / N. It is a take rate, not an
inclusion probability: for unequal-probability designs the two
differ by design. chance_kind states what the recorded chances
mean: first-order inclusion probabilities for without-replacement
stages, expected hits for with-replacement stages. probabilities
states how well the stage's method honors them: "exact" when the
recorded chances equal the design's true first-order chances,
"approximate" when the method treats them as a target achieved to
a documented approximation ("pps_sps", "pps_pareto", and
registered methods declared probabilities = "approximate"), and
NA for digests recorded before the field existed.
The allocation columns distinguish three quantities:
n_targetis the nominal count requested by the design, before execution-time population limits, probability capping, or certainty overflow. For a random-size design specified withfrac, it isN * fracand may be fractional.n_expectedis the sum of the final resolved inclusion probabilities or expected hits. It can differ fromn_targetafter probability capping or other feasibility adjustments.n_realizedis the number of selected units or occurrences in the realization.
These quantities often coincide for a feasible fixed-size design.
For Bernoulli and Poisson sampling, n_realized varies around
n_expected. n_target still records the nominal requested
expectation. It is NA only when no nominal count can be recovered,
for example from an older digest or a method with unspecified target
semantics.
Stage detail stays compact for replicated executions: a common
per-replicate realized allocation is reported, while varying
n_realized and take_rate are NA. Pool detail is the drill-down:
it returns one row per pool and replicate with scalar realized
values, even when all replicates happen to agree. Population and
design columns repeat across those rows, so select one replicate
before using a replicated pool table as a next-wave planning frame.
Unit detail spans the stacked replicates:
is_selected marks units selected in at least one replicate and
n_hits counts occurrences across all replicates, so a
without-replacement unit can show n_hits > 1. The per-replicate
trace is the replicate column of the digest's selected units.
A replicated multi-stage execution records only the stage prefix
shared by every replicate: later-stage pools hang off each
replicate's own selected parents, so those stages are not part of
the manifest and frame_summary() says so.
A digest whose sample was modified after execution (rows, weights, or design columns changed) is reported as invalidated and refused: a stale digest is worse than no digest.
Previewing a design
With frame, the report is resolved from the design and the frame
without drawing: every selection pool is enumerated and every chance
resolved, but nothing is selected. This makes an allocation
inspectable before it is committed to, and lets a design restored from
a file be checked against next wave's frame.
Because there is no realization, n_realized and take_rate are NA,
as are is_selected and n_hits at detail = "unit". Every other
column, and the shape of the table, is the same as for a recorded
digest, so the two are directly comparable.
At detail = "pool", a stage below a clustered stage reports one pool
per candidate parent, and its n_target is what that stage would
take given that parent is selected. This is what field planning
needs: how many households to list in a selected cluster.
At detail = "stage", those conditional pools are rolled up weighted
by the probability each parent is selected, so the row reports the
expected size of the stage rather than the total across every
candidate. A design taking 10 of 100 clusters and 5 units in each
reports n_target = 50 at stage 2, not 500. For a design whose stage
sizes are fixed this is also the exact size. Where per-parent takes
vary (frac over unequal clusters, for instance) the realized size
varies around it.
Not every design can be previewed. A stage below a with-replacement
stage is refused, because the number of times each parent is hit is
random, and so is a design whose non-final stage selects elements,
which cannot be executed either
(samplyr_error_exante_unsupported, samplyr_error_stage_parent_id).
See also
Other diagnostics:
design_effect,
joint_expectation(),
sample-columns,
summary.tbl_sample(),
varcomp.tbl_sample()
Examples
frame <- data.frame(
id = 1:20,
stratum = rep(c("A", "B"), each = 10)
)
# Fixed-size allocation: target, expectation, and realization agree.
fixed <- sampling_design() |>
stratify_by(stratum) |>
draw(n = 3) |>
execute(frame, seed = 42)
frame_summary(fixed)
#> # A tibble: 1 × 12
#> stage unit_level scope chance_kind probabilities storage n_pools N
#> <int> <chr> <chr> <chr> <chr> <chr> <int> <dbl>
#> 1 1 element universe inclusion_proba… exact consta… 2 20
#> # ℹ 4 more variables: n_target <dbl>, n_expected <dbl>, n_realized <dbl>,
#> # take_rate <dbl>
allocation_columns <- c(
"stage", "pool_id", "replicate", "stratum", "N",
"n_target", "n_expected", "n_realized", "take_rate"
)
fixed_pools <- frame_summary(fixed, detail = "pool")
print(fixed_pools[allocation_columns], width = Inf)
#> # A tibble: 2 × 9
#> stage pool_id replicate stratum N n_target n_expected n_realized take_rate
#> <int> <int> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 1 A 10 3 3 3 0.3
#> 2 1 2 1 B 10 3 3 3 0.3
# The same report before anything is drawn: pass the frame instead.
# Nothing is selected and no random numbers are used, so an allocation
# can be checked before it is committed to.
planned <- sampling_design() |>
stratify_by(stratum) |>
draw(n = 3)
frame_summary(planned, frame)
#> # A tibble: 1 × 12
#> stage unit_level scope chance_kind probabilities storage n_pools N
#> <int> <chr> <chr> <chr> <chr> <chr> <int> <dbl>
#> 1 1 element universe inclusion_proba… exact consta… 2 20
#> # ℹ 4 more variables: n_target <dbl>, n_expected <dbl>, n_realized <dbl>,
#> # take_rate <dbl>
print(
frame_summary(planned, frame, detail = "pool")[allocation_columns],
width = Inf
)
#> # A tibble: 2 × 9
#> stage pool_id replicate stratum N n_target n_expected n_realized take_rate
#> <int> <int> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 1 A 10 3 3 NA NA
#> 2 1 2 1 B 10 3 3 NA NA
# Random-size allocation: one scalar row per pool and replicate.
random_sample <- sampling_design() |>
stratify_by(stratum) |>
draw(frac = 0.3, method = "bernoulli", on_empty = "silent") |>
execute(frame, seed = 42, reps = 3)
random_pools <- frame_summary(random_sample, detail = "pool")
print(random_pools[allocation_columns], width = Inf)
#> # A tibble: 6 × 9
#> stage pool_id replicate stratum N n_target n_expected n_realized take_rate
#> <int> <int> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 1 A 10 3 3 5 0.5
#> 2 1 1 2 A 10 3 3 3 0.3
#> 3 1 1 3 A 10 3 3 1 0.1
#> 4 1 2 1 B 10 3 3 4 0.4
#> 5 1 2 2 B 10 3 3 0 0
#> 6 1 2 3 B 10 3 3 1 0.1
# Probability capping can make the resolved expectation smaller
# than the nominal target.
pps_frame <- data.frame(id = 1:20, mos = c(100, rep(1, 19)))
capped <- sampling_design() |>
draw(n = 5, method = "pps_poisson", mos = mos, on_empty = "silent") |>
execute(pps_frame, seed = 42)
#> Warning: Stage 1: PPS Poisson expected sample size fell short of the reachable target in
#> 1 pool.
#> ✖ Reachable 5 units, expected 1.8.
#> ✖ 1 unit has an inclusion probability clipped at 1.
#> ℹ Handle dominant units explicitly with `certainty_size` or `certainty_prop`.
#> ℹ See `?selection-methods` for the "pps_poisson" contract.
capped_pool <- frame_summary(capped, detail = "pool")
print(
capped_pool[c("N", "n_target", "n_expected", "n_realized")],
width = Inf
)
#> # A tibble: 1 × 4
#> N n_target n_expected n_realized
#> <dbl> <dbl> <dbl> <dbl>
#> 1 20 5 1.80 1
# Full digests support anonymous unit-level inspection.
full <- sampling_design() |>
draw(n = 5, method = "pps_brewer", mos = id) |>
execute(frame, seed = 42, frame_digest = "full")
head(frame_summary(full, detail = "unit"))
#> # A tibble: 6 × 9
#> stage pool_id unit_id unit_order chance is_certainty n_descendants is_selected
#> <int> <int> <int> <int> <dbl> <lgl> <int> <lgl>
#> 1 1 1 1 1 0.0238 FALSE NA FALSE
#> 2 1 1 2 2 0.0476 FALSE NA FALSE
#> 3 1 1 3 3 0.0714 FALSE NA FALSE
#> 4 1 1 4 4 0.0952 FALSE NA FALSE
#> 5 1 1 5 5 0.119 FALSE NA FALSE
#> 6 1 1 6 6 0.143 FALSE NA FALSE
#> # ℹ 1 more variable: n_hits <int>