Skip to content

Commit e22449b

Browse files
baogorekclaude
andcommitted
Merge MaxGhenis's add/tob-revenue-variables branch
Merging PR #6750 which adds trust fund revenue variables and fixes LSR recursion. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
2 parents 6684d00 + d639aed commit e22449b

File tree

28 files changed

+751
-201
lines changed

28 files changed

+751
-201
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.426.0] - 2025-10-28 20:44:10
9+
10+
### Added
11+
12+
- Age heterogeneity in labor supply response elasticities using multiplier approach.
13+
814
## [1.425.7] - 2025-10-28 14:08:51
915

1016
### Fixed
@@ -13405,6 +13411,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1340513411

1340613412

1340713413

13414+
[1.426.0]: https://github.com/PolicyEngine/policyengine-us/compare/1.425.7...1.426.0
1340813415
[1.425.7]: https://github.com/PolicyEngine/policyengine-us/compare/1.425.6...1.425.7
1340913416
[1.425.6]: https://github.com/PolicyEngine/policyengine-us/compare/1.425.5...1.425.6
1341013417
[1.425.5]: https://github.com/PolicyEngine/policyengine-us/compare/1.425.4...1.425.5

changelog.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11409,3 +11409,8 @@
1140911409
fixed:
1141011410
- Fix recursion errors when applying LSRs.
1141111411
date: 2025-10-28 14:08:51
11412+
- bump: minor
11413+
changes:
11414+
added:
11415+
- Age heterogeneity in labor supply response elasticities using multiplier approach.
11416+
date: 2025-10-28 20:44:10

