# Recipe 2: Estimating Behavioral Response to ReformΒΆ

This is an advanced recipe that should be followed only after mastering the basic recipe. This recipe shows how to analyze the behavioral responses to a tax reform using the Behavioral-Responses behresp package.

```import taxcalc as tc
import behresp

# use publicly-available CPS input file
recs = tc.Records.cps_constructor()

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

CYR = 2020

# calculate aggregate current-law income tax liabilities for cyr
calc1.calc_all()
itax_rev1 = calc1.weighted_total('iitax')

# specify Calculator object for static analysis of reform policy
calc2 = tc.Calculator(policy=pol, records=recs)

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

# specify assumed non-zero response-function substitution elasticity
response_elasticities = {'sub': 0.25}

# specify Calculator object for analysis of reform with behavioral responses
calc2 = tc.Calculator(policy=pol, records=recs)
_, df2br = behresp.response(calc1, calc2, response_elasticities)

# calculate reform income tax liabilities for CYR with behavioral response
itax_rev2br = (df2br['iitax'] * df2br['s006']).sum()

# print total income tax revenue estimates for CYR
# (estimates in billons of dollars)
print('{}_CURRENT_LAW_P__itax_rev(\$B)= {:.3f}'.format(CYR, itax_rev1 * 1e-9))
print('{}_REFORM_STATIC__itax_rev(\$B)= {:.3f}'.format(CYR, itax_rev2sa * 1e-9))
print('{}_REFORM_DYNAMIC_itax_rev(\$B)= {:.3f}'.format(CYR, itax_rev2br * 1e-9))
```
```---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-2-e3f4917dd976> in <module>
17
18 # specify Calculator object for static analysis of reform policy
20 calc2 = tc.Calculator(policy=pol, records=recs)
21

~/work/Tax-Calculator/Tax-Calculator/taxcalc/policy.py in implement_reform(self, reform, print_warnings, raise_errors)
119         """
120         # need to do conversion:
--> 121         return self._update(reform, print_warnings, raise_errors)
122
123     @staticmethod

~/work/Tax-Calculator/Tax-Calculator/taxcalc/parameters.py in _update(self, revision, print_warnings, raise_errors)
663                     None
664                 )
666             new_params,
667             print_warnings=print_warnings,

~/work/Tax-Calculator/Tax-Calculator/taxcalc/parameters.py in adjust(self, params_or_path, print_warnings, raise_errors, **kwargs)
174             # defer related-parameter validation until all intermediate updates
175             # are complete.
--> 176             with self.transaction(
177                 defer_validation=True,
178                 raise_errors=True,

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/contextlib.py in __enter__(self)
111         del self.args, self.kwds, self.func
112         try:
--> 113             return next(self.gen)
114         except StopIteration:
115             raise RuntimeError("generator didn't yield") from None

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/site-packages/paramtools/parameters.py in transaction(self, defer_validation, raise_errors, ignore_warnings)
420             - `raise_errors`: Either raise errors or simply store the error messages.
421         """
--> 422         _data = copy.deepcopy(self._data)
423         _ops = dict(self.operators)
424         _state = dict(self.view_state())

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
170                     y = x
171                 else:
--> 172                     y = _reconstruct(x, memo, *rv)
173
174     # If is its own copy, don't memoize.

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
294             for key, value in dictiter:
295                 key = deepcopy(key, memo)
--> 296                 value = deepcopy(value, memo)
297                 y[key] = value
298         else:

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
170                     y = x
171                 else:
--> 172                     y = _reconstruct(x, memo, *rv)
173
174     # If is its own copy, don't memoize.

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
294             for key, value in dictiter:
295                 key = deepcopy(key, memo)
--> 296                 value = deepcopy(value, memo)
297                 y[key] = value
298         else:

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
144     copier = _deepcopy_dispatch.get(cls)
145     if copier is not None:
--> 146         y = copier(x, memo)
147     else:
148         if issubclass(cls, type):

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in _deepcopy_list(x, memo, deepcopy)
203     append = y.append
204     for a in x:
--> 205         append(deepcopy(a, memo))
206     return y
207 d[list] = _deepcopy_list

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
170                     y = x
171                 else:
--> 172                     y = _reconstruct(x, memo, *rv)
173
174     # If is its own copy, don't memoize.

/usr/share/miniconda/envs/taxcalc-dev/lib/python3.8/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
262     if deep and args:
263         args = (deepcopy(arg, memo) for arg in args)
--> 264     y = func(*args)
265     if deep:
266         memo[id(x)] = y

KeyboardInterrupt:
```

Create multi-year diagnostic tables for

1. baseline,

2. reform excluding behavioral responses, and

3. reform including behavioral responses

```NUM_YEARS = 3  # number of diagnostic table years beginning with CYR
dtable1 = calc1.diagnostic_table(NUM_YEARS)
dtable2 = calc2.diagnostic_table(NUM_YEARS)
dvar_list3 = list()
year_list3 = list()
for year in range(CYR, CYR + NUM_YEARS):
_, df2br = behresp.response(calc1, calc2, response_elasticities)
dvar_list3.append(df2br)
year_list3.append(year)
dtable3 = tc.create_diagnostic_table(dvar_list3, year_list3)
```

