Skip to content

Final preparations for cchsflow v3#191

Merged
rafdoodle merged 196 commits into
devfrom
v3
Jul 16, 2026
Merged

Final preparations for cchsflow v3#191
rafdoodle merged 196 commits into
devfrom
v3

Conversation

@rafdoodle

Copy link
Copy Markdown
Collaborator

Summary of changes to address #189

Hello @DougManuel and @yulric,

Here are a summary of changes I made so far over the past week to help finalize cchsflow v3:

Must do

Namespace and passing all tests for CRAN submission:

  • ca02a94 — Restructured DESCRIPTION Depends/Imports for CRAN compliance
  • 8171e96 — Added .claude/ and ceps/ to .Rbuildignore
  • 51c81a0 — Replaced non-ASCII characters for CRAN portability
  • e13cc20 — Fixed broken examples, dead cross-references, Rd usage mismatches
  • 05421fe — Fixed test assertions, qualified sjlabelled in tests
  • 5301929 — Resolved global variable binding NOTEs
  • 35db4c6 — Updated NAMESPACE via roxygen, fixed RData object naming
  • c1a16df — Upgraded version to 3.0.0
  • Result: devtools::check() passes with 0 errors, 0 warnings, 2 NOTEs (installed size + timestamps — both non-actionable)

Review and update documentation and package build:

  • 860167b — Standardized roxygen documentation across all 46 v3 3-step functions to follow adl/alcohol template: verb-first titles, @description, @details with domain context, @return with tagged_na info, @examples, @seealso
  • e13cc20 — Fixed broken examples, synced @param with function signatures, fixed Rd line widths

Assess infrastructure — validation functions and branch consolidation:

  • 967be79 — Consolidated validation infrastructure from Doug/Yulric feature branches (feature/v3.0.0-validation-infrastructure, v3.0.0-validation-infrastructure, yulric fork, 3.0.0-merge-strategy); confirmed all cherry-pick candidates already merged or superseded; trimmed worksheets to match YAML schemas; added extra column removal to fix_worksheet()
  • 4c22630 — Updated variable_details.yaml schema to enforce alphabetical sorting via id_column_name

Review and use variable and variable_details schemas:

  • 967be79 — Confirmed v3 YAML schemas are UTD with correct 10-column (variables) and 16-column (variable_details) structure; trimmed CSVs to match; check_worksheet() and fix_worksheet() return 0 errors on both worksheets

Nice to have

DemPoRTv2 variables updated to CCHS 2022 (PUMF) and 2023 (Master):

Derived variables adopt 3-step approach (#173):

  • f078e9d — Incorporated 3-step architecture (clean_variables()case_whenclean_variables()) for all DemPoRTv2-used derived variable functions; properly named functions (calculate_*, categorize_*, derive_*, assess_*)
  • 1ca5e6e — Standardized NULL handling with tagged_na("c") for all-NULL inputs, added expand_null_inputs() DRY helper, added legacy test files
  • 0860899 — Fixed NA handling in education function (get_priority_missing instead of assign_missing for all-missing inputs)
  • 4c22630 — Refactored COPD_Emph_der into CCC_091_der with single categorize_CCC_091() function using consistent CCC_091 input across all eras
  • NA::c sub-issue deferred: The full NA::c infrastructure (changes to assign_missing(), get_priority_missing(), any_missing(), worksheet patterns) remains deferred as a separate sub-issue of Standardise NULL-handling pattern for standalone derived variable functions #173. The current tagged_na("c") return for all-NULL inputs works for standalone function calls but is not yet a first-class missing type in the v3 pipeline.

Tagged NA preservation through recodeflow (#190):

  • b6270d2 — Added prep_cat_output() helper as a workaround for a recodeflow architectural issue where as.factor(unlist(...)) in rec_with_table() strips tagged NA bit patterns during factorization, causing all tagged NAs to collapse to plain NA and get mislabeled as NA(c) by downstream processing. The helper converts tagged NAs to their string equivalents ("NA(a)", "NA(b)", "NA(c)") at the return boundary of categorical Func:: functions so they survive factor conversion. Applied to all 18 categorical derived variable functions. The proper fix belongs in recodeflow's rec_with_table() factorization step, which would make the per-function workaround unnecessary — see Tagged NAs lost during factor conversion in categorical Func:: functions #190 for details.

DemPoRTv2 protocol branch alignment:
The v3 3-step architecture has been fully incorporated into DemPoRTv2's protocol branch. R/cchsflow-helpers.R provides the same v3 infrastructure primitives (clean_variables(), any_missing(), get_priority_missing(), assign_missing(), normalize_input_lengths(), expand_null_inputs(), prep_cat_output()), and R/custom-functions.R contains identical copies of all DemPoRTv2-used derived variable functions using the same 3-step pattern. These are sourced by the targets pipeline (via _targets.R) so that recodeflow::rec_with_table() calls the v3 functions during harmonization. The DemPoRT worksheet (worksheets/cchsflow-variable-details.csv) references these functions via Func:: entries and has been updated to match cchsflow's csv-conventions.md (dummyVariable naming, NA labels, unit consistency, block ordering, alphabetical sorting).

Note that only DemPoRTv2-used variables and their derived functions have been fully updated to the v3 architecture and extended to 2022/2023 cycles; other variables within the same sections (e.g., remaining chronic conditions, physical activity, alcohol) will continue to be updated in coming days.

Test plan

  • devtools::check() — 0 errors, 0 warnings, 2 NOTEs
  • devtools::test() — 0 failures, 829+ passing
  • check_worksheet() — 0 errors on both worksheets
  • check_recode_blocks() — 0 collisions
  • exec/check-worksheets.R and exec/fix-worksheets.R run without errors

Please let me know what you think.

Rafidul

wyusuf068 and others added 30 commits June 4, 2020 09:35
@rafdoodle

rafdoodle commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

The following subjects now contain raw and derived variables extended past 2017-2018 PUMF and Master cycles in databaseStart and variableStart of the CSV worksheets:

  • ADL (ADL)
  • Alcohol (ALC/ALN/ALW)
  • Chronic conditions (CCC variables only)
  • Demographics (DHH - age, sex, marital status, and household characteristics)
  • Diet (FVC)
  • Education (EDU/EHG)
  • General health (GEN)
  • Health Utility Index (HUI - hearing and vision only)
  • Height / Weight / BMI (HWT body measures)
  • Oral health (DEN/OH)
  • Physical activity (PAA/PAC/PAY)
  • Sedentary activity (SAC/SBE)
  • Sociodemographics (SDC)
  • Sleep (SLP)
  • Smoking (SMK)
  • Weights and admin (WTS_M, WTS_S, ADM_RNO)

Deferred / not yet extended:

  • Chronic conditions which are not CCC variables — depression scales (DPS), social provisions (SPS), social support (SSA), disability (DIS)
  • Geography — province (GEOGPRV), health region (GEODPMF)
  • Food security (FINF, FSCDHFS)
  • Health care use (HCU, FLU vaccination)
  • HUI variables unrelated to hearing and vision (cognition, dexterity, emotion, mobility, speech, pain, HSI index)
  • Income (INCGHH, INCGPER, INCDR*)
  • Injury (INJ)
  • Occupation (LBFA)
  • Repetitive strain injury (REP)

Sources: 613 Data Dictionary and NotebookLLM

@DougManuel Please let me know if you think this is good enough for v3 or if more extensions are warranted. Feel free to use the MCP to validate databaseStart and variableStart if you have the time.

Rafidul

@rafdoodle rafdoodle linked an issue Jul 9, 2026 that may be closed by this pull request
…adl.R @note metadata

Review findings: the failing CSV check was a workflow bug (devtools not
installed on the runner), not worksheet violations - worksheets pass all
checks locally on the same commit. Adds devtools to the workflow install
step and rewords the catch-all failure message to surface the real
cause. Restores the three @note version-metadata lines dropped from
R/adl.R in the July refactor, returning the test suite to fully green
(828 passing, 0 failures).

CEP-018 contains the release review summary (L3-L5 sweeps, L6 cross-
cycle prevalence matrix, ADL step-change diagnosis, fast-fix regression
checks) with two open items for the team: issue #139 arms and the
missing-data priority decision.
@DougManuel

DougManuel commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Code review

Review of v3 -> dev: automated L3-L5 sweeps over all 481 changed variables (120 added, 41 removed, 320 modified), L6 cross-cycle integration sampled across the changed domains, and package health checks. Full findings, the L6 prevalence matrix, and diagnosis scripts: ceps/cep-018-v3-release-review/ (committed in 1406aff).

Fixes applied in 1406aff

  1. The failing CSV check was a workflow bug, not worksheet violations. exec/check-worksheets.R needs devtools, which the runner never installed; the job died before any CSV was checked and a catch-all step printed the misleading "violations detected" message. The worksheets pass all checks locally on the same commit (exit 0). Fixed the workflow install step and the failure message — the check should run green now.
  2. Restored the three @note version-metadata lines dropped from R/adl.R in the July refactor. Test suite is fully green again: 828 passing, 0 failures, 0 errors.

Open items before merge (or as fast-follows)

  1. Issue immigration_der and not applicable #139 remains unfixed [90]: categorize_immigration() has no arms for non-immigrants born outside Canada (immigrant_status == 2 & born_canada == 2) — they fall through to missing. Two additional case_when arms before the NA-propagation block resolve it.
  2. Missing-data priority decision [75]: missing_priority_rules.yaml is still unshipped; live behaviour is NA::a-wins while the unmerged config specified NA::b-wins. A methodological decision to record (NEWS note), not a code defect.
  3. DEN_132 / cchs2001_p [50, verify]: claims 2001 coverage but 0% valid in the 200-row sample; cross-check against CEP-006 before merge. Also confirm the single-year tokens (cchs2010_p/2012_p/2014_p) are intentional.

Verified clean

Era-boundary source mappings (0 gaps), databaseStart tokens (CEP-017's malformed DEN_132 tokens fixed), no deprecated _s/_i tokens, no duplicate recode blocks, cross-file integrity intact. Regression checks: #138 no longer reproduces, #159 (tibble input) fixed, #184/#185 fixed, June ADL/alcohol repair and list-mode fix present with tests. The ADL prevalence step change at 2011 was diagnosed as a survey redesign (RAC module -> gated ADL module), correctly represented as NA(a) — details in the CEP.

L6 limitation: no sample data exists for 2019-2023 PUMFs, so this release's headline coverage extensions to those cycles are validated by worksheet checks only.

Recommendation: approve once the CI check re-runs green; items 1-2 above can land in this PR (S-effort each) or as fast-follow issues at the team's preference.

CEP: ceps/cep-018-v3-release-review/

…, cross-file keys

Extends check_worksheet() with three declarative rules, setting the stage
for progressively richer schema validation (full column schema deferred
to the v4 refactor, where this merges into the recodeflow schema layer):

- Database-token registry (inst/metadata/schemas/core/database_registry.yaml,
  32 valid identifiers): every databaseStart token is validated against
  the registry, so typo identifiers fail at PR time instead of becoming
  silent dead rows. Adding a new cycle now requires a deliberate,
  reviewable registry entry.
- Controlled vocabularies (column_enums in the worksheet schemas):
  typeStart (cat/cont/N/A) and typeEnd (cat/cont) in variable_details,
  variableType (Categorical/Continuous) in variables.
- Cross-file key integrity (check_cross_file_keys()): every
  variable_details entry must have a variables.csv row.

Registry naming follows the recodeflow database-metadata draft for a
clean v4 merge. Fixes one pre-existing worksheet cell surfaced by the
enum rule (HWTGCOR_der Func:: row had an empty typeStart; now N/A per
convention) and updates test fixtures that used never-valid values
(variableType 'cont', bare 'cchs' and invented 'cchs2013_p' tokens).

Full checker green on the worksheets (all five rule groups); suite at
836 passing, 0 failures. Relates to CEP-017 Track 2 and CEP-018.
@DougManuel

Copy link
Copy Markdown
Contributor

Follow-up in 638de98 — first increment of schema-driven content validation, per the validation discussion:

  • Database-token registry (inst/metadata/schemas/core/database_registry.yaml): every databaseStart token now validates against 32 registered identifiers in CI. Typos like the DEN_132 cchs2007_2008p class fail at PR time instead of becoming silent dead rows; supporting a new cycle becomes a deliberate one-line registry addition.
  • Controlled vocabularies in the worksheet schemas: typeStart/typeEnd (variable_details) and variableType (variables).
  • Cross-file key check (check_cross_file_keys()): every variable_details entry must have a variables.csv row.

All rules run in the existing CI check and scoped mode. One pre-existing cell fixed (HWTGCOR_der's Func:: row had an empty typeStart, now N/A per convention) and a few test fixtures updated that used never-valid values. Checker fully green on the worksheets; suite at 836 passing / 0 failures.

Registry naming follows the recodeflow database-metadata draft so this layer merges cleanly into recodeflow at the v4 refactor. Full column schema (types, cardinality, dummyVariable grammar) stays deferred to v4 per CEP-017 Track 2.

…iority rules

The CCHS missing-data pattern schema was shipped but dormant. It now has
two thin consumers reading only its normative blocks:

- clean_variables()'s fallback pattern (used when a variable has no
  worksheet metadata) is built from the schema's pattern families instead
  of hardcoded values. Net behavior gain: the early-cycle decimal missing
  codes (999.6-999.9), declared in the schema but absent from the old
  hardcoded fallback, are now handled.
- load_priority_rules() resolves the not-applicable-over-missing priority
  from the schema's declared hierarchy, replacing the built-in fallback
  and its once-per-session 'YAML files not found' warning. The priority
  decision is now read from a versioned, reviewable file.

The schema gains an applies_to: source_codes declaration (codes are in
the raw StatCan domain, not the harmonized domain) and a consumer note
marking variable_assignments as reference-only - variable_details.csv
remains the per-variable source of truth. Also adds .DS_Store to
.Rbuildignore so Finder droppings stay out of the built package.

Suite: 842 passing, 0 failures. Relates to CEP-017 Track 3.
Removes the three sources of drift and confusion flagged in review:

- transformation_map: deleted. It embedded R expressions as YAML strings
  (haven::tagged_na('a')) and duplicated priority_hierarchy, which is now
  the single normative code-to-tag encoding with symbolic tag values.
- variable_assignments: deleted. Per-variable pattern assignment belongs
  to variable_details.csv; the block's judgment content (the never-smoked
  category-6 collision warning, canonical examples per family) is
  preserved in a non-normative authoring_guidance section.
- implementation blocks: deleted. They pointed at a never-merged function
  (preprocess_cchs_missing_codes) and a feature-branch-only constants
  file. Replaced by an accurate consumers list naming the three functions
  that actually read this schema.
- na_category_definitions renamed na_category_semantics, keeping the
  epidemiological guidance (denominator treatment) and dropping its
  duplicate code lists.

Consumers verified byte-identical in behaviour: fallback pattern codes,
decimal variants, and priority resolution unchanged; suite at 842
passing, 0 failures. File shrinks from 219 to ~130 lines with no loss of
normative content.
@DougManuel

Copy link
Copy Markdown
Contributor

Review follow-through: validation and schema consumption (1406aff42d3c1cad)

Four commits followed the release review. Together they diagnose the failing CI check, then use what the review found to strengthen worksheet validation.

CI fix and review artifacts (1406aff4). The failing CSV check was a workflow bug, not worksheet violations: exec/check-worksheets.R needs devtools, the runner never installed it, and a catch-all step masked the real error. The workflow now installs devtools and reports failures honestly. This commit also restores three @note metadata lines dropped from R/adl.R in the July refactor (the only real test failures on the branch). Full review findings and the L6 prevalence matrix are in ceps/cep-018-v3-release-review/.

Schema-driven content validation (638de987). check_worksheet() previously checked formatting only. Three declarative rules now run in the same CI check: a database-token registry (database_registry.yaml) that rejects typo identifiers like the DEN_132 cchs2007_2008p class before they become silent dead rows; controlled vocabularies for typeStart/typeEnd/variableType; and a cross-file key check tying every variable_details entry to a variables.csv row. The rules found one real violation (HWTGCOR_der's empty typeStart, now N/A) and several test fixtures using never-valid values.

Consuming cchs_missing_data.yaml (617148c8). The missing-data schema shipped in the package but nothing read it. Two thin consumers now do: the clean_variables() fallback pattern, which gains the early-cycle decimal codes (999.6–999.9), and load_priority_rules(), which reads the not-applicable-over-missing priority from the schema rather than a code fallback.

Slimming the schema (2d3c1cad). The file stated the same facts three ways. Removing the transformation_map (R code as YAML strings), the per-variable assignments (variable_details.csv is the source of truth), and stale implementation pointers leaves one normative encoding per fact. Author guidance is preserved in a labelled non-normative section. Consumers verified identical in behaviour.

Suite: 842 passing, 0 failures. The principle across these commits is that validation rules are declared in schema files and enforced by generic code, so the next improvement starts with a YAML edit. Registry and schema naming follow the recodeflow draft for a clean merge at v4.

Still open from the review: the #139 immigration arms, the priority-order decision (documented in the schema as not-applicable-wins), and the DEN_132/cchs2001_p coverage check.

@rafdoodle rafdoodle linked an issue Jul 16, 2026 that may be closed by this pull request
@rafdoodle

Copy link
Copy Markdown
Collaborator Author

Open items — all addressed

1. Issue #139categorize_immigration()

Already resolved in f72fbfd ("Fixed #139 by adding 'White Canadians born outside of Canada' and 'Non-white Canadians born outside of Canada' categories to immigration_der"). The immigrant_status == 2 & born_canada == 2 arms exist in R/immigration.R on lines 67-69 (categories 7-8).

2. Missing-data priority

The code is correct and internally consistent — NA::a (not applicable) wins over NA::b (missing/not stated) across:

  • cchs_missing_data.yaml (every pattern family declares "not_applicable wins over missing_data")
  • load_priority_rules() built-in fallback (na_a = 1, na_b = 2)
  • apply_priority_hierarchy() and all derived variable functions (BMI, education, smoking, immigration, etc.)

The CEP-018 review referenced a "never-merged config on 3-step-tidyverse" that specified NA::b-wins. That branch no longer exists locally or on the remote — it was a prior feature branch that was superseded and deleted. The config it contained was never shipped and does not reflect intended behaviour. The unshipped missing_priority_rules.yaml is irrelevant since the YAML schema and built-in fallback both enforce the same hierarchy. One incorrect docstring comment in get_priority_missing() (claimed NA::b > NA::a) has been corrected. No NEWS note needed — there was never a behaviour change, just a stale comment carried over from the superseded branch.

3. DEN_132 / cchs2001_p

The 2001 PUMF mapping (DENA_132) has been verified against the 613 Data Dictionary and NotebookLM. CEP-006 also confirms 2001 coverage: PUMF valid rate of 35.7%, Master valid rate of 87.7% — the variable is well-populated. The 0% rate in the CEP-018 review came from a 200-row sample, which is too small for optional-content modules. The single-year tokens (cchs2010_p, cchs2012_p, cchs2014_p) are intentional — these are annual PUMF releases that exist alongside the combined 2-year PUMFs as documented in csv-conventions.md.

@rafdoodle
rafdoodle merged commit 433156f into dev Jul 16, 2026
2 checks passed
@rafdoodle
rafdoodle deleted the v3 branch July 16, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment