Skip to content

Conversation

@MaxGhenis
Copy link
Contributor

Summary

Implements local SPM threshold calculation from source data. This enables proper SPM threshold calculation for district-level analysis where records may be reweighted to different geographic areas.

Problem

When reweighting CPS records to match district targets, records from high-cost areas (e.g., California) retain their original SPM thresholds even when assigned weight in low-cost areas (e.g., Iowa). This reduces the geographic variation in thresholds that should exist (~50% range from West Virginia to Hawaii).

Solution

Calculate SPM thresholds from components using the formula:

threshold = base_threshold[tenure] × equivalence_scale × geoadj

Key components:

  • ce_threshold.py: Base thresholds from BLS by tenure type

    • Renter: $39,430
    • Owner with mortgage: $39,068
    • Owner without mortgage: $32,586 (2024 values)
  • district_geoadj.py: Geographic adjustment from ACS median 2-bedroom rents

    • Formula: GEOADJ = (local_rent / national_rent) × 0.492 + 0.508
    • Range: ~0.84 (West Virginia) to ~1.27 (Hawaii)
  • local_threshold.py: Calculate local thresholds for SPM units

    • SPM three-parameter equivalence scale (first adult=1.0, additional adults=0.5, children=0.3)
    • Vectorized calculation for all SPM units

Usage:

from policyengine_us_data.spm import (
    calculate_local_spm_thresholds,
    update_spm_thresholds_for_districts,
)

# Calculate thresholds for SPM units in specific districts
thresholds = calculate_local_spm_thresholds(
    district_codes=["0612", "5401"],  # CA-12, WV-01
    tenure_types=["renter", "renter"],
    num_adults=[2, 2],
    num_children=[2, 2],
    year=2024,
)

Test plan

  • 13 unit tests pass for base thresholds, equivalence scale, and GEOADJ formula
  • Integration test with district calibration workflow
  • Validate against published Census SPM thresholds

🤖 Generated with Claude Code

Implements local SPM threshold calculation from source data to replace
the original CPS SPM thresholds when records are reweighted to different
geographic areas.

The SPM threshold formula is:
    threshold = base_threshold[tenure] × equivalence_scale × geoadj

Key components:
- ce_threshold.py: Base thresholds from BLS by tenure type (renter,
  owner with mortgage, owner without mortgage)
- district_geoadj.py: Geographic adjustment from ACS median 2-bedroom
  rents using formula: GEOADJ = (local/national) × 0.492 + 0.508
- local_threshold.py: Calculate local thresholds for SPM units with
  proper equivalence scale and district-specific GEOADJ

This addresses the issue where reweighted records retain their original
area's SPM thresholds instead of the target district's costs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants