Skip to contents

weightflow 1.3.1 (in development)

New features

  • step_round(method = "balanced") takes formula, balancing on the calibration design rather than on the crossed cells of by.

  • step_model_calibration() and step_pseudoweight() take by, fitting and calibrating one domain at a time.

  • step_cre() takes n_groups, so the equal-representation target comes from the design and not from the responding sample, and rescale_previous for a previous wave whose population differs from the current one.

  • jackknife_weights() takes groups and seed, for a delete-a-group jackknife, and max_replicates, which stops a run before it builds more replicates than intended.

  • ci_type and df on the estimation entry points, for Student t intervals when the design degrees of freedom are few.

  • print() on a bootstrap object reports the Monte Carlo error of its standard errors.

Bug fixes

  • A reference_sample() kept its weights in positional order: reordering or subsetting its rows misaligned them silently. They now travel with the rows.

  • Warnings and diagnostics across the pseudo-weighting, panel, trimming and calibration steps now fire where they were silent, stop firing on sound models, and state what a variance assumes about a reference survey. In particular a non-probability recipe is no longer accepted in silence when it adjusts nothing, pseudo-weights twice, or is exported to survey as if it had a sampling design. Report values are escaped in the HTML.

Documentation

  • The non-probability article was rewritten around the multipurpose-calibration argument: what one weight for many variables costs, why a flexible working model is needed, and the rank ceiling on the number of control totals a linear in-sample model can carry. The rotating-panel, longitudinal-panel, composite-estimation and quick-start articles were rebuilt around the same figures.

  • Vignette figures now ship as standalone .svg files embedded as data URIs. Inline SVG did not survive the HTML post-processing: re-parsing the rendered page converts attribute names to lower case, which is correct for HTML but fatal for SVG (viewBox becomes viewbox), and a figure with a relative width and no explicit height collapsed to zero height. A data URI is a single attribute value and is copied verbatim.

weightflow 1.3.0

CRAN release: 2026-09-11

New features

  • Rotating and pure panels. panel_design() reads the unit x wave structure and the rotation calendar – and, given a cluster, the overlap at the cluster level too, which is the one the rotation calendar describes (the unit-level figure is that overlap net of within-household churn); panel_merge() builds the longitudinal file; panel_pr() and step_panel_overlap() apply the panel-selection probability; step_attrition() is the panel-facing nonresponse adjustment and takes the full argument list of step_nonresponse(), crossfit included; and step_longitudinal() / step_cross_sectional() declare which weight a recipe is building.

  • Net change with a coordinated variance. wave_bootstrap() and wave_jackknife() resample PSUs coordinately across waves, so the sample overlap shows up as covariance instead of being ignored. change_estimate() (with change_mean() / change_total(), absolute or relative, optionally by domain), level_estimate() and panel_estimate(contrast = ) read the estimates off those replicates. Both engines take lonely_psu as bootstrap_weights() does, because a stratum with a single PSU contributes no variance to a change either; the collapse map is built over all the waves at once so the replicate pairing survives it.

  • Chained production: wave_step(), wave_carry(), wave_contrast(). One period at a time, as an office actually publishes: each run leaves a compact carry that the next one needs, and wave_contrast() estimates any linear combination over a chain (a rolling quarter, an annual average) from the saved carries alone.

  • Composite (regression composite) estimation: step_cre(). The MR1/MR2 estimator of the Canadian LFS and Uruguay’s ECH, including the equal-representation constraints across rotation groups, with Zhat re-estimated inside every replicate. The step reports the quality of the wave-to-wave link it depends on – the overlap rate, the births, and how many non-birth units failed to link – and warns when that failure rate gets high, because a broken linkage key attenuates the estimated change rather than announcing itself.

  • Gross flows. transition_matrix(), boot_transition() and boot_flows() give the weighted flow between states across waves, as conditional or joint distributions and as population totals with standard errors and net flows.

  • A declarative estimation grammar. step_domain(), step_filter(), step_estimate() and collect_estimates() run over a saved replicate object, so the expensive replicate build happens once and many estimates are read off it. Units whose domain value is missing are reported rather than quietly dropped, so it is visible when the cells will not add up to the overall figure. Every verb of the statistic DSL validates its arguments against the wave data, because a replicate object will put a standard error and a confidence interval on whatever number it is handed: an estimand must give one numeric or logical value per unit (so prop() takes a condition, prop(status == "unemployed"), and refuses a factor rather than averaging its integer codes), p in quantile(var, p) must be a probability in [0, 1] (0.5, not 50), level must be a proportion, and ratio(num, den) is taken over the domain where both are observed – matching survey::svyratio(na.rm = TRUE) exactly – rather than dropping the missing rows of each sum independently. A domain column may not be named after one of the result table’s own columns.

  • report_panel(), a self-contained HTML quality report for a panel run, and new panel alerts (PN-01, PN-02, PN-06, PN-07, PN-08) plus an alert when a nonresponse adjustment stops preserving the eligible total.

  • Exact multinomial PSU resampling is the default in the panel engines (resample = "multinom"): the per-stratum resample counts sum to m_h, which removes an ~8-10% inflation of the composite change SE seen in simulation. Within a stratum the PSUs are ordered by how many waves they appear in, so the units that carry the overlap get the exactly-coordinated draws and the answer does not depend on which PSU ids happen to rotate out.

  • Smaller additions: bounds and calfun for step_model_calibration(), step_trim_calibrated() after a model-calibration step, and refit_steps to choose which steps are re-run per replicate.

  • Four new vignettes: Rotating panels, Pure panels, Coordinated replication and Composite estimation. The change variance is now also validated against an analytic estimator from a different family (Berger and Priam 2016, via ReGenesees::svyDelta()), with the reference values frozen in the test suite.

