Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom table recipe to Tax-Calculator Cookbook #1994

Merged
merged 5 commits into from
May 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/assumpA.json.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<title>assumpA.json</title><pre>
// NEVER SPECIFY BOTH behavior AND growdiff_response IN SAME RUN
{
"consumption": {
},
"behavior": {
// specify non-zero substitution elasticity of taxable income,
// which is response of taxable income to change in marginal tax rate
"_BE_sub": {"2013": [0.25]}
},
"growdiff_baseline": {
},
"growdiff_response": {
// MUST BE EMPTY BECAUSE ASSUMING BEHAVIORAL RESPONSE
}
}
</pre>
58 changes: 57 additions & 1 deletion docs/cookbook.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ <h2>Cookbook Contents</h2>

<p><a href="#recipe01">Directly Comparing Two Reforms</a></p>

<p>...more coming soon...</p>
<p><a href="#recipe02">Estimating Behavioral Response to Tax Reform</a></p>

<p><a href="#recipe03">Creating a Custom Table</a></p>


<h2 id="setup">Preliminaries: Kitchen Setup</h2>
Expand Down Expand Up @@ -226,6 +228,60 @@ <h2 id="recipe01">Advanced Recipe: Directly Comparing Two Reforms</h2>
<p><a href="#toc">Back to Cookbook Contents</a></p>


<h2 id="recipe02">Advanced Recipe: Estimating Behavioral Response
to Tax Reform</h2>

<p>This is an advanced recipe that should be followed only after
mastering the <a href="#recipe00">basic recipe</a>. This recipe
shows how to analyze the behavioral responses to a tax reform.</p>

<p><b>Ingredients</b></p>

<p><a href="reformA.json.html" target="_blank">Policy reform</a> in
the <kbd>ingredients/reformA.json</kbd> file.</p>

<p><a href="assumpA.json.html" target="_blank">Economic assumptions</a> in
the <kbd>ingredients/assumpA.json</kbd> file.</p>

<p><b>Instructions</b></p>

<p><a href="recipe02.py.html" target="_blank">Step-by-step
instructions</a> in the <kbd>recipe02.py</kbd> file.</p>

<p><b>Results</b></p>

<p><a href="recipe02.res.html" target="_blank">Expected text
results</a> from executing <kbd>python recipe02.py > recipe02.out</kbd> at
the command prompt as shown <a href="#execution">above</a>.</p>

<p><a href="#toc">Back to Cookbook Contents</a></p>


<h2 id="recipe03">Advanced Recipe: Creating a Custom Table</h2>

<p>This is an advanced recipe that should be followed only after
mastering the <a href="#recipe00">basic recipe</a>. This recipe
shows how to prepare a custom table.</p>

<p><b>Ingredients</b></p>

<p>No ingredients required because we conduct analysis under
current-law policy.</p>

<p><b>Instructions</b></p>

<p><a href="recipe03.py.html" target="_blank">Step-by-step
instructions</a> in the <kbd>recipe03.py</kbd> file.</p>

<p><b>Results</b></p>

<p><a href="recipe03.res.html" target="_blank">Expected text
results</a> from executing <kbd>python recipe03.py > recipe03.out</kbd> at
the command prompt as shown <a href="#execution">above</a>.</p>

<p><a href="#toc">Back to Cookbook Contents</a></p>


</div>
</body>
</html>
2 changes: 1 addition & 1 deletion docs/cookbook/recipe00.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import print_function # necessary only if using Python 2.7
from taxcalc import *

# use publicly-available CPS input file
# use publicly-available CPS input file including benefits
recs = Records.cps_constructor()
# 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
Expand Down
5 changes: 3 additions & 2 deletions docs/cookbook/recipe01.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@
cyr = 2018

# specify Calculator objects using policy1 and policy2 and calculate for cyr
calc1 = Calculator(policy=policy1, records=Records.cps_constructor())
recs = Records.cps_constructor()
calc1 = Calculator(policy=policy1, records=recs)
calc1.advance_to_year(cyr)
calc1.calc_all()
calc2 = Calculator(policy=policy2, records=Records.cps_constructor())
calc2 = Calculator(policy=policy2, records=recs)
calc2.advance_to_year(cyr)
calc2.calc_all()

Expand Down
4 changes: 2 additions & 2 deletions docs/cookbook/recipe02.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import print_function # necessary only if using Python 2.7
from taxcalc import *

# use publicly-available CPS input file
recs = Records.cps_constructor()
# use publicly-available CPS input file without including benefits
recs = Records.cps_constructor(no_benefits=True)

# specify Calculator object representing current-law policy
pol = Policy()
Expand Down
43 changes: 43 additions & 0 deletions docs/cookbook/recipe03.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import print_function # necessary only if using Python 2.7
from taxcalc import *

