Skip to content

Commit c931c91

Browse files
Merge pull request #6821 from PolicyEngine/revert-labor-supply-elasticity-age-heterogeneity
Revert labor supply elasticity age heterogeneity
2 parents 035f530 + 66a73e5 commit c931c91

File tree

17 files changed

+160
-474
lines changed

17 files changed

+160
-474
lines changed

changelog_entry.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- bump: patch
2+
changes:
3+
changed:
4+
- Revert age heterogeneity in labor supply response elasticities (v1.426.0).
Lines changed: 1 addition & 206 deletions
Original file line numberDiff line numberDiff line change
@@ -1,206 +1 @@
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
1+
# Elasticities
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. This parameter overrides the base income elasticity and age multiplier if provided.
1+
description: Percent change (of the change in disposable income) in labor supply given a 1% change in disposable income.
22
values:
33
2020-01-01: 0
44
metadata:

policyengine_us/parameters/gov/simulation/labor_supply_responses/elasticities/income/age_multiplier_over_threshold.yaml

Lines changed: 0 additions & 11 deletions
This file was deleted.

policyengine_us/parameters/gov/simulation/labor_supply_responses/elasticities/income/age_threshold.yaml

Lines changed: 0 additions & 9 deletions
This file was deleted.

policyengine_us/parameters/gov/simulation/labor_supply_responses/elasticities/income/base.yaml

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
all:
2+
description: Percent change (of the change in the effective marginal wage) in labor supply given a 1% change in the effective marginal wage. This parameter overrides all other substitution elasticities if provided.
3+
values:
4+
2020-01-01: 0
5+
metadata:
6+
unit: /1
7+
label: substitution elasticity of labor supply
8+
by_position_and_decile:
9+
metadata:
10+
label: by position and decile
11+
unit: /1
12+
propagate_metadata_to_children: true
13+
primary:
14+
metadata:
15+
label: primary adult
16+
1:
17+
metadata:
18+
label: primary adult, 1st decile substitution elasticity
19+
values:
20+
2020-01-01: 0
21+
2:
22+
metadata:
23+
label: primary adult, 2nd decile substitution elasticity
24+
values:
25+
2020-01-01: 0
26+
3:
27+
metadata:
28+
label: primary adult, 3rd decile substitution elasticity
29+
values:
30+
2020-01-01: 0
31+
4:
32+
metadata:
33+
label: primary adult, 4th decile substitution elasticity
34+
values:
35+
2020-01-01: 0
36+
5:
37+
metadata:
38+
label: primary adult, 5th decile substitution elasticity
39+
values:
40+
2020-01-01: 0
41+
6:
42+
metadata:
43+
label: primary adult, 6th decile substitution elasticity
44+
values:
45+
2020-01-01: 0
46+
7:
47+
metadata:
48+
label: primary adult, 7th decile substitution elasticity
49+
values:
50+
2020-01-01: 0
51+
8:
52+
metadata:
53+
label: primary adult, 8th decile substitution elasticity
54+
values:
55+
2020-01-01: 0
56+
9:
57+
metadata:
58+
label: primary adult, 9th decile substitution elasticity
59+
values:
60+
2020-01-01: 0
61+
10:
62+
metadata:
63+
label: primary adult, 10th decile substitution elasticity
64+
values:
65+
2020-01-01: 0
66+
secondary:
67+
metadata:
68+
label: secondary adult, all deciles substitution elasticity
69+
values:
70+
2020-01-01: 0

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

Lines changed: 0 additions & 11 deletions
This file was deleted.

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

Lines changed: 0 additions & 9 deletions
This file was deleted.

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

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)