Case Study4 min read

Impact of 401(k) on Financial Assets

Automated conversion of 401k.ipynb

Impact of 401(k) on Financial Assets

Data explanation

1991 Survey of Income and Program Participation

  • net_tfaNet Total Financial Assets. Calculated as the sum of all liquid and interest-earning assets (IRA balances, 401(k) balances, checking accounts, U.S. savings bonds, other interest‐earning accounts, stocks, mutual funds, etc.) minus non‐mortgage debts.

  • e401401(k) Eligibility Indicator. Equals 1 if the individual's employer offers a 401(k) plan; otherwise 0.

  • p401401(k) Participation Indicator. Equals 1 if the individual participate in 401(k) plan; otherwise 0.

  • ageAge. Age of the individual in years.

  • incAnnual Income. Annual income of the individual, measured in U.S. dollars for the year 1990.

  • educYears of Education. Number of completed years of formal education.

  • fsizeFamily Size. Total number of persons living in the household.

  • marrMarital Status. Equals 1 if the individual is married; otherwise 0.

  • twoearnTwo-Earner Household. Equals 1 if there are two wage earners in the household; otherwise 0.

  • dbDefined-Benefit Pension Plan. Equals 1 if the individual is covered by a defined-benefit pension plan; otherwise 0.

  • piraIRA Participation. Equals 1 if the individual contributes to an Individual Retirement Account (IRA); otherwise 0.

  • hownHome Ownership. Equals 1 if the household owns its home; 0 if renting.

We download it with fetch_401K function from doubleML.datasets

This dataset has a problem. confounders were measured in the same year as treatment and outcome, like they are demographic factors that do not change over time. So inference might still be biased.

Result

/Users/ioannmartynov/miniconda3/envs/causalkit/lib/python3.14/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html from .autonotebook import tqdm as notebook_tqdm

Result

Index(['net_tfa', 'age', 'inc', 'fsize', 'educ', 'db', 'marr', 'twoearn', 'p401', 'pira', 'hown'], dtype='object')

EDA

Result
treatmentcountmeanstdminp10p25medianp75p90max
00732110890.47753955256.829173-502302.0-5427.0-1184.0200.07399.033500.01462115.0
11259438262.05859479087.535303-283356.0-1300.03000.015249.045985.598887.41536798.0

Participants’ average net worth is ≈28k higher, but this gap cannot be causally attributed solely to participation. The classes are imbalanced—only 26% are treated.

Result

png

Result

png

Our outcome has large right tail

Result
treatmentnoutlier_countoutlier_ratelower_boundupper_boundhas_outliersmethodtail
00732112920.176479-14058.5020273.50Trueiqrboth
1125942120.081727-61478.25110463.75Trueiqrboth
Result
confoundersmean_d_0mean_d_1abs_diffsmdks_pvalue
0inc32889.80248649366.97571316477.1732270.6621970.00000
1hown0.5891270.7652270.1761000.3834560.00000
2pira0.2002460.3604470.1602010.3624210.00000
3db0.2282480.3916730.1634260.3589680.00000
4twoearn0.3376590.5026990.1650400.3390960.00000
5educ12.99112113.8134160.8222940.2990610.00000
6marr0.5745120.6904390.1159280.2421750.00000
7age40.90097041.5096380.6086680.0601080.00000
8fsize2.8481082.9159600.0678520.0447310.00076

Treatment and control are unbalanced on all confounders except age and fsize; nonetheless, we retain age and fsize in the model to gain efficiency

Inference

Result
value
field
estimandATE
modelIRM
value11027.1737 (ci_abs: 8241.3361, 13813.0113)
value_relative79.0032 (ci_rel: 53.3308, 104.6757)
alpha0.0500
p_value0.0000
is_significantTrue
n_treated2594
n_control7321
treatment_mean38262.0605
control_mean10890.4771
time2026-02-20

Average Treatment Effect is significant and equals 12486.5221 (ci_abs: 9791.0517, 15181.9924)

Refutation

Unconfoundedness

Result
metricvalueflag
0balance_max_smd0.071103GREEN
1balance_frac_violations0.000000GREEN

Sensitivity

Result
r2_yr2_drhotheta_longtheta_shortdelta
p4010.0000389.626565e-081.011027.1736914961.333165-3934.159474
Result

{'theta': 11027.173690133526, 'se': 1421.3718379696486, 'alpha': 0.05, 'z': 1.959963984540054, 'H0': 0.0, 'sampling_ci': (8241.336079073513, 13813.01130119354), 'theta_bounds_cofounding': (11026.878096998567, 11027.469283268485), 'bias_aware_ci': (8241.052409910035, 13813.318820768469), 'max_bias_base': 154546.29526314724, 'max_bias': 0.29559313495817796, 'bound_width': 0.29559313495817796, 'sigma2': 3792734186.778151, 'nu2': 6.29745091623553, 'rv': 0.06659988318083149, 'rva': 0.05062630379913903, 'params': {'r2_y': 3.8e-05, 'r2_d': 9.626565e-08, 'rho': 1.0, 'use_signed_rr': False}}

SUTVA

Result

1.) Are your clients independent (i). Outcome of ones do not depend on others? 2.) Are all clients have full window to measure metrics? 3.) Do you measure confounders before treatment and outcome after? 4.) Do you have a consistent label of treatment, such as if a person does not receive a treatment, he has a label 0?

Score

Result
metricvalueflag
0se_plugin1.421372e+03NA
1psi_p99_over_med3.625835e+01RED
2psi_kurtosis1.700952e+02RED
3max_|t|_g13.709872e+00YELLOW
4max_|t|_g01.989905e+00GREEN
5max_|t|_m2.116322e+00YELLOW
6oos_tstat_fold2.643408e-16GREEN
7oos_tstat_strict1.982299e-16GREEN
Result

png

Result

png

Result

png

Overlap

Result

png

Result
metricvalueflag
0edge_0.01_below0.008472GREEN
1edge_0.01_above0.000000GREEN
2edge_0.02_below0.024307GREEN
3edge_0.02_above0.000000GREEN
4KS0.316022YELLOW
5AUC0.711829GREEN
6ESS_treated_ratio0.383340GREEN
7ESS_control_ratio0.903632GREEN
8tails_w1_q99/med7.777954YELLOW
9tails_w0_q99/med2.375994GREEN
10ATT_identity_relerr0.049028GREEN
11clip_m_total0.008472GREEN
12calib_ECE0.022127GREEN
13calib_slope0.798318YELLOW
14calib_intercept-0.163574GREEN
Result

png

We find no evidence of a violation of the overlap (positivity) assumption.

Conclution

There are problems with design: confounders are measured not before treatment. So treatment affected confounders. However estimate is robust and in real life participation in 401k is increasing net financial assets. To keep in mind real CI bounds may differ from our estimation