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)= 773.525
2020_REF_itax_rev($B)= 777.701
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.710 |
| Itemized Deduction ($b) | 751.927 |
| Standard Deduction Filers (#m) | 176.770 |
| Standard Deduction ($b) | 3076.650 |
| Personal Exemption ($b) | 0.000 |
| Taxable Income ($b) | 8619.446 |
| Regular Tax ($b) | 1498.020 |
| AMT Income ($b) | 7876.417 |
| AMT Liability ($b) | 0.493 |
| AMT Filers (#m) | 0.060 |
| Tax before Credits ($b) | 1498.514 |
| Refundable Credits ($b) | 638.295 |
| Nonrefundable Credits ($b) | 99.269 |
| Reform Surtaxes ($b) | 0.000 |
| Other Taxes ($b) | 75.874 |
| Ind Income Tax ($b) | 773.525 |
| Payroll Taxes ($b) | 1217.941 |
| Combined Liability ($b) | 1991.466 |
| With Income Tax <= 0 (#m) | 135.410 |
| With Combined Tax <= 0 (#m) | 97.110 |
| 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.640 |
| Itemized Deduction ($b) | 749.442 |
| Standard Deduction Filers (#m) | 176.850 |
| Standard Deduction ($b) | 3077.994 |
| Personal Exemption ($b) | 375.177 |
| Taxable Income ($b) | 8371.662 |
| Regular Tax ($b) | 1499.846 |
| AMT Income ($b) | 7879.108 |
| AMT Liability ($b) | 0.499 |
| AMT Filers (#m) | 0.060 |
| Tax before Credits ($b) | 1500.345 |
| Refundable Credits ($b) | 641.613 |
| Nonrefundable Credits ($b) | 93.606 |
| Reform Surtaxes ($b) | 0.000 |
| Other Taxes ($b) | 75.874 |
| Ind Income Tax ($b) | 777.701 |
| Payroll Taxes ($b) | 1217.941 |
| Combined Liability ($b) | 1995.642 |
| With Income Tax <= 0 (#m) | 137.570 |
| With Combined Tax <= 0 (#m) | 97.860 |
| 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.215491 | -25.215491 | 66.048435 | 66.048435 |
| 10-20 | 20.448902 | -51.033360 | -51.379856 | 306.922994 | 307.269490 |
| 20-30 | 20.447972 | -52.108361 | -53.124056 | 541.322300 | 542.337995 |
| 30-40 | 20.448551 | -44.354625 | -45.607079 | 715.655469 | 716.907923 |
| 40-50 | 20.448614 | -41.799605 | -43.510350 | 885.454944 | 887.165690 |
| 50-60 | 20.448520 | -37.680549 | -40.323118 | 1098.748895 | 1101.391464 |
| 60-70 | 20.448182 | -28.584357 | -32.247243 | 1379.848991 | 1383.511877 |
| 70-80 | 20.448218 | 3.962813 | -0.866496 | 1741.327674 | 1746.156983 |
| 80-90 | 20.447460 | 85.055506 | 76.871220 | 2292.697520 | 2300.881806 |
| 90-100 | 20.449858 | 982.914585 | 1010.734622 | 4742.729255 | 4714.909218 |
| ALL | 204.484164 | 773.525096 | 777.700692 | 13781.731202 | 13777.555605 |
| 90-95 | 10.225611 | 141.366846 | 135.815262 | 1532.636268 | 1538.187853 |
| 95-99 | 8.177219 | 320.487022 | 318.139847 | 1823.880447 | 1826.227622 |
| Top 1% | 2.047027 | 521.060717 | 556.779513 | 1386.212540 | 1350.493743 |
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.346496 | -16.944488 | 0.112894 |
| 20-30 | 20.447972 | -1.015695 | -49.672180 | 0.187632 |
| 30-40 | 20.448551 | -1.252454 | -61.249042 | 0.175008 |
| 40-50 | 20.448614 | -1.710746 | -83.660720 | 0.193205 |
| 50-60 | 20.448520 | -2.642569 | -129.230324 | 0.240507 |
| 60-70 | 20.448182 | -3.662886 | -179.130172 | 0.265456 |
| 70-80 | 20.448218 | -4.829309 | -236.172600 | 0.277335 |
| 80-90 | 20.447460 | -8.184286 | -400.259300 | 0.356972 |
| 90-100 | 20.449858 | 27.820037 | 1360.402501 | -0.586583 |
| ALL | 204.484164 | 4.175596 | 20.420144 | -0.030298 |
| 90-95 | 10.225611 | -5.551584 | -542.909800 | 0.362225 |
| 95-99 | 8.177219 | -2.347175 | -287.038246 | 0.128691 |
| Top 1% | 2.047027 | 35.718796 | 17449.105127 | -2.576719 |