From 846fc380a03686d77d2a1c3da30e9ef3ff1319f8 Mon Sep 17 00:00:00 2001 From: andersonfrailey Date: Thu, 18 May 2017 15:30:27 -0400 Subject: [PATCH 1/2] initial commit --- taxcalc/calculate.py | 4 +++- taxcalc/functions.py | 18 ++++++++++++++++++ taxcalc/records_variables.json | 7 ++++++- taxcalc/utils.py | 10 +++++++++- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/taxcalc/calculate.py b/taxcalc/calculate.py index 818b44ca5..6887accb4 100644 --- a/taxcalc/calculate.py +++ b/taxcalc/calculate.py @@ -22,7 +22,8 @@ AmOppCreditParts, EducationTaxCredit, NonrefundableCredits, C1040, IITAX, BenefitSurtax, BenefitLimitation, - FairShareTax, LumpSumTax, ExpandIncome) + FairShareTax, LumpSumTax, ExpandIncome, + AfterTaxIncome) from taxcalc.policy import Policy from taxcalc.records import Records from taxcalc.behavior import Behavior @@ -217,6 +218,7 @@ def calc_all(self, zero_out_calc_vars=False): FairShareTax(self.policy, self.records) LumpSumTax(self.policy, self.records) ExpandIncome(self.policy, self.records) + AfterTaxIncome(self.policy, self.records) def increment_year(self): """ diff --git a/taxcalc/functions.py b/taxcalc/functions.py index e2637c0c4..e695ead6d 100644 --- a/taxcalc/functions.py +++ b/taxcalc/functions.py @@ -1554,3 +1554,21 @@ def ExpandIncome(c00100, ptax_was, e02400, c02500, employer_fica_share + nontaxable_ubi) # universal basic income return expanded_income + + +@iterate_jit(nopython=True) +def AfterTaxIncome(combined, expanded_income, aftertax_income): + """ + Calculate after tax income + + Parameters + ---------- + combined: combined tax liability + expanded_income: expanded income + + Returns + ------- + aftertax_income: expanded_income - combined + """ + aftertax_income = expanded_income - combined + return aftertax_income diff --git a/taxcalc/records_variables.json b/taxcalc/records_variables.json index 2f05e1189..5175f2670 100644 --- a/taxcalc/records_variables.json +++ b/taxcalc/records_variables.json @@ -881,6 +881,11 @@ "type": "float", "desc": "Marginal income tax rate (in percentage terms) on extra taxpayer earnings (e00200p)", "form": {} - } + }, + "aftertax_income": { + "type": "float", + "desc": "After tax income. Equal to expanded_income - combined", + "form": {} + } } } diff --git a/taxcalc/utils.py b/taxcalc/utils.py index 85f743f86..164d546ee 100644 --- a/taxcalc/utils.py +++ b/taxcalc/utils.py @@ -25,7 +25,7 @@ BOKEH_AVAILABLE = False -STATS_COLUMNS = ['expanded_income', 'c00100', 'standard', +STATS_COLUMNS = ['expanded_income', 'c00100', 'aftertax_income', 'standard', 'c04470', 'c04600', 'c04800', 'taxbc', 'c62100', 'c09600', 'c05800', 'othertaxes', 'refund', 'c07100', 'iitax', 'payrolltax', 'combined', 's006'] @@ -491,6 +491,7 @@ def create_difference_table(recs1, recs2, groupby, res2 = results(recs2) baseline_income_measure = income_measure + '_baseline' res2[baseline_income_measure] = res1[income_measure] + res2['aftertax_baseline'] = res1['aftertax_income'] income_measure = baseline_income_measure if groupby == 'weighted_deciles': pdf = add_weighted_income_bins(res2, num_bins=10, @@ -513,9 +514,13 @@ def create_difference_table(recs1, recs2, groupby, # Positive values are the magnitude of the tax increase # Negative values are the magnitude of the tax decrease res2['tax_diff'] = res2[income_to_present] - res1[income_to_present] + res2['aftertax_perc'] = res2['tax_diff'] / res2['aftertax_baseline'] diffs = means_and_comparisons('tax_diff', pdf.groupby('bins', as_index=False), (res2['tax_diff'] * res2['s006']).sum()) + aftertax_perc = pdf.groupby('bins', as_index=False).apply(weighted_mean, + 'aftertax_perc') + diffs['aftertax_perc'] = aftertax_perc sum_row = get_sums(diffs)[diffs.columns.values.tolist()] diffs = diffs.append(sum_row) # pylint: disable=redefined-variable-type pd.options.display.float_format = '{:8,.0f}'.format @@ -527,6 +532,9 @@ def create_difference_table(recs1, recs2, groupby, srs_change = ['{0:.2f}%'.format(val * 100) for val in diffs['share_of_change']] diffs['share_of_change'] = pd.Series(srs_change, index=diffs.index) + srs_aftertax_perc = ['{0:.2f}%'.format(val * 100) + for val in diffs['aftertax_perc']] + diffs['aftertax_perc'] = pd.Series(srs_aftertax_perc, index=diffs.index) # columns containing weighted values relative to the binning mechanism non_sum_cols = [col for col in diffs.columns if 'mean' in col or 'perc' in col] From 2bd0d6c5e31cc91a27625e1c8897bf99901ef930 Mon Sep 17 00:00:00 2001 From: andersonfrailey Date: Tue, 23 May 2017 12:57:55 -0400 Subject: [PATCH 2/2] fix test --- taxcalc/tests/test_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/taxcalc/tests/test_utils.py b/taxcalc/tests/test_utils.py index 6549f6f02..7a28213ae 100644 --- a/taxcalc/tests/test_utils.py +++ b/taxcalc/tests/test_utils.py @@ -441,7 +441,8 @@ def test_diff_table_sum_row(puf_1991, weights_1991): groupby='small_income_bins') tdiff2 = create_difference_table(calc1.records, calc2.records, groupby='large_income_bins') - non_digit_cols = ['mean', 'perc_inc', 'perc_cut', 'share_of_change'] + non_digit_cols = ['mean', 'perc_inc', 'perc_cut', 'share_of_change', + 'aftertax_perc'] digit_cols = [x for x in tdiff1.columns.tolist() if x not in non_digit_cols] assert np.allclose(tdiff1[digit_cols][-1:], tdiff2[digit_cols][-1:])