Bug fixes

These are fixes against 1.2.0 as published. The panel layer is new in this release, so nothing about it appears here: what it does and what it checks is described under New features.

  • Response-propensity models could diverge under production design weights: a binomial GLM reads the prior weights as the number of trials, so large design weights started the fit at the separation boundary and the fitted propensities collapsed. Model weights are now normalized to mean 1 wherever a weighted binomial model is fitted, which leaves the estimates invariant.

  • Recipe files are safe to exchange. read_recipe() accepts only a whitelist of data-manipulation calls in the conditions and formulas a recipe stores, unless allow_code = TRUE; before, a hand-edited condition still ran on the first prep(). And write_recipe() no longer serializes a population = data frame value by value: it is stored as a descriptor and asked back through references =, as reference_sample() already was.

  • Adjustment cells are keyed unambiguously. A by value containing the " | " separator, or equal to the "(missing)" sentinel, used to collapse two different cells into one – with the wrong adjustment factor for both, and the “cell with no respondents” alert suppressed because the empty half was absorbed by the full one.

  • Two publication gates that failed open are closed: disclosure_risk() silently skipped cells with a missing value or a non-positive median weight, leaving those units out of the screen for weight dominance, and as_sae_input() rated both a missing-domain area and a zero-variance domain as publishable.

  • step_round("preserve_total") breaks ties in the fractional part at random rather than by row order, which was moving mass systematically towards whatever the file was sorted by while reporting the grand total as preserved. Call set.seed() before prep() for a reproducible result, as method = "balanced" already required.

  • The model-assisted and propensity steps are steadier under cross-fitting: whether a y_model() is a regression or a classification is decided once over the whole sample instead of inside each fold (and an explicit family is respected), propensities at the 0/1 boundary warn instead of being clamped in silence, and a fold whose training set has only respondents says so rather than failing inside the model engine.

  • The HTML reports describe the active weights, negatives included, in the weight-distribution card and the matching Status check; a column name containing a space no longer aborts the whole report; and the trimming note names the direction the weight total moved when the bounds could not be met.

  • boot_total() warns that the two-phase total variance is conservative, which it was silently before, and the wave engines reject NA or blank in strata / psu, as bootstrap_weights() has since 1.2.0 – those rows paste into one design key and were resampled as a single pseudo-PSU, understating the variance.

  • Stricter validation and robustness fixes for degenerate and edge-case inputs across the cascade, trimming and the auxiliary outputs, each with a regression test.

