feat: support svyrep.design (replicate-weight) survey objects - #356
Open
szimmer wants to merge 2 commits into
Open
feat: support svyrep.design (replicate-weight) survey objects#356szimmer wants to merge 2 commits into
szimmer wants to merge 2 commits into
Conversation
`svyrep.design` is a sibling class of `survey.design` rather than a subclass, so replicate-weight designs failed S3 dispatch before reaching any statistical code. Register `svyrep.design` methods for the six survey ard_* generics. The implementations are shared with the existing `survey.design` methods: statistics are computed by survey::svymean(), svytotal(), svyvar(), svyquantile(), svytable() and svyby(), all of which already handle replicate designs, so no separate calculation is needed. Tests cover dispatch, ARD structure, agreement of weighted point estimates with the linearized design, that replicate variance is genuinely used rather than silently falling back to linearization, and all replicate types (JK1, JKn, bootstrap, subbootstrap, Fay, BRR). Refs pharmaverse#355 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The methods were previously alias assignments
(`ard_tabulate.svyrep.design <- ard_tabulate.survey.design`). That form
is invisible to tooling that reasons about the source statically:
- covr reported no rows at all for R/svyrep.design.R -- the file was
absent from the coverage report rather than scoring 0% or 100%,
because top-level assignments carry no instrumentable expressions
- covr::file_coverage() errored outright with
"object 'ard_attributes.survey.design' not found", since the aliases
resolve only at load time and depend on file collation order
- static analysis could not resolve the right-hand sides
Defining each method as a thin wrapper that forwards to its
`survey.design` counterpart fixes all three: R/svyrep.design.R now
reports 100% coverage (6/6 lines hit by the test suite) and no longer
depends on files being sourced in a particular order. Behaviour is
unchanged -- the same `survey.design` implementations do the work, and
tidyselect arguments pass through `...` untouched.
Also:
- add an @examplesIf block to each of the six shared help topics
showing a replicate design built with as.svrepdesign(), and
regenerate the .Rd files
- scope the NEWS entry to the six functions actually covered, and note
that the survey test and confidence interval functions do not yet
accept replicate designs, so the release notes do not promise more
than the change delivers
- satisfy lintr in the tests: rename BRRrep to brr_rep (snake_case) and
load the survey data into an explicit environment so apiclus1 is not
flagged as an undefined global inside the helper
Refs pharmaverse#355
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes are proposed in this pull request?
svyrep.designmethods forard_attributes(),ard_total_n(),ard_missing(),ard_tabulate(),ard_tabulate_value()andard_summary(), so these functions now accept replicate-weight survey designs created withsurvey::svrepdesign()orsurvey::as.svrepdesign(). Becausesvyrep.designis a sibling class ofsurvey.designrather than a subclass, such designs previously failed S3 dispatch. Statistics are computed by the samesurveyfunctions as forsurvey.design, all of which already support replicate designs, so variance estimates correctly reflect the replicate weights. The survey test and confidence interval functions (e.g.ard_survey_svychisq(),ard_categorical_ci(),ard_continuous_ci()) do not yet accept replicate designs. (Feature Request: Supportsvyrep.design(replicate-weight) survey objects #355, @szimmer)Provide more detail here as needed.
svyrep.designis a sibling ofsurvey.design, not a subclass:so replicate designs were rejected at dispatch, before reaching any statistical code.
No new statistical code is introduced. Each new method is a thin wrapper that forwards to its
survey.designcounterpart, which reachessurveythrough.compute_svy_stat()and.svytable_counts():surveyfunction calledsvymean,svytotal,svyvar,svyquantile,svytablesvyrep.designmethodssvybysvyby.defaultSE,deffScope. This covers the first of the two blockers described in #355 — the missing S3 methods. The seven functions with hard
check_class(data, "survey.design")guards are untouched here, sogtsummary::add_p()andadd_ci()will still fail on replicate designs after this merges. I'd like to follow up with a second PR relaxing five of them (ard_survey_svychisq(),ard_survey_svyttest(),ard_survey_svyranktest(),ard_categorical_ci(),ard_continuous_ci()), each of which wraps asurveyfunction that already handles replicate designs, and a third forard_emmeans_contrast()/ard_emmeans_emmeans(), which I have not yet tested against replicate designs. Splitting it this way keeps each PR to changes I can evidence. Happy to combine them if you'd rather review one.Tests (
tests/testthat/test-svyrep.design.R) cover:svyrep.designcards::check_ard_structure()on the resultsn,N,p,median) agreeing exactly with the equivalent linearized design, since the sampling weights are identicalp.std.errorvalues differ from the linearized design and matchsurvey::SE(survey::svymean(...))on the same design, so this is not a silent fallback to linearizationsvrepdesign()by=tabulationFor reference, on
apiclus1:stypeMotivation. Replicate weights are the standard variance-estimation method shipped with most large public-use survey files — NHANES, NHIS, BRFSS, ACS and the NCES surveys, and anything using BRR or jackknife. This is also the blocker for
gtsummary::tbl_svysummary()supporting replicate designs (ddsjoberg/gtsummary#1441, #1535).Reference GitHub issue associated with pull request.
Addresses #355 (the first of the two blockers described there; please leave the issue open for the
check_class()guards).Pre-review Checklist (if item does not apply, mark is as complete)
usethis::pr_merge_main()ard_*()function was added, it passes the ARD structural checks fromcards::check_ard_structure().ard_*()function was added,set_cli_abort_call()has been set.ard_*()function was added and it depends on another package (such as,broom),is_pkg_installed("broom")has been set in the function call and the following added to the roxygen comments:@examplesIf do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = "broom""))devtools::test_coverage()Notes on the checklist:
covrreports 100% forR/svyrep.design.R(6/6 lines, exercised by the new tests); package coverage is 96.73%.set_cli_abort_call()andis_pkg_installed("survey")are inherited from thesurvey.designfunctions the new methods delegate to.survey.designcounterparts via@rdname; each topic gained an@examplesIfblock showing a replicate design.