Skip to content

Commit 1722f02

Browse files
committed
first pass at new variables
1 parent 3be9ebd commit 1722f02

File tree

3 files changed

+51
-42
lines changed

3 files changed

+51
-42
lines changed

policyengine_us_data/datasets/cps/cps.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,11 +1045,11 @@ class Pooled_3_Year_CPS_2023(PooledCPS):
10451045

10461046

10471047
if __name__ == "__main__":
1048-
CPS_2021().generate()
1049-
CPS_2022().generate()
1050-
CPS_2023().generate()
1048+
#CPS_2021().generate()
1049+
#CPS_2022().generate()
1050+
#CPS_2023().generate()
10511051
CPS_2024().generate()
1052-
CPS_2021_Full().generate()
1053-
CPS_2022_Full().generate()
1054-
CPS_2023_Full().generate()
1055-
Pooled_3_Year_CPS_2023().generate()
1052+
#CPS_2021_Full().generate()
1053+
#CPS_2022_Full().generate()
1054+
#CPS_2023_Full().generate()
1055+
#Pooled_3_Year_CPS_2023().generate()

policyengine_us_data/datasets/cps/extended_cps.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"investment_income_elected_form_4952",
6363
"early_withdrawal_penalty",
6464
"prior_year_minimum_tax_credit",
65-
"farm_rent_income",
65+
"farm_rental_income",
6666
"qualified_tuition_expenses",
6767
"educator_expense",
6868
"long_term_capital_gains_on_collectibles",
@@ -71,6 +71,12 @@
7171
"unreported_payroll_tax",
7272
"recapture_of_investment_credit",
7373
"deductible_mortgage_interest",
74+
"reit_dividend_income",
75+
"ptp_income",
76+
"bdc_dividend_income",
77+
"s_corp_income",
78+
"partnership_income",
79+
"farm_operations_income"
7480
]
7581

7682
if os.environ.get("TEST_LITE"):

policyengine_us_data/datasets/puf/puf.py

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def preprocess_puf(puf: pd.DataFrame) -> pd.DataFrame:
146146
puf["educator_expense"] = puf.E03220
147147
puf["employment_income"] = puf.E00200
148148
puf["estate_income"] = puf.E26390 - puf.E26400
149-
puf["farm_income"] = puf.T27800
149+
puf["farm_income"] = puf.T27800 # Schedule J, separate from QBI
150150
puf["health_savings_account_ald"] = puf.E03290
151151
puf["interest_deduction"] = puf.E19200
152152
puf["long_term_capital_gains"] = puf.P23250
@@ -164,7 +164,12 @@ def preprocess_puf(puf: pd.DataFrame) -> pd.DataFrame:
164164
puf["qualified_dividend_income"] = puf.E00650
165165
puf["qualified_tuition_expenses"] = puf.E03230
166166
puf["real_estate_taxes"] = puf.E18500
167-
puf["rental_income"] = puf.E25850 - puf.E25860
167+
puf["rental_income"] = puf.E25850 - puf.E25860 # Schedule E rent and royalty
168+
puf["s_corp_income"] = puf.E26190 - puf.E26180 # Schedule E active S-Corp income
169+
puf["partnership_income"] = puf.E25980 - puf.E25960 # Schedule E active partnership income
170+
puf["farm_operations_income"] = puf.E02100 # Schedule F active farming operations
171+
puf["farm_rental_income"] = puf.E27200 # Schedule E farm rental income
172+
puf["self_employment_income"] = puf.E00900 # Schedule C Sole Proprietorship
168173
puf["self_employed_health_insurance_ald"] = puf.E03270
169174
puf["self_employed_pension_contribution_ald"] = puf.E03300
170175
puf["short_term_capital_gains"] = puf.P22250
@@ -200,32 +205,19 @@ def preprocess_puf(puf: pd.DataFrame) -> pd.DataFrame:
200205
# Ignore f2441 (AMT form attached)
201206
# Ignore cmbtp (estimate of AMT income not in AGI)
202207
# Ignore k1bx14s and k1bx14p (partner self-employment income included in partnership and S-corp income)
203-
# --- Qualified Business Income Deduction related variables ---
204-
# Income sources
205-
puf["sole_proprietorship_net_income"] = puf.E00900 # Schedule C Sole proprietorship income
206-
puf["farm_operations_net_income"] = puf.E02100 # Schedule F active farming operations
207-
puf["farm_rental_net_income"] = puf.E27200 # Schedule E farm rental income
208-
puf["rent_royalty_net_income"] = puf.E25850 - puf.E25860 # Schedule E rent and royalty
209-
puf["estate_trust_net_income"] = puf.E26390 - puf.E26400 # Schedule E estate or trust
210-
puf["s_corp_net_income"] = puf.E26190 - puf.E26180 # Schedule E active S-Corp income
211-
puf["partnership_net_income"] = puf.E25980 - puf.E25960 # Schedule E active partnership income
212-
213-
puf["reit_dividends"] = 100
214-
puf["ptp_income"] = 100 # Publically traded partnership income
215-
puf["bdc_dividends"] = 100 # business development company income
216208

