Basic Recipe: Static Analysis of a Simple Reform#
This is the recipe you should follow first. Mastering this recipe is a prerequisite for all the other recipes in this cookbook.
Imports#
import taxcalc as tc
import pandas as pd
from bokeh.io import show, output_notebook
Setup#
Use publicly-available CPS input file.
NOTE: if you have access to the restricted-use IRS-SOI PUF-based input file and you have that file (named ‘puf.csv’) located in the directory where this script is located, then you can substitute the following statement for the prior statement:
recs = tc.Records()
recs = tc.Records.cps_constructor()
Specify Calculator object for static analysis of current-law policy.
pol = tc.Policy()
calc1 = tc.Calculator(policy=pol, records=recs)
NOTE: calc1 now contains a PRIVATE COPY of pol and a PRIVATE COPY of recs, so we can continue to use pol and recs in this script without any concern about side effects from Calculator method calls on calc1.
CYR = 2020
Calculate aggregate current-law income tax liabilities for CYR.
calc1.advance_to_year(CYR)
calc1.calc_all()
itax_rev1 = calc1.weighted_total('iitax')
Read JSON reform file and use (the default) static analysis assumptions.
reform_filename = 'github://PSLmodels:Tax-Calculator@master/docs/recipes/_static/reformA.json'
params = tc.Calculator.read_json_param_objects(reform_filename, None)
Specify Calculator object for static analysis of reform policy.
pol.implement_reform(params['policy'])
calc2 = tc.Calculator(policy=pol, records=recs)
Calculate#
Calculate reform income tax liabilities for CYR.
calc2.advance_to_year(CYR)
calc2.calc_all()
itax_rev2 = calc2.weighted_total('iitax')
Results#
Print total revenue estimates for 2018.
Estimates in billons of dollars rounded to nearest hundredth of a billion.
print('{}_CLP_itax_rev($B)= {:.3f}'.format(CYR, itax_rev1 * 1e-9))
print('{}_REF_itax_rev($B)= {:.3f}'.format(CYR, itax_rev2 * 1e-9))
2020_CLP_itax_rev($B)= 819.616
2020_REF_itax_rev($B)= 823.808
Generate several other standard results tables.
# Aggregate diagnostic tables for CYR.
clp_diagnostic_table = calc1.diagnostic_table(1)
ref_diagnostic_table = calc2.diagnostic_table(1)
# Income-tax distribution for CYR with CLP and REF results side-by-side.
dist_table1, dist_table2 = calc1.distribution_tables(calc2, 'weighted_deciles')
assert isinstance(dist_table1, pd.DataFrame)
assert isinstance(dist_table2, pd.DataFrame)
dist_extract = pd.DataFrame()
dist_extract['funits(#m)'] = dist_table1['count']
dist_extract['itax1($b)'] = dist_table1['iitax']
dist_extract['itax2($b)'] = dist_table2['iitax']
dist_extract['aftertax_inc1($b)'] = dist_table1['aftertax_income']
dist_extract['aftertax_inc2($b)'] = dist_table2['aftertax_income']
# Income-tax difference table by expanded-income decile for CYR.
diff_table = calc1.difference_table(calc2, 'weighted_deciles', 'iitax')
assert isinstance(diff_table, pd.DataFrame)
diff_extract = pd.DataFrame()
dif_colnames = ['count', 'tot_change', 'mean', 'pc_aftertaxinc']
ext_colnames = ['funits(#m)', 'agg_diff($b)', 'mean_diff($)', 'aftertaxinc_diff(%)']
for dname, ename in zip(dif_colnames, ext_colnames):
diff_extract[ename] = diff_table[dname]
Plotting#
Generate a decile graph and display it using Bokeh (will render in Jupyter, not in webpage).
Print tables#
CLP diagnostic table for CYR.
clp_diagnostic_table
| 2020 | |
|---|---|
| Returns (#m) | 204.480 |
| AGI ($b) | 11572.622 |
| Itemizers (#m) | 27.450 |
| Itemized Deduction ($b) | 745.193 |
| Standard Deduction Filers (#m) | 176.920 |
| Standard Deduction ($b) | 3081.007 |
| Personal Exemption ($b) | 0.000 |
| Taxable Income ($b) | 8615.647 |
| Regular Tax ($b) | 1497.472 |
| AMT Income ($b) | 7876.981 |
| AMT Liability ($b) | 0.493 |
| AMT Filers (#m) | 0.060 |
| Tax before Credits ($b) | 1497.966 |
| Refundable Credits ($b) | 655.024 |
| Nonrefundable Credits ($b) | 99.200 |
| Reform Surtaxes ($b) | 0.000 |
| Other Taxes ($b) | 75.874 |
| Ind Income Tax ($b) | 819.616 |
| Payroll Taxes ($b) | 1154.642 |
| Combined Liability ($b) | 1974.257 |
| With Income Tax <= 0 (#m) | 133.140 |
| With Combined Tax <= 0 (#m) | 98.180 |
| UBI Benefits ($b) | 0.000 |
| Total Benefits, Consumption Value ($b) | 3617.042 |
| Total Benefits Cost ($b) | 3617.042 |
REF diagnostic table for CYR.
ref_diagnostic_table
| 2020 | |
|---|---|
| Returns (#m) | 204.480 |
| AGI ($b) | 11572.622 |
| Itemizers (#m) | 27.370 |
| Itemized Deduction ($b) | 742.660 |
| Standard Deduction Filers (#m) | 177.000 |
| Standard Deduction ($b) | 3082.379 |
| Personal Exemption ($b) | 375.177 |
| Taxable Income ($b) | 8367.955 |
| Regular Tax ($b) | 1499.314 |
| AMT Income ($b) | 7879.688 |
| AMT Liability ($b) | 0.499 |
| AMT Filers (#m) | 0.060 |
| Tax before Credits ($b) | 1499.813 |
| Refundable Credits ($b) | 658.341 |
| Nonrefundable Credits ($b) | 93.538 |
| Reform Surtaxes ($b) | 0.000 |
| Other Taxes ($b) | 75.874 |
| Ind Income Tax ($b) | 823.808 |
| Payroll Taxes ($b) | 1154.642 |
| Combined Liability ($b) | 1978.450 |
| With Income Tax <= 0 (#m) | 135.250 |
| With Combined Tax <= 0 (#m) | 98.940 |
| UBI Benefits ($b) | 0.000 |
| Total Benefits, Consumption Value ($b) | 3617.042 |
| Total Benefits Cost ($b) | 3617.042 |
Extract of CYR distribution tables by baseline expanded-income decile.
dist_extract
| funits(#m) | itax1($b) | itax2($b) | aftertax_inc1($b) | aftertax_inc2($b) | |
|---|---|---|---|---|---|
| 0-10n | 0.103662 | -0.292423 | -0.292423 | -6.364313 | -6.364313 |
| 0-10z | 8.289516 | -17.339037 | -17.339037 | 17.339037 | 17.339037 |
| 0-10p | 12.054710 | -25.550068 | -25.550068 | 66.416417 | 66.416417 |
| 10-20 | 20.448902 | -52.267633 | -52.614071 | 308.445163 | 308.791601 |
| 20-30 | 20.447972 | -52.555753 | -53.570845 | 542.859235 | 543.874327 |
| 30-40 | 20.448551 | -42.954619 | -44.205712 | 718.143120 | 719.394213 |
| 40-50 | 20.448614 | -40.575299 | -42.283651 | 888.361287 | 890.069640 |
| 50-60 | 20.448520 | -34.576096 | -37.215626 | 1101.059851 | 1103.699381 |
| 60-70 | 20.448182 | -25.195338 | -28.856025 | 1382.305265 | 1385.965952 |
| 70-80 | 20.448218 | 6.748732 | 1.921132 | 1743.439567 | 1748.267167 |
| 80-90 | 20.447460 | 92.531134 | 84.353496 | 2293.838411 | 2302.016048 |
| 90-100 | 20.449858 | 1011.642048 | 1039.461214 | 4743.097081 | 4715.277914 |
| ALL | 204.484164 | 819.615646 | 823.808384 | 13798.940122 | 13794.747384 |
| 90-95 | 10.225611 | 146.772369 | 141.221308 | 1532.923116 | 1538.474176 |
| 95-99 | 8.177219 | 331.108319 | 328.760896 | 1823.948871 | 1826.296294 |
| Top 1% | 2.047027 | 533.761360 | 569.479010 | 1386.225094 | 1350.507444 |
Extract of CYR income-tax difference table by expanded-income decile.
diff_extract
| funits(#m) | agg_diff($b) | mean_diff($) | aftertaxinc_diff(%) | |
|---|---|---|---|---|
| 0-10n | 0.103662 | 0.000000 | 0.000000 | 0.000000 |
| 0-10z | 8.289516 | 0.000000 | 0.000000 | 0.000000 |
| 0-10p | 12.054710 | 0.000000 | 0.000000 | 0.000000 |
| 10-20 | 20.448902 | -0.346437 | -16.941614 | 0.112317 |
| 20-30 | 20.447972 | -1.015092 | -49.642681 | 0.186990 |
| 30-40 | 20.448551 | -1.251093 | -61.182482 | 0.174212 |
| 40-50 | 20.448614 | -1.708352 | -83.543663 | 0.192304 |
| 50-60 | 20.448520 | -2.639530 | -129.081712 | 0.239726 |
| 60-70 | 20.448182 | -3.660687 | -179.022607 | 0.264825 |
| 70-80 | 20.448218 | -4.827599 | -236.088993 | 0.276901 |
| 80-90 | 20.447460 | -8.177638 | -399.934175 | 0.356505 |
| 90-100 | 20.449858 | 27.819167 | 1360.359929 | -0.586519 |
| ALL | 204.484164 | 4.192738 | 20.503974 | -0.030384 |
| 90-95 | 10.225611 | -5.551060 | -542.858546 | 0.362123 |
| 95-99 | 8.177219 | -2.347423 | -287.068625 | 0.128700 |
| Top 1% | 2.047027 | 35.717650 | 17448.545148 | -2.576613 |