# use publicly-available CPS input file without including benefits
recs = Records.cps_constructor(no_benefits=True)

# specify Calculator object for static analysis of current-law policy
pol = Policy()
calc = Calculator(policy=pol, records=recs)

cyr = 2020

# calculate aggregate current-law income tax liabilities for cyr
calc.advance_to_year(cyr)
calc.calc_all()

# tabulate custom table showing number of filing units receiving EITC
# and the average positive EITC amount by IRS-SOI AGI categories
vardf = calc.dataframe(['s006', 'c00100', 'eitc'])
vardf = add_income_table_row_variable(vardf, 'c00100', SOI_AGI_BINS)
gbydf = vardf.groupby('table_row', as_index=False)

# print AGI table with ALL row at bottom
print('Filing Units Receiving EITC and Average Positive EITC by AGI category')
results = '{:23s}\t{:8.3f}\t{:8.3f}'
colhead = '{:23s}\t{:>8s}\t{:>8s}'
print(colhead.format('AGI category', 'Num(#M)', 'Avg($K)'))
tot_recips = 0.
tot_amount = 0.
idx = 0
for gname, grp in gbydf:
recips = grp[grp['eitc'] > 0]['s006'].sum() * 1e-6
tot_recips += recips
amount = (grp['eitc'] * grp['s006']).sum() * 1e-9
tot_amount += amount
if recips > 0:
avg = amount / recips
else:
avg = np.nan
print(results.format(gname, recips, avg))
idx += 1
avg = tot_amount / tot_recips
print(results.format('ALL', tot_recips, avg))
28 changes: 28 additions & 0 deletions docs/cookbook/recipe03.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
You loaded data for 2014.
Tax-Calculator startup automatically extrapolated your data to 2014.
WARNING: Tax-Calculator packages for Python 2.7 will
no longer be provided beginning in 2019
because Pandas is stopping development for 2.7
SOLUTION: upgrade to Python 3.6 now
Filing Units Receiving EITC and Average Positive EITC by AGI category
AGI category Num(#M) Avg($K)
[-9e+99, 1.0) 0.059 1.340
[1.0, 5000.0) 1.772 0.711
[5000.0, 10000.0) 3.672 1.638
[10000.0, 15000.0) 4.419 2.185
[15000.0, 20000.0) 3.178 3.479
[20000.0, 25000.0) 2.620 4.141
[25000.0, 30000.0) 2.405 3.853
[30000.0, 40000.0) 4.245 2.553
[40000.0, 50000.0) 2.414 1.341
[50000.0, 75000.0) 0.483 0.562
[75000.0, 100000.0) 0.000 nan
[100000.0, 200000.0) 0.000 nan
[200000.0, 500000.0) 0.000 nan
[500000.0, 1000000.0) 0.000 nan
[1000000.0, 1500000.0) 0.000 nan
[1500000.0, 2000000.0) 0.000 nan
[2000000.0, 5000000.0) 0.000 nan
[5000000.0, 10000000.0) 0.000 nan
[10000000.0, 9e+99) 0.000 nan
ALL 25.266 2.475
17 changes: 13 additions & 4 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,8 @@ <h2 id="params">Response Parameters</h2>

<p>This section contains documentation of several sets of parameters
that characterize responses to a tax reform. Consumption
parameters are used to compute marginal tax rates. Behavior
parameters are used to compute marginal tax rates and to compute the
consumption value of in-kind benefits. Behavior
parameters are used to compute changes in input variables caused by a
tax reform in a partial-equilibrium setting. Growdiff parameters are
used to specify baseline differences and/or reform responses in the
Expand All @@ -1217,11 +1218,19 @@ <h2 id="params">Response Parameters</h2>
dynamic response parameters control advanced features of
Tax-Calculator, so understanding the
<a href="https://github.com/open-source-economics/Tax-Calculator/tree/master/taxcalc">source
code</a> that uses them is essential. Each default parameter value is
zero and is projected into the future at that value, which implies no
code</a> that uses them is essential. Default response parameter values are
zero and are projected into the future at that value, which implies no
response to the reform. Using the default no-reform-response
assumption for all the response parameters generates a static analysis
of the tax reform.</p>
of the tax reform. The benefit value consumption parameters have a
default value of one, which implies the consumption value of the
in-kind benefits is equal to the government cost of providing the
benefits.</p>

<p>Note that some of the response parameters are incompatible with
each other, and therefore, cannot be used together. The behavior
parameters can not have non-zero values with specifying non-zero
growdiff response parameters.</p>


<h3>Section Contents</h3>
Expand Down
14 changes: 7 additions & 7 deletions docs/recipe00.graph.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/recipe00.py.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import print_function # necessary only if using Python 2.7
from taxcalc import *

# use publicly-available CPS input file
# use publicly-available CPS input file including benefits
recs = Records.cps_constructor()
# 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
Expand Down Expand Up @@ -56,7 +56,7 @@
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)
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()
Expand All @@ -67,7 +67,7 @@
dist_extract['aftertax_inc2($b)'] = dist_table2['aftertax_income'] * 1e-9

