Skip to content

Commit

Permalink
Merge pull request #2002 from martinholmer/add-recipe
Browse files Browse the repository at this point in the history
Add charitable-giving-response recipe to cookbook
  • Loading branch information
martinholmer authored May 18, 2018
2 parents 38e1bbc + a438253 commit 936ddaf
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 12 deletions.
56 changes: 46 additions & 10 deletions docs/cookbook.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ <h1 id="toc">Cookbook of Tested Recipes for Python Programming with
<p>This document tells you how to use Tax-Calculator, an open-source
federal income and payroll tax simulation model, in Python scripts
that you can run on your own computer. Note that these recipes
require Tax-Calculator release 0.14.0 or higher. For other ways of
require Tax-Calculator release 0.20.0 or higher. For other ways of
using Tax-Calculator, see the
<a href="https://open-source-economics.github.io/Tax-Calculator/">
user documentation</a>, which this Cookbook assumes you have read.</p>
Expand Down Expand Up @@ -47,11 +47,13 @@ <h2>Cookbook Contents</h2>

<p><b>Advanced Recipes</b></p>

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

<p><a href="#recipe02">Estimating Behavioral Response to Tax Reform</a></p>
<p><a href="#recipe02">(2) Estimating Behavioral Response to Tax Reform</a></p>

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

<p><a href="#recipe04">(4) Estimating Reform Response by Earnings Group</a></p>


<h2 id="setup">Preliminaries: Kitchen Setup</h2>
Expand Down Expand Up @@ -200,7 +202,7 @@ <h2 id="recipe00">Basic Recipe: Static Analysis of a Simple Reform</h2>
<p><a href="#toc">Back to Cookbook Contents</a></p>


<h2 id="recipe01">Advanced Recipe: Directly Comparing Two Reforms</h2>
<h2 id="recipe01">Advanced Recipe: (1) Directly Comparing Two Reforms</h2>

<p>This is an advanced recipe that should be followed only after
mastering the <a href="#recipe00">basic recipe</a>. This recipe
Expand All @@ -223,12 +225,12 @@ <h2 id="recipe01">Advanced Recipe: Directly Comparing Two Reforms</h2>

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

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


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

<p>This is an advanced recipe that should be followed only after
Expand All @@ -252,12 +254,12 @@ <h2 id="recipe02">Advanced Recipe: Estimating Behavioral Response

<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>
the command prompt as illustrated <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>
<h2 id="recipe03">Advanced Recipe: (3) 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
Expand All @@ -277,7 +279,41 @@ <h2 id="recipe03">Advanced Recipe: Creating a Custom Table</h2>

<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>
the command prompt as illustrated <a href="#execution">above</a>.</p>

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


<h2 id="recipe04">Advanced Recipe: (4) Estimating Reform Response by Earnings Group</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 estimate the reform response in charitable giving when the
response elasticities vary by earnings group. It employs the groupby
technique used in the <a href="#recipe03">Creating a Custom Table</a>
recipe, so you might want to read that recipe first.</p>

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

<p><a href="reformB.json.html" target="_blank">Policy reform</a> in
the <kbd>ingredients/reformA.json</kbd> file. Note that this reform
increases the personal exemption amount (from zero where it is under
current-law policy) and decreases the standard deduction amounts (so
they are approximately where they were before the TCJA reform that is
now current-law policy). The lowering of the standard deduction
amounts generates several warning messages per year that can safely be
ignored.</p>

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

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

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

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

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

Expand Down
7 changes: 7 additions & 0 deletions docs/cookbook/ingredients/reformB.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Raise personal exemption and lower standard deduction beginning in 2020.
{
"policy": {
"_II_em": {"2020": [2000]},
"_STD": {"2020": [[6000, 12000, 6000, 9000, 12000]]}
}
}
4 changes: 2 additions & 2 deletions docs/cookbook/recipe03.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
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')
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)'))
print(colhead.format('AGI Category', 'Num(#M)', 'Avg($K)'))
tot_recips = 0.
tot_amount = 0.
idx = 0
Expand Down
82 changes: 82 additions & 0 deletions docs/cookbook/recipe04.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
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()
calc1 = Calculator(policy=pol, records=recs)

cyr = 2020

# calculate current-law tax liabilities for cyr
calc1.advance_to_year(cyr)
calc1.calc_all()

# calculate marginal tax rate wrt cash charitable giving
(_, _, mtr1) = calc1.mtr('e19800', calc_all_already_called=True,
wrt_full_compensation=False)

# read JSON reform file and use (the default) static analysis assumptions
reform_filename = './ingredients/reformB.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 tax liabilities for cyr
calc2.advance_to_year(cyr)
calc2.calc_all()

# calculate marginal tax rate wrt cash charitable giving
(_, _, mtr2) = calc2.mtr('e19800', calc_all_already_called=True,
wrt_full_compensation=False)

# extract variables needed for quantity_response utility function
# (note the aftertax price is 1+mtr because mtr wrt charity is non-positive)
vdf = calc1.dataframe(['s006', 'e19800', 'e00200'])
vdf['price1'] = 1.0 + mtr1
vdf['price2'] = 1.0 + mtr2
vdf['atinc1'] = calc1.array('aftertax_income')
vdf['atinc2'] = calc2.array('aftertax_income')

