Add aggregate_survey() for survey microdata-to-panel aggregation#282
Add aggregate_survey() for survey microdata-to-panel aggregation#282
Conversation
Adds a new prep utility that aggregates individual-level survey data (BRFSS, ACS, CPS) to geographic-period cells with design-based precision estimates. Returns a (DataFrame, SurveyDesign) tuple ready for second-stage DiD estimation with inverse-variance weights and geographic clustering. Computes Horvitz-Thompson influence functions per cell, routing to TSL or replicate variance via existing survey infrastructure. Falls back to SRS variance when within-cell design is too thin. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ⛔ Blocker Highest unmitigated finding is a P0 methodology bug in Executive Summary
Methodology Affected method: design-weighted cell mean estimation with TSL/replicate variance and second-stage inverse-variance weighting in
Code Quality
Performance No material findings in the changed code. Maintainability
Tech Debt No separate tech-debt-only finding. The P0/P1 issues above are not tracked in TODO.md, so they remain unmitigated and cannot be deferred under the stated review policy. Security No findings. I did not see secrets, unsafe command construction, or new data-exposure paths in the changed files. Documentation/Tests
Path to Approval
|
Rework aggregate_survey() to use full-design domain estimation: zero-pad influence functions outside each cell, preserving full strata/PSU structure for variance computation per Lumley (2004) Section 3.4 and the library's subpopulation() methodology. Also fix: min_n parameter now operative (forces SRS fallback), empty-input guard added, docstring examples corrected, REGISTRY.md rewritten with domain estimation language, 4 new tests added (domain regression, min_n behavior, empty input, replicate weights). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Highest unmitigated finding is a Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
Address remaining P1/P3 from AI review: - Reject NaN in by columns before groupby (P1) - Make docstring/RST examples illustrative pseudocode (P3) - Add tests for partial and all-NaN grouping keys (P3) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Highest unmitigated finding is a Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
Replace label-based index lookup with stable positional row tracking via _row_pos column, so duplicate DataFrame indices cannot break or mis-map cell aggregation. Add regression test verifying identical results with duplicated vs clean indices. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Highest unmitigated finding is a Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
Replace _row_pos column injection with groupby().indices which returns positional indices directly. No temporary columns are added to the user's data, eliminating any column name collision risk. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Highest unmitigated finding is a Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Verification note: I could not run the tests in this environment because Path to Approval
|
Define validity as non-NaN AND positive weight so zero-weight padding
rows don't inflate {outcome}_n or bypass n_valid < 2 / min_n guards.
Add regression test for cell with 1 real + 9 zero-weight observations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Highest unmitigated finding is a Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
The returned SurveyDesign now points at a {outcome}_weight column
where NaN/Inf precision values are mapped to 0.0, so downstream
fit() never rejects missing weights. Diagnostic *_precision column
is preserved as-is. Add stage2-handoff test with single-observation
cell (NaN precision → zero weight → fit succeeds).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Highest unmitigated finding is a Executive Summary
Methodology
Code Quality
Performance No findings. Maintainability No findings. Tech Debt No findings. Neither Security No findings. Documentation/Tests
Path to Approval
|
Cells with non-finite outcome mean (n_valid==0, all-missing, all-zero- weight) are dropped from the panel with a warning before constructing the stage2 SurveyDesign. This ensures fit() never encounters NaN outcomes and eliminates all-zero-weight PSUs from second-stage variance/df calculations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Highest unmitigated finding is a Executive Summary
Methodology
Code Quality
Performance No findings. Maintainability No separate findings. Tech Debt No separate findings. I checked TODO.md:L51-L120; neither remaining Security No findings. Documentation/Tests
Path to Approval
|
Geographic units where every cell has zero weight are pruned before constructing stage2, preventing inflated survey df/variance. If all cells are dropped, raise ValueError with clear message. Add regressions for zero-weight PSU pruning and all-cells-dropped cases. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment The two prior blocker-class handoff issues do look fixed: non-estimable cells are now dropped before return at diff_diff/prep.py:1641, zero-total-weight geographies are pruned before the stage-two design is built at diff_diff/prep.py:1669, and the empty-post-drop case now raises at diff_diff/prep.py:1687, with matching regressions at tests/test_prep.py:2481, tests/test_prep.py:2512, and tests/test_prep.py:2550. The remaining unmitigated issue is a new Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
Multi-outcome filtering is based on the first outcome (consistent with the returned SurveyDesign using the first outcome's weights). Docstring now explicitly states this contract. Warning emitted when dropped cells had valid data for secondary outcomes. Test added for the contract. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good Executive Summary
Methodology
Code Quality
Performance No findings. Maintainability No findings. Tech Debt No findings. Security No findings. Documentation/Tests
|
- Validate empty by/outcomes lists with clear ValueError (P2) - Fix replicate test to use JK1 matching DGP output (P3) - Update RST example with *_weight column and filtering note (P3) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
|
Non-numeric columns now raise a clear ValueError instead of failing inside astype(np.float64). Add regression test for string column. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
Replace np.issubdtype with pd.api.types.is_numeric_dtype so pandas nullable extension dtypes (Int64, Float64) are accepted as numeric. Add regression test with Float64 outcome column. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
Exercises the SRS fallback path under a JK1 replicate-weight design, verifying that fallback SEs are finite/positive and differ from the replicate-based SEs. Covers the min_n × replicate interaction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
Both SRS fallback branches now normalize positive weights to mean=1 before computing variance, ensuring SEs are invariant to constant weight rescaling (important for replicate designs that preserve raw weight scale). Add scale-invariance regression test with 5x rescaling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good No unmitigated P0/P1 findings remain in this re-review. The new Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
|
The RST example references undefined 'microdata' variable, same as the existing wide_to_long skip pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
aggregate_survey()todiff_diff/prep.py— aggregates individual-level survey microdata to geographic-period cells with design-based precision estimates(DataFrame, SurveyDesign)tuple: panel with cell means/SEs/precision weights, plus pre-configured aweight + geographic clustering design for second-stage DiDsrs_fallbackcolumn) when within-cell design is too thinMethodology references (required if estimator / math changes)
survey::svyby()patternValidation
tests/test_prep.py::TestAggregateSurvey— 17 tests covering core functionality, edge cases (SRS fallback, zero variance, missing data, singleton PSU), correctness (SRS equivalence, design effect, equal weights), and full integration pipeline (microdata → aggregate → DiD estimation)Security / privacy
Generated with Claude Code