# income-tax difference table by expanded-income decile for cyr
diff_table = calc1.difference_table(calc2, tax_to_diff='iitax')
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',
Expand Down
7 changes: 4 additions & 3 deletions docs/recipe01.py.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@
cyr = 2018

# specify Calculator objects using policy1 and policy2 and calculate for cyr
calc1 = Calculator(policy=policy1, records=Records.cps_constructor())
recs = Records.cps_constructor()
calc1 = Calculator(policy=policy1, records=recs)
calc1.advance_to_year(cyr)
calc1.calc_all()
calc2 = Calculator(policy=policy2, records=Records.cps_constructor())
calc2 = Calculator(policy=policy2, records=recs)
calc2.advance_to_year(cyr)
calc2.calc_all()

Expand All @@ -47,7 +48,7 @@
iitax_rev2 = calc2.weighted_total('iitax')

# construct reform2-vs-reform1 difference table with results for income deciles
diff_table = calc1.difference_table(calc2, tax_to_diff='iitax')
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',
Expand Down
53 changes: 53 additions & 0 deletions docs/recipe02.py.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<title>recipe02.py</title><pre>
from __future__ import print_function # necessary only if using Python 2.7
from taxcalc import *

# use publicly-available CPS input file without including benefits
recs = Records.cps_constructor(no_benefits=True)

# specify Calculator object representing current-law policy
pol = Policy()
calc1 = Calculator(policy=pol, records=recs)

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 = './ingredients/reformA.json'
params = Calculator.read_json_param_objects(reform=reform_filename,
assump=None)

# specify Calculator object for static analysis of reform policy
pol.implement_reform(params['policy'])
calc2 = Calculator(policy=pol, records=recs)

# calculate reform income tax liabilities for cyr under static assumptions
calc2.advance_to_year(cyr)
calc2.calc_all()
itax_rev2 = calc2.weighted_total('iitax')

# read JSON reform file and (dynamic) behavioral-analysis assumptions
assump_filename = './ingredients/assumpA.json'
params = Calculator.read_json_param_objects(reform=reform_filename,
assump=assump_filename)
behv = Behavior()
behv.update_behavior(params['behavior'])

# specify Calculator object for behavioral-response analysis of reform policy
calc3 = Calculator(policy=pol, records=recs, behavior=behv)

# calculate reform income tax liabilities for cyr under dynamic assumptions
calc3.advance_to_year(cyr)
calc3br = Behavior.response(calc1, calc3)
itax_rev3 = calc3br.weighted_total('iitax')

# print total revenue estimates for cyr
# (estimates in billons of dollars rounded to nearest hundredth of a billion)
print('{}_CURRENT_LAW_P__itax_rev($B)= {:.2f}'.format(cyr, itax_rev1 * 1e-9))
print('{}_REFORM_STATIC__itax_rev($B)= {:.2f}'.format(cyr, itax_rev2 * 1e-9))
print('{}_REFORM_DYNAMIC_itax_rev($B)= {:.2f}'.format(cyr, itax_rev3 * 1e-9))
</pre>
23 changes: 23 additions & 0 deletions docs/recipe02.res.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<title>recipe02.res</title><pre>
You loaded data for 2014.
Tax-Calculator startup automatically extrapolated your data to 2014.
WARNING: Tax-Calculator packages for Python 2.7 will
no longer be provided beginning in 2019
because Pandas is stopping development for 2.7
SOLUTION: upgrade to Python 3.6 now
You loaded data for 2014.
Tax-Calculator startup automatically extrapolated your data to 2014.
WARNING: Tax-Calculator packages for Python 2.7 will
no longer be provided beginning in 2019
because Pandas is stopping development for 2.7
SOLUTION: upgrade to Python 3.6 now
You loaded data for 2014.
Tax-Calculator startup automatically extrapolated your data to 2014.
WARNING: Tax-Calculator packages for Python 2.7 will
no longer be provided beginning in 2019
because Pandas is stopping development for 2.7
SOLUTION: upgrade to Python 3.6 now
2020_CURRENT_LAW_P__itax_rev($B)= 1278.60
2020_REFORM_STATIC__itax_rev($B)= 1269.52
2020_REFORM_DYNAMIC_itax_rev($B)= 1261.18
</pre>
Loading