pvstackr 0.2.1
This release changes the documentation only. The R code, the computations and the printed output are the same as in 0.2.0.
The help pages, the ten articles and the README are rewritten in plain language and checked against the code, the companion methods preprint and the cited literature.
-
Statements that did not match the package are corrected:
- pvstackr fits a single-level linear regression weighted by the survey weights and reports its fixed effects. A formula with a random-effect term stops
pv_brr_target(),stack_directandstack_psiswith an error. The earlier articles presented a two-level model with a school variance. - The likelihood of each plausible value is survey-weighted, and each row of the stacked data has as its weight the final weight divided by its mean and by the number of plausible values. The earlier text called the likelihood unweighted and gave the row weight as one over the number of plausible values.
- pvstackr runs no part of Pareto smoothed importance sampling:
stack_psistakes importance weights and Pareto k-hat values computed elsewhere. The thresholds of Vehtari et al. (2017, 2024) are now stated apart from pvstackr’s single threshold,psis_k_threshold. - The companion methods paper is cited as its Zenodo preprint (https://doi.org/10.5281/zenodo.22407935). Its stacked fixed-effect point identity is Theorem 4.1, with conditions (R1)–(R5). Coverage results that the preprint does not report are no longer attributed to it; the interval labels (
interval_role,coverage_claim_allowed) are pvstackr’s reporting rule. - The covariance that
pv_brr_target()computes from the replicate weights is called the BRR–Fay replicate covariance, not a sandwich estimator.
- pvstackr fits a single-level linear regression weighted by the survey weights and reports its fixed effects. A formula with a random-effect term stops
The interval label
coverage_claim_allowedis described as what it is: a record of how an interval was built, by pvstackr’s reporting rule. It does not certify the coverage of the interval.The package title and description are rewritten in plain words.
The articles have new titles; their file names and web addresses are unchanged. The website has a “Get started” link to the first article.
The tests that check phrases in the documentation follow the new wording and check the same facts.
pvstackr 0.2.0
Revalidating a legacy target no longer requires its estimates to match bit-for-bit.
pv_revalidate_brr_target()rebuilds the target from the raw inputs and compared every primitive withidentical(), including the weighted least-squares estimates and a hash of them. Those last bits differ between BLAS implementations, so a target built on one machine could not be revalidated on another. Structure, declared inputs, and the input-derived design hash are still compared exactly; the estimates now go through the package’s existing numeric policy (absolute 1e-12, relative 1e-10). A difference large enough to matter still fails closed.Content hashes and validation stamps no longer depend on the R version that wrote them. Both hashed the whole serialization stream, whose fourteen-byte header records the writing R version. The eight-hex content hashes (
design_hash,target_hash, and the fixture digests) are compared fail-closed when a legacy target is revalidated, so that comparison could never succeed across two R versions, and the validation stamps made a saved fit refuse its own accessors after an R upgrade. The header is now excluded from both. Hash values change: content hashes computed by earlier releases will not match the ones this release derives, so a storeddesign_hashfrom 0.1.x or 0.2.0-dev is expected to differ.Validation stamps no longer depend on the R version that wrote them. The stamp hashed the whole serialization stream, whose fourteen-byte header records the writing R version, so a saved fit failed its own stamp when it was read back under a different R version and its accessors refused to return anything. The header is now excluded, and the four stamps – fit, summary, method comparison, and comparison source projection – are portable across R versions and machines. The bundled example fit was regenerated under the corrected scheme.
The bundled brms adapter is now public:
pv_backend_brms_fit_function(),pv_backend_brms_draws_function(), andpv_backend_brms_sampler_diagnostics(). Injecting all three intopv_fit()runs the same fitting, extraction, and diagnostic code the bundled backend runs, so the two routes are one implementation rather than two that have to be kept in step, and any one of the three can be replaced to attach a different engine. The routes are not interchangeable in what they record: an injected fit carries injected engine and diagnostic provenance, and the bundled route additionally checks backend availability before sampling. A reportable injected fit needs all three; an adapter that supplies only a fit and a draws function leaves the sampler evidence incomplete and the fit is blocked.pv_backend_brms_fit_function()now resolves the Stan backend itself when it is reached through an injected adapter, instead of rejecting everypv_control(backend = )value the bundled route would have resolved for it. Cache directories remain the injected adapter’s own responsibility, as the recorded provenance has always said; create the directory first or passcache_dir = NULL. Underbackend = "brms"a supplieddiagnose_functionis still ignored in favour of the bundled sampler record, but the fit now always records that the override was ignored, not only when the override happened to return asamplerelement.A population-level prior (
class = "b"with nocoef) is now expanded onto the individual slope coefficients instead of being refused.stack_directmaterializes the model matrix and fits0 + ..., which turns the intercept into an ordinary column, so passing such a prior through unchanged would have silently widened it to cover the intercept. Expanding it restores the scope the prior had against the original formula. Priors whose scope cannot be reproduced exactly – intercept-class, coefficient-specific, grouped, or opaque – are still refused before the backend runs, and supplying any explicit prior still raises theexplicit_prior_warningreason code.stack_psisnow separates the weight input route, Pareto-k source, and smoothing provenance. Supplied or injected weights can enter the reportable caller-declared external-PSIS route only when the caller records both an external producer and version; this records a declaration, not package verification; otherwise they fail closed, as do raw self-normalized log ratios. Every path records per-PV Kish-style iid weight ESS, its draw-count fraction, and the maximum normalized weight. These are weight-concentration diagnostics, not MCMC ESS,loo::relative_eff(), or a replacement for the immutable Pareto-k gate. Mixed weight routes are rejected rather than silently prioritized. The legacyfallback = "warn"request now emits its scheduled deprecation warning and still behaves as immutable fail-closed"block".New bundled brms backend for the stacked fit:
pv_fit(method = "stack_direct")withpv_control(backend = "brms")now runs without an injectedfit_function/draws_functionpair. The bundled adapter fits the prepared stacked formula withbrms::brm()(through cmdstanr when it is installed and CmdStan is configured, rstan when cmdstanr is absent; an installed cmdstanr without a working CmdStan is an error, not a fallback) and returns fixed-effect and residual-scale draws as a plain base matrix. brms is in Suggests; injected adapters remain the mechanism for other engines, andper_pv/stack_psisinputs are unchanged.Final
pvstackr_fitobjects now carry an exact validation record. A deep tier preserves the full semantic checks, while a cheap tier re-hashes the current package-owned payload with domain-separated SHA-256 and rejects stale stamps. This catches same-moment draw replacements, coordinated proposal/weight row changes, hidden leaf attributes, and self-rehashed data-free design snapshots that summary-only validation cannot distinguish. Opaque retained backend objects are explicit fast-tier exceptions and force deep validation. Public fit accessors and fit print/summary methods use the rehash tier, avoiding repeated method-specific recomputation while still reading every mutable retained payload byte.Blocked fits now use a generic fail-closed retention firewall. Effective
return_draws,keep_data,keep_backend_fit, andkeep_log_likare alwaysFALSE; reportable estimates and heavy design, stack-fit, CCC, draw, weight, pooling, backend, and log-likelihood payloads are absent. Blockedstack_directfits may retain only a canonical independently valid external target plus exact slim sampler or scalar CCC gate evidence, while blockedstack_psisfits retain only the canonical Pareto-k/provenance decision record and bounded weight-concentration diagnostics. The recursive validator also rejects hidden payloads in nested fields or leaf attributes. Becauseper_pvhas no typed blocked schema, relabeling a reportable reference fit as blocked is rejected.Historical PSIS results now have an explicit inspection-only migration path.
pv_migrate_legacy_psis_fit()returns current validated fits unchanged but projects any non-currentstack_psisfit to bounded Pareto-k evidence and a redaction record; saved estimates, draws, pooling, weights, backend objects, and data are not migrated, and estimate/draw accessors refuse the inspection object. New method comparisons and fit/comparison summaries carry deep-valid compact source reportability objects, canonical source projections, and owned-payload SHA-256 records. Pre-marker serialized comparisons or summaries containing PSIS are refused and must be rebuilt, while an independent semantic gate also rejects warning PSIS rows and any blocked row retaining numeric or pooling metadata.
pvstackr 0.1.1
Patch release fixing two bugs found while preparing the LSAE software article. Point estimates are unchanged for every method; the fixes affect stack_psis interval width and the acceptance of posterior::draws_matrix inputs.
Bug fixes
stack_psisPSIS-weighted covariance.pv_weighted_mean_cov()appliedsqrt(weights)to only one factor of the cross-product (crossprod(centered * sqrt(weights), centered)), weighting each draw bysqrt(w)instead ofw. This inflatedstack_psiswithin-imputation covariances by roughly the square root of the draw count. Weighted-mean point estimates were unaffected, butstack_psisstandard errors and intervals reported by 0.1.0 are inflated and should be recomputed. Added a direct regression test for the weighted-covariance formula.CCC validation of
posterior::draws_matrixinputs. When adraws_functionreturned aposterior::draws_matrix(the natural output ofposterior::as_draws_matrix()on abrmsfit),validate_pvstackr_ccc()compareddraws_fe_calagainst the fixed-effect block ofdraws_calibratedwith a strictidentical(). Thedraws_matrixS3 class and draw-id row names made that check fail even when the values matched, aborting with “CCCdraws_fe_calmust equal the fixed-effect block ofdraws_calibrated”. Draw matrices are now normalized to plain base matrices at the ingestion boundary (ccc_as_draw_matrix()), so the identity check compares values and column names rather than S3 provenance. Added regression tests for adraws_matrix-classed input through calibration and validation, plus (under the optional backend-smoke suite) a genuineposterior::as_draws_matrix()through the fullstack_directCCC path.
pvstackr 0.1.0
First public release. pvstackr calibrates a stacked Bayesian-backend fit of plausible-value survey data to an external Rubin/BRR-Fay fixed-effect target, anchoring the reportable fixed-effect estimates and intervals to a design-based reference.
New features
-
Declare a PISA-style design.
pv_design()describes a plausible-value survey design and auto-detects its structure withdetect_pisa_pv_columns()(plausible-value sets) anddetect_pisa_brr_replicate_weights()(BRR replicate weights), recording row-support and Fay/design fingerprints and validating duplicate, missing, or malformed columns. -
Assemble an external target.
pv_brr_target()builds the external Rubin/BRR-Fay fixed-effect target (Rubin combining, the BRR-Fay sandwich variance, and Barnard-Rubin degrees of freedom) thatstack_directcalibrates to. -
Fit a method.
pv_fit()dispatches across three methods:stack_direct(the default),per_pv, andstack_psis. The engines are also exported directly aspv_fit_direct(),pv_fit_reference(), andpv_fit_stack_psis().pv_control()collects fitting controls. -
Compare methods.
pv_compare_methods()aligns the fixed-effect estimates from the three methods into a single comparison object with agreement diagnostics, retains blocked methods explicitly, and validates the result. -
Read results. Stable accessors return the pieces you report:
get_estimates()(the reportable estimate table with interval metadata),get_target(),get_draws()(retained top-level fixed-effect draws), andget_diagnostics(). -
Inspect at a glance. Compact
print()andsummary()methods cover designs, targets, controls, fits, and method comparisons. -
Bundled synthetic example. A tiny synthetic
pisa_tinyfixture and a cachedstack_directfit (underinst/extdata/) let every example and vignette run instantly with no live sampler. No real PISA records or OECD/PISA-distributed files are bundled. -
Documented object contract.
?pvstackr_object_contractsspecifies the structure of each object and the meaning of the interval-metadata columns.
Documentation
- Ten vignettes in two tracks. An Applied track (workflow-first): A1 getting started, A2 the end-to-end workflow, A3 reading results and what to report, A4 comparing methods, and A5 real PISA data guidance. A Method track (rigorous, equation-backed): M1 foundations and notation, M2 the BRR-Fay fixed-effect target, M3 the stacked fractional bridge, M4 CCC (Cholesky Calibration Correction), and M5 methods, PSIS, and coverage.
- pkgdown website at https://joonho112.github.io/pvstackr/, with the reference index grouped by workflow stage (design -> target -> fit -> compare -> read).
-
Rewritten roxygen documentation with
@familygroups and@seealsocross-links connecting each stage of the workflow. - Rewritten README with a problem-first introduction, the method in three steps, a five-minute fixture example, and both vignette tables.
- Hex logo and favicons for the package and site.
Scope and honesty
- Fixed-effect only. Reportable estimates and retained draws are fixed-effect quantities. Group/random-effect terms are out of scope for the v0.1 BRR-Fay target engine.
-
Coverage is claimable for
stack_directonly.stack_directintervals are coverage-claimable only when backed by an external design-based BRR-Fay target with Barnard-Rubin degrees of freedom. The claim rests on target provenance and validation evidence, not on CCC arithmetic alone.per_pvandstack_psisresults are descriptive, and the estimate table flags this per interval. - No efficiency or speed claims. “One fit” refers to the stacked-fit architecture (topology), not to benchmarked runtime. The package makes no “faster” or “N-times” claims.
-
No real PISA microdata. Only the synthetic
pisa_tinyfixture ships. Real PISA data must be obtained under its own license; vignette A5 explains how to connect to it without bundling licensed files. -
stack_psisexpects supplied diagnostics. It uses PSIS weights and Pareto-k diagnostics that you supply or inject; the package does not run liveloo::psis()in v0.1. - Not affiliated. This is an independent research package and is not affiliated with or endorsed by the OECD or the PISA programme.
-
Method paper forthcoming. The methodology manuscript is in preparation; for now, please cite the package (see
citation("pvstackr")).
pvstackr 0.0.0.9000
Development
- Initial development scaffold: established the package boundary as a clean applied-method package (not a paper-replication repository), fixed the
pvstackrname and theper_pv/stack_psis/stack_directmethod IDs, and built out the public surface, fixtures, and test/parity coverage that the 0.1.0 release documents.