# group filing units into earnings groups with different response elasticities
# (note earnings groups are just an example based on no empirical results)
earnings_bins = [-9e99, 50e3, 9e99] # two groups: below and above $50,000
vdf = add_income_table_row_variable(vdf, 'e00200', earnings_bins)
gbydf = vdf.groupby('table_row', as_index=False)

# compute percentage response in charitable giving
# (note elasticity values are just an example based on no empirical results)
price_elasticity = [-0.1, -0.4]
income_elasticity = [0.1, 0.1]
print('\nResponse in Charitable Giving by Earnings Group')
results = '{:18s}\t{:8.3f}\t{:8.3f}\t{:8.2f}'
colhead = '{:18s}\t{:>8s}\t{:>8s}\t{:>8s}'
print(colhead.format('Earnings Group', 'Num(#M)', 'Resp($B)', 'Resp(%)'))
tot_funits = 0.
tot_response = 0.
tot_baseline = 0.
idx = 0
for gname, grp in gbydf:
funits = grp['s006'].sum() * 1e-6
tot_funits += funits
response = quantity_response(grp['e19800'],
price_elasticity[idx],
grp['price1'],
grp['price2'],
income_elasticity[idx],
grp['atinc1'],
grp['atinc2'])
grp_response = (response * grp['s006']).sum() * 1e-9
tot_response += grp_response
grp_baseline = (grp['e19800'] * grp['s006']).sum() * 1e-9
tot_baseline += grp_baseline
pct_response = 100. * grp_response / grp_baseline
print(results.format(gname, funits, grp_response, pct_response))
idx += 1
pct_response = 100. * tot_response / tot_baseline
print(results.format('ALL', tot_funits, tot_response, pct_response))
59 changes: 59 additions & 0 deletions docs/cookbook/recipe04.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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
WARNING: 2020 _STD_0 value 6000.0 < min value 12390.92
WARNING: 2020 _STD_1 value 12000.0 < min value 24881.84
WARNING: 2020 _STD_2 value 6000.0 < min value 12390.92
WARNING: 2020 _STD_3 value 9000.0 < min value 18636.38
WARNING: 2020 _STD_4 value 12000.0 < min value 24881.84
WARNING: 2021 _STD_0 value 6127.8 < min value 12656.98
WARNING: 2021 _STD_1 value 12255.6 < min value 25413.95
WARNING: 2021 _STD_2 value 6127.8 < min value 12656.98
WARNING: 2021 _STD_3 value 9191.7 < min value 19035.46
WARNING: 2021 _STD_4 value 12255.6 < min value 25413.95
WARNING: 2022 _STD_0 value 6261.39 < min value 12935.08
WARNING: 2022 _STD_1 value 12522.77 < min value 25970.15
WARNING: 2022 _STD_2 value 6261.39 < min value 12935.08
WARNING: 2022 _STD_3 value 9392.08 < min value 19452.61
WARNING: 2022 _STD_4 value 12522.77 < min value 25970.15
WARNING: 2023 _STD_0 value 6394.13 < min value 13211.42
WARNING: 2023 _STD_1 value 12788.25 < min value 26522.84
WARNING: 2023 _STD_2 value 6394.13 < min value 13211.42
WARNING: 2023 _STD_3 value 9591.19 < min value 19867.13
WARNING: 2023 _STD_4 value 12788.25 < min value 26522.84
WARNING: 2024 _STD_0 value 6531.6 < min value 13497.62
WARNING: 2024 _STD_1 value 13063.2 < min value 27095.23
WARNING: 2024 _STD_2 value 6531.6 < min value 13497.62
WARNING: 2024 _STD_3 value 9797.4 < min value 20296.42
WARNING: 2024 _STD_4 value 13063.2 < min value 27095.23
WARNING: 2025 _STD_0 value 6670.72 < min value 13787.25
WARNING: 2025 _STD_1 value 13341.45 < min value 27674.49
WARNING: 2025 _STD_2 value 6670.72 < min value 13787.25
WARNING: 2025 _STD_3 value 10006.08 < min value 20730.86
WARNING: 2025 _STD_4 value 13341.45 < min value 27674.49
WARNING: 2026 _STD_0 value 6812.81 < min value 7555.0
WARNING: 2026 _STD_1 value 13625.62 < min value 15211.0
WARNING: 2026 _STD_2 value 6812.81 < min value 7555.0
WARNING: 2026 _STD_3 value 10219.21 < min value 11172.0
WARNING: 2026 _STD_4 value 13625.62 < min value 15211.0
WARNING: 2027 _STD_0 value 6959.29 < min value 7719.58
WARNING: 2027 _STD_1 value 13918.57 < min value 15540.19
WARNING: 2027 _STD_2 value 6959.29 < min value 7719.58
WARNING: 2027 _STD_3 value 10438.92 < min value 11414.35
WARNING: 2027 _STD_4 value 13918.57 < min value 15540.19

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

Response in Charitable Giving by Earnings Group
Earnings Group Num(#M) Resp($B) Resp(%)
[-9e+99, 50000.0) 115.196 0.641 0.59
[50000.0, 9e+99) 59.317 3.478 2.05
ALL 174.513 4.118 1.48

0 comments on commit 936ddaf

Please sign in to comment.