Diagnostic table for baseline:

```dtable1
```
2020 2021 2022
Returns (#m) 205.440 208.140 210.820
AGI (\$b) 11475.571 11691.366 12219.492
Itemizers (#m) 30.950 29.170 30.670
Itemized Deduction (\$b) 824.019 760.366 809.757
Standard Deduction Filers (#m) 174.490 178.960 180.140
Standard Deduction (\$b) 3188.464 3289.501 3344.937
Personal Exemption (\$b) 0.000 0.000 0.000
Taxable Income (\$b) 8513.062 8731.100 9177.528
Regular Tax (\$b) 1505.162 1544.527 1635.569
AMT Income (\$b) 10856.448 11122.136 11611.624
AMT Liability (\$b) 0.923 0.883 0.902
AMT Filers (#m) 0.420 0.440 0.440
Tax before Credits (\$b) 1506.085 1545.410 1636.472
Refundable Credits (\$b) 103.539 867.141 102.528
Nonrefundable Credits (\$b) 94.954 3.935 98.942
Reform Surtaxes (\$b) 0.000 0.000 0.000
Other Taxes (\$b) 13.895 12.309 13.109
Ind Income Tax (\$b) 1321.487 686.642 1448.110
Payroll Taxes (\$b) 1186.745 1213.929 1267.083
Combined Liability (\$b) 2508.233 1900.571 2715.194
With Income Tax <= 0 (#m) 101.340 136.280 102.410
With Combined Tax <= 0 (#m) 69.360 106.330 71.670
UBI Benefits (\$b) 0.000 0.000 0.000
Total Benefits, Consumption Value (\$b) 3650.123 3871.611 4112.506
Total Benefits Cost (\$b) 3650.123 3871.611 4112.506

Diagnostic table for reform, excluding behavioral responses:

```dtable2
```
2020 2021 2022
Returns (#m) 205.440 208.140 210.820
AGI (\$b) 11475.571 11691.366 12219.492
Itemizers (#m) 30.860 29.100 30.580
Itemized Deduction (\$b) 821.244 757.934 807.273
Standard Deduction Filers (#m) 174.580 179.040 180.230
Standard Deduction (\$b) 3190.011 3290.859 3346.410
Personal Exemption (\$b) 387.209 394.699 403.152
Taxable Income (\$b) 8274.064 8486.881 8927.069
Regular Tax (\$b) 1511.260 1550.256 1643.269
AMT Income (\$b) 10859.047 11124.396 11613.962
AMT Liability (\$b) 0.978 0.964 0.978
AMT Filers (#m) 0.450 0.450 0.460
Tax before Credits (\$b) 1512.239 1551.220 1644.247
Refundable Credits (\$b) 106.802 867.141 106.097
Nonrefundable Credits (\$b) 89.372 3.728 93.371
Reform Surtaxes (\$b) 0.000 0.000 0.000
Other Taxes (\$b) 13.895 12.309 13.109
Ind Income Tax (\$b) 1329.959 692.660 1457.889
Payroll Taxes (\$b) 1186.745 1213.929 1267.083
Combined Liability (\$b) 2516.705 1906.589 2724.972
With Income Tax <= 0 (#m) 103.730 138.010 104.890
With Combined Tax <= 0 (#m) 69.930 107.270 72.360
UBI Benefits (\$b) 0.000 0.000 0.000
Total Benefits, Consumption Value (\$b) 3650.123 3871.611 4112.506
Total Benefits Cost (\$b) 3650.123 3871.611 4112.506

Diagnostic table for reform, including behavioral responses:

```dtable3
```
2020 2021 2022
Returns (#m) 205.440 208.140 210.820
AGI (\$b) 11445.873 11659.522 12185.655
Itemizers (#m) 30.830 29.070 30.560
Itemized Deduction (\$b) 819.497 756.391 805.450
Standard Deduction Filers (#m) 174.620 179.060 180.260
Standard Deduction (\$b) 3190.774 3291.311 3347.043
Personal Exemption (\$b) 387.209 394.699 403.152
Taxable Income (\$b) 8245.048 8455.598 8893.866
Regular Tax (\$b) 1498.246 1536.636 1628.637
AMT Income (\$b) 10830.848 11093.908 11581.700
AMT Liability (\$b) 0.990 0.984 1.007
AMT Filers (#m) 0.440 0.450 0.460
Tax before Credits (\$b) 1499.236 1537.620 1629.644
Refundable Credits (\$b) 106.529 867.114 105.817
Nonrefundable Credits (\$b) 89.619 3.744 93.623
Reform Surtaxes (\$b) 0.000 0.000 0.000
Other Taxes (\$b) 13.579 12.004 12.784
Ind Income Tax (\$b) 1316.667 678.766 1442.988
Payroll Taxes (\$b) 1185.888 1212.854 1266.008
Combined Liability (\$b) 2502.555 1891.620 2708.996
With Income Tax <= 0 (#m) 103.580 137.980 104.690
With Combined Tax <= 0 (#m) 69.730 107.250 72.170
UBI Benefits (\$b) 0.000 0.000 0.000
Total Benefits, Consumption Value (\$b) 3650.123 3871.611 4112.506
Total Benefits Cost (\$b) 3650.123 3871.611 4112.506