Resolves both designs on the same register, without drawing, and reports where they agree and where they part. The allocation level asks whether the two designs form the same units and pools at every stage and give each pool the same take. The probability level asks whether they give every unit the same first-order inclusion probability.
Arguments
- x, y
Two
sampling_designobjects, each with a completedraw()on every stage. A design restored withread_design()is one. An executed sample is refused.- frame
The register both designs are resolved on, a data frame.
- ...
Must be empty. Arguments after it are matched by exact name.
- key
A bare column of
frameidentifying the population unit. It must be unique and have no missing values.- level
What to compare,
"allocation"(default) or"probabilities".- atol, rtol
Absolute and relative tolerances. Two values
aandbagree whenabs(a - b) <= atol + rtol * max(abs(a), abs(b)). They apply to expected pool sizes and to probabilities. Requested takes are compared exactly.- allow_approximate
Passed to
exante_probabilities()at the probability level. Both designs must then have the same probability tier.
Value
An object of class samplyr_design_comparison, a list with
verdict:"agree","differ"or"unresolved".level: the level compared.probability_quality: at the probability level, the tier both designs share,"exact"or"approximate", andNAotherwise. With"approximate", what agrees is the targets of the methods, which they meet only to an approximation, and the print says so.checks: a tibble with one row per check, withstage(NAfor a check of the whole design),check,status("agree","differ","unresolved"or"not_run") anddetail.pools: at the allocation level, one row per pool the two designs share, withstage,pool_key,N,n_target_x,n_target_y,n_expected_x,n_expected_yandagree.units: at the probability level, one row per register row, with the key column,probability_x,probability_y,abs_diff,rel_diffandagree.specification: two rows per stage the designs both have, withstage,aspect("method"or"mos"),x,yandstatus. The status is"same","differ", or for two measures of size in different columns,"proportional"when one is a constant multiple of the other on every row offrame. It does not enter the verdict.
The verdict is "differ" when any check differs, "unresolved" when
none differs but one could not run, and "agree" otherwise.
Details
The allocation level ignores the selection method and the measure of
size. A design written with the default srswor can therefore stand for a
requirement of a protocol, such as five districts in every region, and be
compared with a design that draws the districts with probability
proportional to size. The probability level compares the designs as they
would select.
At either level, the method and the measure of size of each stage are listed side by side, outside the verdict. Two designs can agree on their probabilities with different methods, and a requirement written with the default method differs from the design that meets it by construction, so the list describes the two specifications without judging them.
Allocation
Pools are matched by the frame rows they hold, never by the names of the
stratification variables. stratify_by(province, urban_rural) and
stratify_by(urban_rural) under a province parent form the same pools,
and cluster_by(region, province) and cluster_by(province) form the
same units when province ids are nested in regions. When the units of a
stage differ, its pools and takes are not compared. When the pools
differ, the check names the pools of x that y splits or merges.
Two designs on the same frame see the same pools, so a comparison cannot
find a category the frame lacks. A province without urban EAs forms one
pool in both designs, and they agree. execute() and validate_frame()
report such a parent with samplyr_message_absent_strata when the
requirement names its strata in an explicit n table.
Probabilities
Units with probability zero in one design and positive in the other are a coverage difference and are counted on their own. A relative difference is computed only where both probabilities are positive. A verdict of agreement says that the first-order inclusion probabilities agree on this frame. It says nothing about joint inclusion probabilities, variances or the selection algorithm, which can differ between designs that agree.
What is not compared
A check that cannot run is reported as "unresolved" with the reason,
never as agreement: designs with different numbers of stages, a stage below
a with-replacement stage, methods whose probabilities are unknown, mixed
probability tiers, and a stage that sets on_capped = "error" on a frame
with short pools.
See also
exante_probabilities() for the probabilities of one design,
frame_summary() for the pools of one design
Other diagnostics:
design_effect,
frame_summary(),
joint_expectation(),
sample_columns,
summary.tbl_sample(),
varcomp.tbl_sample()
Examples
frame <- data.frame(
region = rep(c("North", "South", "East"), each = 40),
district = rep(sprintf("d%02d", 1:12), each = 10),
size = rep(c(5, 9, 4, 7, 6, 8, 3, 9, 5, 6, 7, 4), each = 10),
household = 1:120
)
# A protocol asks for two districts in every region. A sketch design
# states that requirement in the grammar, with the default method.
requirement <- sampling_design() |>
stratify_by(region) |>
cluster_by(district) |>
draw(n = 2)
# The design as written draws districts with PPS.
written <- sampling_design() |>
stratify_by(region) |>
cluster_by(district) |>
draw(n = 2, method = "pps_brewer", mos = size)
compare_designs(requirement, written, frame, key = household)
#> ── Design comparison ───────────────────────────────────────────────────────────
#> Allocations agree on this frame.
#>
#> ✔ Stage 1 units: agree. 12 units.
#> ✔ Stage 1 pools: agree. 3 pools.
#> ✔ Stage 1 targets: agree. Every pool takes the same. x takes 6 units in all, y 6.
#>
#> Methods and measures of size, outside the verdict:
#> ℹ Stage 1 method: srswor in x, pps_brewer in y.
#> ℹ Stage 1 measure of size: none in x, size in y.
# A design that shares four districts across the regions departs from it.
shared <- sampling_design() |>
stratify_by(region, alloc = "equal") |>
cluster_by(district) |>
draw(n = 4, method = "pps_brewer", mos = size)
compare_designs(requirement, shared, frame, key = household)
#> ── Design comparison ───────────────────────────────────────────────────────────
#> Allocations differ on this frame.
#>
#> ✔ Stage 1 units: agree. 12 units.
#> ✔ Stage 1 pools: agree. 3 pools.
#> ✖ Stage 1 targets: differ. 2 of 3 pools differ ("North", "South"). x takes 6 units in all, y 4.
#>
#> Methods and measures of size, outside the verdict:
#> ℹ Stage 1 method: srswor in x, pps_brewer in y.
#> ℹ Stage 1 measure of size: none in x, size in y.
# A design and its own file give the same probabilities.
path <- tempfile(fileext = ".json")
write_design(written, path)
compare_designs(
written, read_design(path), frame,
key = household, level = "probabilities"
)
#> ── Design comparison ───────────────────────────────────────────────────────────
#> First-order inclusion probabilities agree on this frame.
#>
#> ✔ Probabilities: agree. 120 units, 0 differ. Largest absolute difference 0, largest relative difference 0.
#>
#> Methods and measures of size, outside the verdict:
#> ✔ Stage 1 method: pps_brewer in both.
#> ✔ Stage 1 measure of size: size in both.