209+
# --- Qualified Business Income Deduction computation and simulation ---
217210
qbi = (
218-
puf["sole_proprietorship_net_income"]
219-
+ puf["schedule_F_farm_net_income"]
220-
+ puf["farm_rental_net_income"]
221-
+ puf["rent_royalty_net_income"]
222-
+ puf["estate_trust_net_income"]
223-
+ puf["s_corp_net_income"]
224-
+ puf["partnership_net_income"]
211+
puf["self_employment_income"] # Schedule C sole prop
212+
+ puf["farm_operations_income"] # NEW: schedule F active farming ops
213+
+ puf["farm_rental_income"] # Schedule E farm rent: TODO: accidentally renamed farm_rent_income
214+
+ puf["rental_income"] # Schedule E rent and royalty
215+
+ puf["estate_income"] # Schedule E estate and trust
216+
+ puf["s_corp_income"] # NEW: Schedule E S Corp # TODO: remake partnership_s_corp_income?
217+
+ puf["partnership_income"] # NEW: Schedule E active partnership
225218
)
226219
print(f"QBI Est (Millions) New: {np.dot(qbi, puf.S006) / 1E6:,.0f}")
227220

228-
229221
def simulate_w2_wages_from_qualified_business(qbi, diagnostics=False):
230222
MIN_MARGIN = .03
231223
MAX_MARGIN = .15
@@ -264,20 +256,22 @@ def simulate_w2_wages_from_qualified_business(qbi, diagnostics=False):
264256
print(f"Within positive QBI, proportion with W2 wages: {np.mean(w2_wages[qbi>0]>0):.2f}")
265257
print(f"Within positive wages, mean in Millions is {np.mean(w2_wages[w2_wages>0])/1E6:.1f}")
266258
print(f"Within positive wages, median in Millions is {np.median(w2_wages[w2_wages>0])/1E6:.1f}")
267-
print(f"Within positive wages, 75th percentile in Millions is {np.percentile(w2_wages[w2_wages>0], 75)/1E6:.1f}")
268-
print(f"Within positive wages, max in Millions is {np.max(w2_wages[w2_wages>0])/1E6:.1f}")
269-
print(f"Within positive wages, median ubia property probability is {np.median(pr_has_qualified_property[w2_wages>0]):.3f}")
270-
print(f"Within positive wages, median ubia property in millions is {np.median(ubia_property[w2_wages>0])/1E6:.1f}")
259+
print(f"Within pos wages, 75th perc (mil) is {np.percentile(w2_wages[w2_wages>0], 75)/1E6:.1f}")
260+
print(f"For pos wages, max (mil) is {np.max(w2_wages[w2_wages>0])/1E6:.1f}")
261+
print(f"For pos wages, med ubia >0 prob: {np.median(pr_has_qualified_property[w2_wages>0]):.3f}")
262+
print(f"For positive wages, med ubia prop (mil): {np.median(ubia_property[w2_wages>0])/1E6:.1f}")
271263
return w2_wages, ubia_property
272264

273265
w2_wages, ubia_property = simulate_w2_wages_from_qualified_business(qbi)
274266
puf["w2_wages_from_qualified_business"] = w2_wages
275267
puf["unadjusted_basis_qualified_property"] = ubia_property
276268

277-
# Business is SSTB
269+
# Simulate whether business is SSTB
278270
largest_qbi_source = np.argmax(puf[[
279-
# 0: 20% 1: 0% 2: 15% 3: 0% 4: 0% 5: 0% 6: 10% 7: 10% 0%
280-
"E00900", "E02100", "E26270", "P25700", "E25850", "E27200", "E26390", "E26400", "E02000"]], axis=1)
271+
# 0: 20% 1: 0% 2: 15% 3: 0% 4: 0%
272+
"E00900", "E02100", "E26270", "P25700", "E25850",
273+
# 5: 0% 6: 10% 7: 10% 0%
274+
"E27200", "E26390", "E26400", "E02000"]], axis=1)
281275
largest_qbi_source = np.where(qbi <= 0, -1, largest_qbi_source)
282276

283277
pr_sstb = np.where(largest_qbi_source == -1, 0,
@@ -294,8 +288,12 @@ def simulate_w2_wages_from_qualified_business(qbi, diagnostics=False):
294288

295289
pr_sstb = np.where(qbi < 1E-3, 0, pr_sstb)
296290
puf["business_is_sstb"] = np.random.binomial(n=1, p=pr_sstb)
297-
# TODO: Fix the syntax:
298-
#print(f"{100 * np.mean(puf.loc[qbi > 0]["business_is_sstb"]):.1f}% of pos businesses")
291+
print(f"SSTB %: {100 * np.mean(puf.loc[qbi > 0]['business_is_sstb']):.1f}% of qbi pos biz")
292+
293+
# TODO: improve
294+
puf["reit_dividend_income"] = 100
295+
puf["ptp_income"] = 100 # Publically traded partnership income
296+
puf["bdc_dividend_income"] = 100 # business development company income
299297

300298
# -------- End QBID work -------
301299
puf["filing_status"] = puf.MARS.map(
@@ -326,21 +324,23 @@ def simulate_w2_wages_from_qualified_business(qbi, diagnostics=False):
326324
"educator_expense",
327325
"employment_income",
328326
"estate_income",
327+
"farm_operations_income",
329328
"farm_income",
330-
"farm_rent_income",
329+
"farm_rental_income",
331330
"health_savings_account_ald",
332331
"interest_deduction",
333332
"long_term_capital_gains",
334333
"long_term_capital_gains_on_collectibles",
335334
"unreimbursed_business_employee_expenses",
336335
"non_qualified_dividend_income",
337336
"non_sch_d_capital_gains",
338-
"partnership_s_corp_income",
339337
"qualified_dividend_income",
340338
"qualified_tuition_expenses",
341339
"real_estate_taxes",
342340
"rental_income",
343341
"self_employment_income",
342+
"s_corp_income",
343+
"partnership_income",
344344
"self_employed_health_insurance_ald",
345345
"self_employed_pension_contribution_ald",
346346
"short_term_capital_gains",
@@ -374,6 +374,9 @@ def simulate_w2_wages_from_qualified_business(qbi, diagnostics=False):
374374
"unadjusted_basis_qualified_property",
375375
"business_is_sstb",
376376
"deductible_mortgage_interest",
377+
"reit_dividend_income",
378+
"ptp_income",
379+
"bdc_dividend_income"
377380
]
378381

379382

0 commit comments

Comments
 (0)