changelog_entry.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
1+
- bump: minor
2+
changes:
3+
added:
4+
- Trust fund revenue variables (tob_revenue_total, tob_revenue_oasdi, tob_revenue_medicare_hi) using exact branching methodology
5+
- Tier 1 and tier 2 taxable Social Security variables for proper OASDI vs Medicare HI allocation
6+
- LSR recursion guard to prevent infinite loops when branches calculate variables
7+
fixed:
8+
- Labor supply behavioral response infinite recursion bug
Lines changed: 206 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,206 @@
1-
# Elasticities
1+
# Labor Supply Response Elasticities
2+
3+
This directory contains parameters for labor supply response elasticities used in behavioral microsimulation analysis.
4+
5+
## Overview
6+
7+
Labor supply elasticities measure how individuals adjust their work behavior in response to changes in economic incentives:
8+
9+
- **Substitution elasticity**: How labor supply responds to changes in the effective marginal wage rate (after-tax wage)
10+
- **Income elasticity**: How labor supply responds to changes in disposable income
11+
12+
## Age Heterogeneity: The Multiplier Approach
13+
14+
Both elasticity types support age-based heterogeneity through an **age multiplier** that scales base elasticities for individuals aged 65 and over. This approach is based on empirical research showing that older workers have higher labor supply elasticities than working-age adults.
15+
16+
### Research Findings
17+
18+
- **French (2005)**: Elasticities 3.0x-3.25x higher for age 60 vs age 40 workers
19+
- **CBO Working Papers (2012-12, 2012-13)**: Frisch elasticity ranges from 0.27 to 0.53 (central: 0.40) for working-age adults
20+
- **General pattern**: Retirement-age individuals (62-70) have particularly high elasticities, especially on the extensive margin (whether to work at all)
21+
22+
### Why a Multiplier Approach?
23+
24+
The multiplier approach was chosen over separate age-specific parameters because:
25+
1. **Evidence-based**: Literature consistently shows older workers are more elastic, but doesn't provide income-decile-specific multipliers
26+
2. **Parsimony**: 13 total parameters instead of 44 (11 base elasticities + 2 age multipliers)
27+
3. **Transparency**: Users can easily understand and adjust one multiplier value
28+
4. **Flexibility**: Multiplier can range from 1.0 (no age effect) to 3.0+ (French 2005 finding)
29+
30+
## Substitution Elasticity Structure
31+
32+
The substitution elasticity uses a two-step calculation:
33+
34+
### Step 1: Base Elasticity (by position and decile)
35+
36+
Base elasticities vary by:
37+
1. **Position**: primary earner vs secondary earner within tax unit
38+
2. **Decile**: 10 income deciles (for primary earners only)
39+
40+
This creates 11 base elasticity parameters:
41+
- 10 for primary earners by decile
42+
- 1 for secondary earners (all deciles)
43+
44+
### Step 2: Age Multiplier
45+
46+
For individuals aged 65 and over, the base elasticity is multiplied by `age_multiplier_65_and_over`.
47+
48+
**Formula**:
49+
- If age < 65: `elasticity = base_elasticity`
50+
- If age >= 65: `elasticity = base_elasticity × age_multiplier_65_and_over`
51+
52+
### Global Override
53+
54+
The `all` parameter overrides all base elasticities and age multipliers if set to non-zero.
55+
56+
## Income Elasticity Structure
57+
58+
The income elasticity uses a simpler two-parameter structure:
59+
60+
1. **Base elasticity**: Applied to all working-age individuals (under 65)
61+
2. **Age multiplier**: Applied to individuals 65 and over
62+
63+
**Formula**:
64+
- If age < 65: `elasticity = base`
65+
- If age >= 65: `elasticity = base × age_multiplier_65_and_over`
66+
67+
The `all` parameter overrides base and multiplier if set to non-zero.
68+
69+
## Default Values
70+
71+
- All base elasticities default to 0 (no behavioral response)
72+
- Age multipliers default to 2.0 (conservative estimate based on literature)
73+
- Users must explicitly set base elasticity values to enable behavioral responses
74+
75+
## Usage Examples
76+
77+
### Example 1: No behavioral response (default)
78+
```yaml
79+
substitution:
80+
by_position_and_decile:
81+
primary:
82+
1: 0
83+
2: 0
84+
# ... all zeros
85+
secondary: 0
86+
age_multiplier_65_and_over: 2.0 # Doesn't matter since base is 0
87+
88+
income:
89+
base: 0
90+
age_multiplier_65_and_over: 2.0 # Doesn't matter since base is 0
91+
```
92+
93+
Result: Everyone has zero elasticity regardless of age.
94+
95+
### Example 2: Same elasticity for all ages
96+
```yaml
97+
substitution:
98+
by_position_and_decile:
99+
primary:
100+
1: 0.31 # CBO-style values
101+
2: 0.27
102+
# ... other deciles
103+
secondary: 0.40
104+
age_multiplier_65_and_over: 1.0 # No age effect
105+
106+
income:
107+
base: -0.04
108+
age_multiplier_65_and_over: 1.0 # No age effect
109+
```
110+
111+
Result: Same elasticity for everyone regardless of age.
112+
113+
### Example 3: Higher elasticity for elderly (RECOMMENDED)
114+
```yaml
115+
substitution:
116+
by_position_and_decile:
117+
primary:
118+
1: 0.31
119+
2: 0.27
120+
# ... other deciles
121+
secondary: 0.40
122+
age_multiplier_65_and_over: 2.0 # Conservative estimate
123+
124+
income:
125+
base: -0.04
126+
age_multiplier_65_and_over: 2.0
127+
```
128+
129+
Result:
130+
- Age 40, primary earner, decile 1: elasticity = 0.31
131+
- Age 70, primary earner, decile 1: elasticity = 0.31 × 2.0 = 0.62
132+
- Age 40: income elasticity = -0.04
133+
- Age 70: income elasticity = -0.04 × 2.0 = -0.08
134+
135+
### Example 4: Aggressive multiplier based on French (2005)
136+
```yaml
137+
substitution:
138+
age_multiplier_65_and_over: 3.0 # Upper end of literature
139+
140+
income:
141+
base: -0.04
142+
age_multiplier_65_and_over: 3.0
143+
```
144+
145+
Result:
146+
- Age 70, primary earner, decile 1 (base 0.31): elasticity = 0.31 × 3.0 = 0.93
147+
- Age 70: income elasticity = -0.04 × 3.0 = -0.12
148+
149+
## Multiplier Value Guidance
150+
151+
Based on literature review (see `age_heterogeneity_analysis.md`):
152+
153+
| Multiplier | Interpretation | Source |
154+
|------------|----------------|--------|
155+
| 1.0 | No age difference | Ignores evidence |
156+
| 1.5 | Conservative | Lower end of estimates |
157+
| 2.0 | **Recommended default** | Conservative but evidence-based |
158+
| 2.5 | Moderate | Midpoint of French (2005) range |
159+
| 3.0 | Aggressive | French (2005) finding for age 60 vs 40 |
160+
| 3.25 | Upper bound | Upper end of French (2005) range |
161+
162+
**Note**: The exact multiplier value has uncertainty. We recommend starting with 2.0 and conducting sensitivity analysis with values in the 1.5-3.0 range.
163+
164+
## References
165+
166+
- [French (2005): "The Effects of Health, Wealth, and Wages on Labour Supply and Retirement Behaviour"](https://academic.oup.com/restud/article-abstract/72/2/395/1558553) - Review of Economic Studies 72(2): 395-427
167+
- [CBO Working Paper 2012-12: "A Review of Recent Research on Labor Supply Elasticities"](https://www.cbo.gov/publication/43675) - McClelland & Mok
168+
- [CBO Working Paper 2012-13: "Review of Estimates of the Frisch Elasticity of Labor Supply"](https://www.cbo.gov/publication/43676) - Reichling & Whalen
169+
170+
## Implementation Notes
171+
172+
- Age is determined from the `age` variable for the year (`period.this_year`)
173+
- Age 65 is the cutoff: age < 65 uses base elasticity, age >= 65 applies multiplier
174+
- Primary earner is defined as the highest earner within the tax unit
175+
- Earnings deciles are determined using hardcoded markers (TODO: parametrize)
176+
- Negative total earnings result in zero elasticity (using `max_(earnings, 0)`)
177+
- Zero base elasticity remains zero even with multiplier (0 × multiplier = 0)
178+
179+
## Technical Details
180+
181+
### How Primary/Secondary Earner is Determined
182+
183+
Within each tax unit, the person with the highest total earnings (employment + self-employment) is designated as the primary earner. All other earners in the unit are secondary earners. This means:
184+
- Single-person tax units: That person is always primary
185+
- Multi-person tax units: Only the highest earner gets primary elasticity; others get zero (since secondary earner base elasticities default to 0)
186+
187+
### Earnings Decile Markers
188+
189+
Current hardcoded decile boundaries (TODO: parametrize):
190+
- Decile 1: $0 - $14,000
191+
- Decile 2: $14,000 - $28,000
192+
- Decile 3: $28,000 - $39,000
193+
- Decile 4: $39,000 - $50,000
194+
- Decile 5: $50,000 - $61,000
195+
- Decile 6: $61,000 - $76,000
196+
- Decile 7: $76,000 - $97,000
197+
- Decile 8: $97,000 - $138,000
198+
- Decile 9: $138,000 - $1,726,000
199+
- Decile 10: $1,726,000+
200+
201+
### Negative Earnings Handling
202+
203+
To prevent negative earnings from causing sign flips in economic responses, the code applies `max_(earnings, 0)` before calculating elasticities. This means:
204+
- Positive net earnings: Normal elasticity calculation
205+
- Negative net earnings: Treated as zero earnings, resulting in zero substitution elasticity
206+
- Income elasticity still applies to individuals with negative earnings
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
description: Multiplier applied to base income elasticity for individuals at or above the age threshold. Research suggests income effects are stronger for older workers. French (2005) shows much higher elasticities near retirement age. A multiplier of 2.0 is conservative. Set to 1.0 for no age difference.
2+
values:
3+
2020-01-01: 2.0
4+
metadata:
5+
unit: /1
6+
label: elasticity multiplier for ages at or above threshold
7+
reference:
8+
- title: "French (2005): The Effects of Health, Wealth, and Wages on Labour Supply and Retirement Behaviour"
9+
href: https://academic.oup.com/restud/article-abstract/72/2/395/1558553
10+
- title: "CBO Working Paper 2012-12: A Review of Recent Research on Labor Supply Elasticities"
11+
href: https://www.cbo.gov/publication/43675
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
description: Age at which the age multiplier begins to apply. Individuals at this age or older will have their base elasticity multiplied by the age multiplier. Default is 65 (typical retirement age), but can be adjusted to reflect different retirement patterns or policy scenarios (e.g., 62 for early retirement, 67 for full retirement age).
2+
values:
3+
2020-01-01: 65
4+
metadata:
5+
unit: year
6+
label: age threshold for elasticity multiplier
7+
reference:
8+
- title: "French (2005): The Effects of Health, Wealth, and Wages on Labour Supply and Retirement Behaviour"
9+
href: https://academic.oup.com/restud/article-abstract/72/2/395/1558553

policyengine_us/parameters/gov/simulation/labor_supply_responses/elasticities/income.yaml renamed to policyengine_us/parameters/gov/simulation/labor_supply_responses/elasticities/income/all.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description: Percent change (of the change in disposable income) in labor supply given a 1% change in disposable income.
1+
description: Percent change (of the change in disposable income) in labor supply given a 1% change in disposable income. This parameter overrides the base income elasticity and age multiplier if provided.
22
values:
33
2020-01-01: 0
44
metadata:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
description: Base income elasticity of labor supply for working-age individuals (under 65). This value is multiplied by the age multiplier for individuals 65 and over. Typically negative, indicating that higher income reduces labor supply.
2+
values:
3+
2020-01-01: 0
4+
metadata:
5+
unit: /1
6+
label: base income elasticity below threshold
7+
reference:
8+
- title: "CBO Working Paper 2012-12: A Review of Recent Research on Labor Supply Elasticities"
9+
href: https://www.cbo.gov/publication/43675
10+
- title: "CBO Working Paper 2012-13: Review of Estimates of the Frisch Elasticity of Labor Supply"
11+
href: https://www.cbo.gov/publication/43676

policyengine_us/parameters/gov/simulation/labor_supply_responses/elasticities/substitution.yaml

Lines changed: 0 additions & 70 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
description: Multiplier applied to all substitution elasticities for individuals at or above the age threshold. Research shows older workers have higher labor supply elasticities than working-age adults. French (2005) finds elasticities 3x higher for age 60 vs age 40. A multiplier of 2.0 is conservative. Set to 1.0 for no age difference.
2+
values:
3+
2020-01-01: 2.0
4+
metadata:
5+
unit: /1
6+
label: elasticity multiplier for ages at or above threshold
7+
reference:
8+
- title: "French (2005): The Effects of Health, Wealth, and Wages on Labour Supply and Retirement Behaviour"
9+
href: https://academic.oup.com/restud/article-abstract/72/2/395/1558553
10+
- title: "CBO Working Paper 2012-12: A Review of Recent Research on Labor Supply Elasticities"
11+
href: https://www.cbo.gov/publication/43675

0 commit comments

Comments
 (0)