PolicyEngine / PolicyEngine/microcosm
Carry CPS employer fields and add a jobs imputation stage for employer-side payroll taxes
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 4
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 94
Description
Finding
The dashboard analysis for FUTA (futa-wage-base-dashboard#4) joined raw CPS ASEC employer fields onto the certified national file by PERIDNUM and source_year (100% of 166,321 persons match, ASEC 2023 to 2025). Two things the file lacks for employer-side payroll taxes:
- Employer count. FUTA applies its wage base per employer per employee. The person table has no employers-last-year field, so any per-employer cap is applied once per worker. The raw ASEC has
PHMEMPRS(1, 2, 3 or more; simultaneous jobs count as one) and the longest-job vs other-employer wage split (ERN_VALwithERN_SRCE= 1,WS_VAL). Definitions: Census 2024 ASEC public-use data dictionary. - Longest-job class of worker.
PEIO1COW(March reference-week job) is carried;LJCW(class of worker on the longest job last year, with the federal/state/local split) is not. FUTA exemption follows the employer of record for the year's wages.
Measured on the certified file with the joined fields: exempt employers (government plus private nonprofit) hold 21.7% of wages under the $7,000 base and 22.7% under $43,000; per-employer capping as the CPS reports employers raises revenue at the $7,000 base by 7% (Census weights) to 12% (model weights).
Two data-quality observations from the same join
- Multi-employer workers are over-represented after selection and calibration. 14.8% of wage earners report two or more employers at model weights, 13.1% among the selected rows at Census weights, 10.9% in the full ASEC. Employer count is not a target, so the sparse selection and reweighting drift on it. For ratios like this the raw ASEC at Census weights is currently the better source.
- The CPS itself undercounts employer-employee pairs. 1.13 employers per wage earner in the ASEC (3 or more counted as 3) against 275.0 million Forms W-2 filed in calendar 2024 (IRS Publication 6961, Table 2) for about 167 million earners, roughly 1.65 per earner. With the exempt and per-employer adjustments applied, the FUTA model sits 17% below IRS collections; this gap is the likely reason.
Proposal
- Carry
PHMEMPRS,LJCW,ERN_VAL,ERN_SRCE,WS_VALthrough the carried-column stage (us_runtime/cps_carried.py,source_stages.json) as person inputs. Small change; unblocks a per-employer FUTA rule in the engine. - Add a jobs imputation stage: give each worker an employer count and wage split seeded from those fields, fitted so the implied distribution of jobs by wage band matches IRS SOI Form W-2 tabulations. Once jobs exist as a structure, W-2 counts by band become ordinary sum targets with broad support (every worker carries jobs), and FUTA collections become a held-out check. Reweighting alone cannot fix the count: hitting 275 million pairs by upweighting the 11% of multi-employer respondents is the thin-support concentration
docs/us-fact-to-target.mdalready rules out.
Related: the wage-band target proposal in the companion issue. Downstream rule change: policyengine-us issue on FUTA exempt employers and per-employer caps (linked from the Slack thread).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with us_runtime/cps_carried.py, source_stages.json, and docs/us-fact-to-target.md; trace how carried person inputs and calibration targets are represented. Carry the named CPS fields and add a jobs-imputation stage whose implied job distribution matches IRS SOI Form W-2 wage-band tabulations, with FUTA collections as a held-out check.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data-engineering
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100