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

Function to modify a reform #1802

Closed
MaxGhenis opened this issue Dec 31, 2017 · 5 comments
Closed

Function to modify a reform #1802

MaxGhenis opened this issue Dec 31, 2017 · 5 comments

Comments

@MaxGhenis
Copy link
Contributor

MaxGhenis commented Dec 31, 2017

I'm working on analyses that involve modifying reforms, for example removing deductions, and adding UBI to existing reforms. The UBI amount will be calculated in my script (to be revenue-neutral), so I'd like to be able to modify the reform on-the-fly. The ideal would be something like:

pol.modify_param(param='_UBI1', value=1000, year=2018)

Where pol is an existing reform, e.g. TCJA.

Looking through policy.py and parameters.py I don't a way to do this.

While the current motivation of seeing how things change under TCJA will soon be irrelevant, I think this would be a broadly useful tool for sensitivity analysis among proposed reforms.

@martinholmer
Copy link
Collaborator

martinholmer commented Jan 2, 2018

@MaxGhenis said:

I'm working on analyses that involve modifying reforms, for example removing deductions, and adding UBI to existing reforms. The UBI amount will be calculated in my script (to be revenue-neutral), so I'd like to be able to modify the reform on-the-fly. The ideal would be something like:

pol.modify_param(param='_UBI1', value=1000, year=2018)

Where pol is an existing reform, e.g. TCJA.

Looking through policy.py and parameters.py I don't a way to do this.

While the current motivation of seeing how things change under TCJA will soon be irrelevant, I think this would be a broadly useful tool for sensitivity analysis among proposed reforms.

I agree with you, @MaxGhenis, that the ability to implement a "compound reform" (consisting of two simple reforms) will be "broadly useful." However, I don't think Tax-Calculator needs any enhancements to do what you want to do. My understanding is that there are no problems calling implement_reform twice for the same Policy object. If you have problems with the approach I outline below (which has been used extensively in pull request #1803), please raise another issue. Meanwhile, I'm closing this issue.

The (untested) example below assumes use of Tax-Calculator release 0.14.3, the last in which pre-TCJA policy is current-law policy. It also assumes that the "policy" dictionary derived from the reforms/TCJA_Reconciliation.json file is called `tcja_reform'.

pol = Policy()
pol.implement_reform(tcja_reform)
ubi_reform = {2018: {'_UBI1': [2500], '_UBI2': [10000], '_UBI3': [10000]}}
pol.implement_reform(ubi_reform)

@MaxGhenis
Copy link
Contributor Author

Terrific, thank you @martinholmer! I used this to considerably simplify a charitable deduction analysis (commit) and verified it produces identical results to creating my own separate reforms.

@martinholmer
Copy link
Collaborator

@MaxGhenis, thanks for the feedback on your experience implementing compound reforms by calling the Policy implement_reform method twice. It's good to hear you were able to check the validity of this approach. I hope to add soon a Cookbook recipe that features this technique.

@MaxGhenis
Copy link
Contributor Author

For posterity, the reform parameters require underscores, so could look like:

ubi_reform = {2018: {'_UBI1': [ubi_amount], 
                     '_UBI2': [ubi_amount], 
                     '_UBI3': [ubi_amount],
                     '_UBI_ecrt': [1.0]}}

I've found copy.deepcopy useful in conjunction with this approach, to create an edited version of an existing reform (e.g. to compare to it). For example here was a doubly-compounded reform after modifying to both repeal the charitable deduction and add a UBI (also in the notebook):

tcja_ubi_no_charitable_policy = copy.deepcopy(tcja_no_charitable_policy)
tcja_ubi_no_charitable_policy.implement_reform(ubi_reform)

@martinholmer
Copy link
Collaborator

@MaxGhenis, Thanks for the correction on my original example in issue #1802 and for you deepcopy usage tip here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants