Skip to content

Commit 2d3c1ca

Browse files
committed
Slim cchs_missing_data.yaml to one normative encoding per fact (v1.1.0)
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.
1 parent 617148c commit 2d3c1ca

1 file changed

Lines changed: 58 additions & 157 deletions

File tree

inst/metadata/schemas/cchs/cchs_missing_data.yaml

Lines changed: 58 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,225 +1,126 @@
1-
schema_version: "1.0.0"
2-
schema_date: "2025-01-20"
3-
description: "CCHS missing data patterns and transformation rules - machine-actionable metadata reference"
1+
schema_version: "1.1.0"
2+
schema_date: "2026-07-15"
3+
description: "CCHS missing data patterns and priority rules - machine-actionable metadata"
44

55
# All codes and ranges in this schema are in the SOURCE coding domain (raw
6-
# StatCan codes), not the harmonized/derived domain. Consumers: the
7-
# clean_variables() fallback pattern and load_priority_rules() read the
8-
# normative blocks (pattern_definitions, na_category_definitions);
9-
# variable_assignments is reference documentation only - the per-variable
10-
# source of truth is variable_details.csv.
6+
# StatCan codes), not the harmonized/derived domain.
117
applies_to: "source_codes"
128

13-
# Cross-reference with human-readable documentation
9+
# Consumers (code that reads this file). The per-variable source of truth is
10+
# variable_details.csv; this schema supplies the pattern families, the
11+
# priority hierarchy, and the fallback pattern.
12+
consumers:
13+
- "load_cchs_missing_data() in R/load-schema.R"
14+
- ".default_cchs_pattern() in R/clean-variables.R"
15+
- "load_priority_rules() in R/missing-data-functions.R"
16+
1417
related_documentation:
1518
user_guide: "vignettes/missing_value_conventions.qmd"
16-
implementation_guide: "vignettes/missing_value_conventions.qmd"
17-
19+
1820
# ============================================================================
19-
# MISSING DATA PATTERN DEFINITIONS
21+
# MISSING DATA PATTERN DEFINITIONS (normative)
2022
# ============================================================================
23+
# Each family's priority_hierarchy is the single normative encoding of which
24+
# source codes map to which tagged-NA category. Tag values are symbolic
25+
# ("a", "b"); consumers construct haven::tagged_na() from them - this file
26+
# contains data, never executable code.
2127
pattern_definitions:
2228
title: "CCHS Missing Data Code Patterns"
23-
description: "Authoritative specification of missing data patterns for cchsflow implementation"
24-
version: "1.0.0"
25-
26-
# Core pattern specifications
29+
description: "Missing-code families follow StatCan field width: single digit (valid 1-5), double digit (valid 1-95), triple digit (continuous)."
30+
2731
patterns:
2832
single_digit_missing:
2933
description: "Binary/ternary variables with valid responses 1-5"
3034
valid_response_range: [1, 5]
31-
missing_codes: [6, 7, 8, 9]
32-
transformation_map:
33-
6: "haven::tagged_na('a')" # Not applicable
34-
7: "haven::tagged_na('b')" # Don't know
35-
8: "haven::tagged_na('b')" # Refusal
36-
9: "haven::tagged_na('b')" # Not stated
3735
priority_hierarchy:
38-
description: "Two-tier priority system: not_applicable wins over any missing_data"
39-
not_applicable:
36+
description: "Two-tier priority: not_applicable wins over missing_data"
37+
not_applicable:
4038
label: "Not applicable"
4139
description: "Participant doesn't qualify for this question"
4240
original_codes: [6]
4341
tagged_na: ["a"]
4442
missing_data:
4543
label: "Missing data"
46-
description: "All missing response types (don't know, refusal, not stated)"
44+
description: "Don't know (7), refusal (8), not stated (9)"
4745
original_codes: [7, 8, 9]
4846
tagged_na: ["b"]
49-
47+
5048
double_digit_missing:
5149
description: "Multi-category scales with valid responses 1-95"
5250
valid_response_range: [1, 95]
53-
missing_codes: [96, 97, 98, 99]
54-
critical_usage_note: "Required when max valid response > 5 (e.g., smoking status 6=never smoked)"
55-
transformation_map:
56-
96: "haven::tagged_na('a')" # Not applicable
57-
97: "haven::tagged_na('b')" # Don't know
58-
98: "haven::tagged_na('b')" # Refusal
59-
99: "haven::tagged_na('b')" # Not stated
51+
critical_usage_note: "Required when max valid response > 5 (e.g., 6-category smoking status where 6 = never smoked is VALID)"
6052
priority_hierarchy:
61-
description: "Two-tier priority system: not_applicable wins over any missing_data"
53+
description: "Two-tier priority: not_applicable wins over missing_data"
6254
not_applicable:
6355
label: "Not applicable"
6456
description: "Participant doesn't qualify for this question"
6557
original_codes: [96]
6658
tagged_na: ["a"]
6759
missing_data:
6860
label: "Missing data"
69-
description: "All missing response types (don't know, refusal, not stated)"
61+
description: "Don't know (97), refusal (98), not stated (99)"
7062
original_codes: [97, 98, 99]
7163
tagged_na: ["b"]
72-
64+
7365
triple_digit_missing:
7466
description: "Continuous measurements with variable-specific valid ranges"
7567
valid_response_range: "variable_specific"
76-
missing_codes: [996, 997, 998, 999]
77-
decimal_variations: [999.6, 999.7, 999.8, 999.9] # Early cycles
78-
transformation_map:
79-
996: "haven::tagged_na('a')" # Not applicable
80-
997: "haven::tagged_na('b')" # Don't know
81-
998: "haven::tagged_na('b')" # Refusal
82-
999: "haven::tagged_na('b')" # Not stated
83-
999.6: "haven::tagged_na('a')" # Not applicable (decimal)
84-
999.7: "haven::tagged_na('b')" # Don't know (decimal)
85-
999.8: "haven::tagged_na('b')" # Refusal (decimal)
86-
999.9: "haven::tagged_na('b')" # Not stated (decimal)
8768
priority_hierarchy:
88-
description: "Two-tier priority system: not_applicable wins over any missing_data"
69+
description: "Two-tier priority: not_applicable wins over missing_data"
8970
not_applicable:
9071
label: "Not applicable"
9172
description: "Participant doesn't qualify for this question"
9273
original_codes: [996]
9374
tagged_na: ["a"]
94-
decimal_codes: [999.6]
75+
decimal_codes: [999.6] # early-cycle variant
9576
missing_data:
9677
label: "Missing data"
97-
description: "All missing response types (don't know, refusal, not stated)"
78+
description: "Don't know (997), refusal (998), not stated (999)"
9879
original_codes: [997, 998, 999]
9980
tagged_na: ["b"]
100-
decimal_codes: [999.7, 999.8, 999.9]
101-
102-
# ============================================================================
103-
# VARIABLE PATTERN ASSIGNMENTS
104-
# ============================================================================
105-
variable_assignments:
106-
title: "CCHS Variable Pattern Assignments"
107-
description: "Machine-actionable assignments of missing data patterns to specific CCHS variables"
108-
reference_guide: "vignettes/missing_value_conventions.qmd#pattern-selection-guidelines"
109-
110-
smoking_variables:
111-
SMK_005:
112-
pattern: "single_digit_missing"
113-
valid_range: [1, 3]
114-
description: "Type of smoker presently"
115-
SMK_030:
116-
pattern: "single_digit_missing"
117-
valid_range: [1, 2]
118-
description: "Ever smoked daily"
119-
SMK_01A:
120-
pattern: "single_digit_missing"
121-
valid_range: [1, 2]
122-
description: "Smoked 100+ cigarettes in lifetime"
123-
SMOKING_STATUS_DERIVED:
124-
pattern: "double_digit_missing" # CRITICAL: 6 is valid (never smoked)
125-
valid_range: [1, 6]
126-
description: "Derived smoking status (6-category)"
127-
critical_note: "Category 6 (never smoked) is VALID, not missing"
128-
SMKG203:
129-
pattern: "double_digit_missing"
130-
valid_range: [1, 11]
131-
description: "Age started smoking daily (categorical)"
132-
SMKG207:
133-
pattern: "double_digit_missing"
134-
valid_range: [1, 11]
135-
description: "Age started smoking daily (former daily smokers)"
136-
SMK_204:
137-
pattern: "triple_digit_missing"
138-
valid_range: [0, 150]
139-
description: "Cigarettes per day (daily smokers)"
140-
SMK_208:
141-
pattern: "triple_digit_missing"
142-
valid_range: [0, 150]
143-
description: "Cigarettes per day (former daily smokers)"
144-
145-
anthropometric_variables:
146-
HWTDGHTM:
147-
pattern: "triple_digit_missing"
148-
valid_range: [0.5, 2.5]
149-
description: "Height in meters"
150-
HWTDGWTK:
151-
pattern: "triple_digit_missing"
152-
valid_range: [20, 300]
153-
description: "Weight in kilograms"
81+
decimal_codes: [999.7, 999.8, 999.9] # early-cycle variants
15482

15583
# ============================================================================
156-
# TRANSFORMATION RULES
84+
# NA CATEGORY SEMANTICS
15785
# ============================================================================
158-
transformation_rules:
159-
title: "CCHS Missing Data Transformation Implementation"
160-
description: "Machine-actionable rules for converting original CCHS codes to standardized NA categories"
161-
reference_documentation: "vignettes/missing_value_conventions.qmd#current-classification-used-in-cchsflow"
162-
163-
na_category_definitions:
164-
"NA::a":
165-
semantic_meaning: "Not applicable"
166-
original_codes: [6, 96, 996]
167-
statistical_treatment: "Exclude from denominators and percentage calculations"
168-
169-
"NA::b":
170-
semantic_meaning: "Missing data"
171-
original_codes: [7, 8, 9, 97, 98, 99, 997, 998, 999]
172-
statistical_treatment: "Include in denominators, exclude from numerators"
173-
174-
implementation:
175-
primary_function: "preprocess_cchs_missing_codes"
176-
pattern_aliases:
177-
# Deprecated names for backward compatibility
178-
standard_response: "single_digit_missing"
179-
categorical_age: "double_digit_missing"
180-
continuous_standard: "triple_digit_missing"
181-
182-
pattern_selection_rules:
183-
reference: "vignettes/missing_value_conventions.qmd#pattern-selection-guidelines"
184-
decision_logic:
185-
continuous_variables: "triple_digit_missing"
186-
max_valid_over_5: "double_digit_missing"
187-
max_valid_under_6: "single_digit_missing"
86+
# Epidemiological meaning and analysis guidance per tagged-NA category.
87+
# Codes are NOT repeated here - they live in the family definitions above.
88+
na_category_semantics:
89+
"NA::a":
90+
semantic_meaning: "Not applicable"
91+
statistical_treatment: "Exclude from denominators and percentage calculations"
92+
"NA::b":
93+
semantic_meaning: "Missing data"
94+
statistical_treatment: "Include in denominators, exclude from numerators"
18895

18996
# ============================================================================
190-
# IMPLEMENTATION REFERENCE
97+
# AUTHORING GUIDANCE (non-normative)
19198
# ============================================================================
192-
implementation:
193-
primary_function: "preprocess_cchs_missing_codes"
194-
pattern_names: ["single_digit_missing", "double_digit_missing", "triple_digit_missing"]
195-
constants_file: "R/validation-constants.R"
196-
197-
testing_requirements:
198-
boundary_testing: "Test all valid category endpoints and missing codes"
199-
type_safety: "Validate haven::tagged_na() preservation"
200-
integration: "Verify rec_with_table() workflow compatibility"
201-
99+
# How to choose a family when adding a variable to the worksheets. Judgment
100+
# guidance for authors, not machine-executed logic.
101+
authoring_guidance:
102+
family_selection:
103+
continuous_variables: "triple_digit_missing"
104+
max_valid_over_5: "double_digit_missing (single-digit codes would collide with valid categories)"
105+
max_valid_under_6: "single_digit_missing"
106+
canonical_examples:
107+
single_digit_missing: "SMK_005 (type of smoker, valid 1-3), ADL_01 (needs help, valid 1-2)"
108+
double_digit_missing: "SMKDSTY 6-category smoking status - category 6 (never smoked) is VALID, not missing; SMKG203 (age started, valid 1-11)"
109+
triple_digit_missing: "SMK_204 (cigarettes per day), HWTGHTM (height in metres)"
202110
cycle_considerations:
203-
stable_patterns: "Core missing codes (6,7,8,9) consistent since CCHS 2001"
204-
decimal_variations: "Early cycles use 999.6, later cycles use whole numbers"
205-
handled_automatically: "cchsflow normalizes all variations"
111+
stable_patterns: "Core missing codes (6,7,8,9 families) consistent since CCHS 2001"
112+
decimal_variations: "Early cycles use 999.6-999.9 for some continuous variables; declared in triple_digit_missing and handled by the fallback pattern"
206113

207114
# ============================================================================
208115
# METADATA AND VERSIONING
209116
# ============================================================================
210117
metadata:
211118
schema_authority: "cchsflow development team"
212119
last_reviewed: "2026-07-15"
213-
next_review_due: "2025-07-20"
120+
next_review_due: "2027-01-15"
214121
version_history:
122+
"1.1.0": "Slimmed to one normative encoding per fact: removed transformation_map (R-code strings; redundant with priority_hierarchy), removed per-variable assignments (variable_details.csv is the per-variable source of truth; judgment preserved in authoring_guidance), removed stale implementation pointers (referenced never-merged functions), replaced with an accurate consumers list. Added applies_to: source_codes."
215123
"1.0.0": "Initial comprehensive specification with standardized pattern names (single/double/triple_digit_missing)"
216-
217-
related_documents:
218-
primary_reference: "vignettes/missing_value_conventions.qmd"
219-
implementation_guide: "vignettes/missing_value_conventions.qmd"
220-
constants_file: "R/validation-constants.R"
221-
helper_functions: "R/missing-data-functions.R"
222-
223124
contact_information:
224125
maintainer: "cchsflow development team"
225126
issues: "https://github.com/Big-Life-Lab/cchsflow/issues"

0 commit comments

Comments
 (0)