step_calibrate(). In addition to the classic
margins/totals inputs (which keep working
unchanged), calibration targets can now be given as tidy data frames,
paired with the new count argument that names the counts
column:
step_select_within(). A new
n_selected argument (a single number or an unquoted column)
works alongside n_eligible for simple random selection of a
subsample: the weight is multiplied by
n_eligible / n_selected (equivalent to
prob = n_selected/n_eligible). It defaults to 1, so
selecting a single person keeps working unchanged.step_model_calibration(). The totals of the
x_formula auxiliaries can now be supplied through the new
x_totals argument, in the same two shapes as
step_calibrate(method = "linear"): the tidy format (a named
list with a data frame per factor, paired with count, and a
single number per continuous total) or the classic model-matrix vector.
This covers the common case where the X control totals come from an
external source rather than from the frame; the auxiliaries then need to
be present only in the sample, not in population. When
x_totals is NULL (default) the X totals are
still taken from population, so existing code is unchanged.
population remains required, because the model-assisted
block predicts each outcome over every population unit. Model
calibration now also warns, like linear calibration, when the achieved
totals do not fully satisfy the constraints (collinear or
ill-conditioned auxiliaries).jackknife_weights() builds jackknife replicate weights by
deleting one PSU at a time and re-running the whole recipe on each
replicate, so the replicate weights carry the variability of every
adjustment. It is the stratified jackknife (JKn) with
strata/psu, the unstratified jackknife (JK1)
with strata = NULL, and the delete-one-unit jackknife with
psu = NULL. jackknife_estimate() (plus
jack_total() / jack_mean()) summarise a
statistic with the JKn variance and match survey’s
replicate jackknife for totals. as_svrepdesign() now also
accepts a jackknife object, so the recipe-aware replicate weights flow
into survey/srvyr for any estimand and any
domain.step_calibrate(). A new by argument
names a domain (partition) column; the weights are then calibrated
independently within each domain, each to its own
totals (partitioned / domain calibration). The tidy totals carry the
domain as a column, and a continuous total becomes a data frame
domain, value (one total per domain); the domain variable
does not go in the formula/margins. It composes with
calfun, bounds, penalty and
equal_within_cluster, applied within each domain, and
reproduces every domain’s benchmarks. by = NULL (default)
calibrates globally, unchanged.step_calibrate(method = "linear").
calfun now also accepts "raking" (the
multiplicative distance g = exp(u)), next to "linear" and
"logit". It keeps the calibration weights positive without
needing explicit bounds and still satisfies the constraints
exactly, and works on mixed categorical and continuous auxiliaries as
well as with the integrative option (equal_within_cluster,
one weight per cluster). Matches
survey::calibrate(calfun = "raking").summary() and report_weighting() now report
the R-indicator (Schouten, Cobben & Bethlehem), R = 1 - 2*S, with S
the design-weighted standard deviation of the estimated response
propensities over the eligible sample: closer to 1 means a more
representative response and less nonresponse-bias risk. The report also
shows the unconditional partial R-indicators by auxiliary, pointing to
which variable drives the lack of representativity. It is computed on
the auxiliaries of the nonresponse step and needs no new function or
user action; recipes without a nonresponse step are unaffected.xgboost) for
step_nonresponse() and
step_model_calibration().crossfit) to
estimate each unit out-of-sample, with folds formed by cluster to avoid
leakage.penalty) to keep weights stable with many
auxiliaries.method = "potter"), a data-driven cutoff.prep().
prep() now computes non-fatal quality alerts and stores
them on the prepped object ($alerts) and per step: negative
or sub-1 weights and g-factors outside the Deville-Särndal bounds
[0.1, 10] after calibration, small adjustment cells (new
min_cell_n, default 30, following Kalton and
Flores-Cervantes 2003) and excessive adjustment factors (new
max_factor, default 2.5). Alerts always appear in the HTML
report; set prep(warn = TRUE) to also raise them as R
warnings.report_weighting(). The report gains a “Weight
distribution (final)” summary (min, p1, median, p99, max, max/min ratio,
and counts of negative, sub-1 and extreme weights) and a per-step
“Quality alerts” block.disposition column in the
sample_one example data. A single factor with the
full field disposition (eligible respondent, eligible nonrespondent,
household nonresponse, ineligible, unknown eligibility), recoded from
the existing indicator columns (which are kept). It gives a tidy
single-column view of the dispositions and can be used directly via
logical conditions in the steps.The optional machine-learning engines
(engine = "forest" via ranger,
engine = "boost" via xgboost) now run single-threaded by
default, for reproducibility and to respect CRAN’s check limits. Set
options(weightflow.num_threads = n) to use n
threads.
report_weighting() now flags calibration steps that
did not converge. When a raking, linear or bounded calibration stops
without satisfying the requested totals (the same condition that already
prints a console warning), the HTML report shows a “Did not converge”
alert on that step and no longer states that the step converged.
Previously the report always reported convergence, regardless of the
actual result.
step_calibrate(equal_within_cluster = TRUE) now
implements the genuine Lemaitre-Dufour (1987) integrative method: each
unit’s auxiliaries are replaced by their household mean before a
person-level calibration, so the per-household penalty scales with
household size. This matches survey’s
calibrate(aggregate.stage = ) (Vanderhoeft 2001),
ReGenesees and Statistics Canada’s GES. The previous implementation used
a household-level distance (summed auxiliaries, uniform per-household
penalty), a different (non-standard) method. Integrative-calibration
weights will change; totals are still met exactly and weights remain
constant within household.
First release.
A dependency-free, pipeable API to compute survey weights from design
base weights through a chain of hierarchical adjustment stages. Build a
recipe lazily, estimate it with prep(), and extract the
weights with collect_weights(). Separating define
from apply makes the whole process reproducible and auditable,
and lets the bootstrap re-run the entire cascade on each replicate.
step_unknown_eligibility(): redistribute the weight of
unknown-eligibility cases to the known ones (person- or household-level
via cluster).step_drop_ineligible(): zero out out-of-scope
units.step_select_within(): within-household selection
(unequal prob or equal n_eligible).step_nonresponse(): weighting-class or propensity
adjustment, at the person or household level
(cluster).step_calibrate(): raking, post-stratification and
linear/GREG calibration, with bounded (Deville-Särndal) and integrative
(one weight per household) cluster options.step_model_calibration(): Wu-Sitter model
calibration.step_trim(), step_trim_weights(),
step_round(), step_rescale(): trimming,
rounding and rescaling.step_assert(): quality checkpoint (deff, weight ratio,
effective n).summary(), plot() and
weight_factors() for per-stage diagnostics.design_effect() for the Kish design effect and
effective sample size.report_weighting() builds a self-contained HTML report
with a pipeline diagram, the variables used, per-stage summaries and
per-step visuals.bootstrap_weights() resamples PSUs within strata
(Rao-Wu rescaling) and re-applies the whole recipe on each replicate, so
the replicate weights carry the variability of every adjustment.boot_mean() and boot_total() return the
estimate, standard error and CI.as_svydesign(), as_svrepdesign() and
collect_replicate_weights() bridge to the
survey and srvyr packages for design-based
inference.population,
sample_survey (take-all roster) and sample_one
(multistage select-one design), all with stratum, PSU and design
weight.