weightflow 1.2.0

CRAN release: 2026-08-30

New features

  • Two-phase (double) sampling. step_subsample() records a second phase and the bootstrap returns the variance split into its two components (V = V1 + V2).
  • Non-probability samples. step_pseudoweight() (pseudo-weighting, mass imputation and doubly robust estimators), step_nr_sensitivity() for nonignorable nonresponse, and data_defect() for the Meng (2018) view.
  • Calibrate to a reference survey with reference_sample(), propagating the reference’s own sampling error.
  • Recipes as files. write_recipe() / read_recipe() serialize the method (not the data) to a versionable YAML manifest.
  • Confidentiality and hand-off. collect_replicate_weights(scramble = TRUE), disclosure_risk(), and as_sae_input() for small-area models.
  • Quality control. weighting_alerts() / has_alerts() as a single programmatic channel, domain_summary(min_n_eff = ) as an explicit publication gate, and stable ids on every step.
  • Finite-population correction (fpc) and t / percentile confidence intervals in the replicate estimators.

Bug fixes

  • Cells for by-based steps are now built over the units still active, so units dropped earlier no longer raise spurious (missing) cells.
  • Behaviour change: the mean estimators and replicate-weight exports keep active negative weights (a valid GREG output), matching the totals estimators and survey.
  • Stricter, earlier argument validation across the step constructors and estimators, plus robustness fixes for malformed and edge-case inputs, each with a regression test.
  • Documentation: ?weightflow-concepts (argument correspondence with survey) and ?weightflow-alerts (the alert catalogue).

weightflow 1.1.0

CRAN release: 2026-08-19

New features

Bug fixes and documentation

  • Robustness and correctness fixes for edge cases in the cascade, the replicate variance and the HTML report, each covered by a regression test.
  • Help pages reviewed and rewritten, with estimator formulas in the details.

weightflow 1.0.0

CRAN release: 2026-08-04

New features

  • Nonresponse by calibration (step_nonresponse(method = "calibration")) and unweighted propensity models (weight_model = FALSE).
  • Trimmed calibration (step_trim_calibrated()): trim calibrated weights into an absolute interval while preserving the calibration totals.
  • Tidy control totals that disagree on N now reconcile instead of failing, with a message naming the rescaling.
  • Lonely-PSU handling and parallelism in bootstrap_weights() and jackknife_weights(), and a redistribute argument for step_trim_weights().
  • report_weighting() becomes a full methodological quality report (GSBPM 5.6 / ESS style), with a narrative mode, a per-domain reliability card and new charts.

Bug fixes

  • Cross-fitting no longer errors in a fresh session, step_trim_weights() now trims negative weights, and the report’s before/after scatter is reproducible.

weightflow 0.2.0

CRAN release: 2026-07-22

New features

  • Tidy population totals for step_calibrate(), alongside the classic margins/totals inputs.
  • Domain (partitioned) calibration (by) and the exponential (raking) distance (calfun = "raking") for linear calibration.
  • Delete-a-PSU jackknife variance, recipe-aware like the bootstrap.
  • Machine-learning response propensities (CART, random forest, xgboost) with k-fold cross-fitting, ridge (penalized) calibration, and Potter MSE-optimal trimming.
  • Quality alerts in prep(), an R-indicator of response representativity, and a weight-distribution summary in the report.
  • Subsampling more than one person per household (n_selected), external consistency totals for model calibration (x_totals), and a new vignette on preparing the sample.

Bug fixes

  • The optional machine-learning engines now run single-threaded by default, for reproducibility and to respect CRAN core limits.
  • report_weighting() flags calibration steps that did not converge.
  • step_calibrate(equal_within_cluster = TRUE) now implements the genuine Lemaitre-Dufour (1987) integrative method.

weightflow 0.1.0

CRAN release: 2026-06-30

First release. The weighting cascade as a declarative recipe: