Recipe 1: Directly Comparing Two Reforms
Recipe 1: Directly Comparing Two Reforms¶
This is an advanced recipe that should be followed only after mastering the basic recipe. This recipe shows how to compare two reforms (instead of comparing a reform to current-law policy) and also shows how to use the reform files available on the Tax-Calculator website (instead of reform files on your computer’s disk).
import pandas as pd
import taxcalc as tc
# read an "old" reform file
# ("old" means the reform file is defined relative to pre-TCJA policy)
# specify reform dictionary for pre-TCJA policy
reform1 = tc.Policy.read_json_reform('github://PSLmodels:[email protected]/psl_examples/taxcalc/2017_law.json')
# specify reform dictionary for TCJA as passed by Congress in late 2017
reform2 = tc.Policy.read_json_reform('github://PSLmodels:[email protected]/psl_examples/taxcalc/TCJA.json')
# specify Policy object for pre-TCJA policy
bpolicy = tc.Policy()
bpolicy.implement_reform(reform1, print_warnings=False, raise_errors=False)
assert not bpolicy.parameter_errors
# specify Policy object for TCJA reform relative to pre-TCJA policy
rpolicy = tc.Policy()
rpolicy.implement_reform(reform1, print_warnings=False, raise_errors=False)
assert not rpolicy.parameter_errors
rpolicy.implement_reform(reform2, print_warnings=False, raise_errors=False)
assert not rpolicy.parameter_errors
# specify Calculator objects using bpolicy and rpolicy
recs = tc.Records.cps_constructor()
calc1 = tc.Calculator(policy=bpolicy, records=recs)
calc2 = tc.Calculator(policy=rpolicy, records=recs)
CYR = 2018
# calculate for specified CYR
calc1.advance_to_year(CYR)
calc1.calc_all()
calc2.advance_to_year(CYR)
calc2.calc_all()
# compare aggregate individual income tax revenue in cyr
iitax_rev1 = calc1.weighted_total('iitax')
iitax_rev2 = calc2.weighted_total('iitax')
# construct reform-vs-baseline difference table with results for income deciles
diff_table = calc1.difference_table(calc2, 'weighted_deciles', 'iitax')
assert isinstance(diff_table, pd.DataFrame)
diff_extract = pd.DataFrame()
dif_colnames = ['count', 'tax_cut', 'tax_inc',
'tot_change', 'mean', 'pc_aftertaxinc']
ext_colnames = ['funits(#m)', 'taxfall(#m)', 'taxrise(#m)',
'agg_diff($b)', 'mean_diff($)', 'aftertax_income_diff(%)']
for dname, ename in zip(dif_colnames, ext_colnames):
diff_extract[ename] = diff_table[dname]
# print total revenue estimates for cyr
# (estimates in billons of dollars)
print('{}_REFORM1_iitax_rev($B)= {:.3f}'.format(CYR, iitax_rev1 * 1e-9))
print('{}_REFORM2_iitax_rev($B)= {:.3f}'.format(CYR, iitax_rev2 * 1e-9))
print('')
2018_REFORM1_iitax_rev($B)= 1361.859
2018_REFORM2_iitax_rev($B)= 1195.985
Print reform2-vs-reform1 difference table
title = 'Extract of {} income-tax difference table by expanded-income decile'
print(title.format(CYR))
print('(taxfall is count of funits with cut in income tax in reform 2 vs 1)')
print('(taxrise is count of funits with rise in income tax in reform 2 vs 1)')
print(diff_extract.to_string())
Extract of 2018 income-tax difference table by expanded-income decile
(taxfall is count of funits with cut in income tax in reform 2 vs 1)
(taxrise is count of funits with rise in income tax in reform 2 vs 1)
funits(#m) taxfall(#m) taxrise(#m) agg_diff($b) mean_diff($) aftertax_income_diff(%)
0-10n 0.099742 0.000000 0.000000 0.000000 0.000000 0.000000
0-10z 8.084653 0.000000 0.000000 0.000000 0.000000 NaN
0-10p 11.735831 0.169713 0.011669 -0.011944 -1.017723 0.031206
10-20 19.920848 6.251255 2.881016 -0.773067 -38.806919 0.322054
20-30 19.920146 10.132046 2.388090 -1.883900 -94.572577 0.416365
30-40 19.920561 9.240418 2.014589 -3.487296 -175.060155 0.568270
40-50 19.919924 11.020755 2.138903 -5.811243 -291.730166 0.764024
50-60 19.922029 13.167126 2.068208 -8.677719 -435.584083 0.915270
60-70 19.920346 14.128191 1.779769 -11.880010 -596.375656 0.992884
70-80 19.917057 15.548090 1.521095 -17.000687 -853.574274 1.121701
80-90 19.923101 16.962688 1.655445 -26.051354 -1307.595365 1.292798
90-100 19.922247 18.151020 1.515929 -90.296172 -4532.429038 2.135099
ALL 199.206484 114.771304 17.974713 -165.873391 -832.670642 1.381894
90-95 9.961787 8.958237 0.772773 -22.392938 -2247.883726 1.646793
95-99 7.965885 7.393762 0.547601 -37.425665 -4698.243304 2.281880
Top 1% 1.994576 1.799021 0.195555 -30.477569 -15280.226295 2.479426