Created
July 25, 2025 23:44
-
-
Save MaxGhenis/dbecbf2381217980e3890cbbe0f85708 to your computer and use it in GitHub Desktop.
Resolution: Multiple tax units explain the itemization behavior
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Resolution: Household 4428 Has Multiple Tax Units\n", | |
| "\n", | |
| "The apparent bug is explained by household 4428 having 2 tax units with different itemization decisions." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from policyengine_us import Microsimulation\n", | |
| "from policyengine_us.model_api import *\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "DATASET = \"hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5\"\n", | |
| "YEAR = 2026" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Setup Reform" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "reform = Reform.from_dict({\n", | |
| " \"gov.irs.income.bracket.rates.2\": {\"2026-01-01\": 0.15},\n", | |
| " \"gov.irs.income.bracket.rates.3\": {\"2026-01-01\": 0.25},\n", | |
| " \"gov.irs.deductions.standard.amount.JOINT\": {\"2026-01-01\": 48900},\n", | |
| " \"gov.irs.income.exemption.amount\": {\"2026-01-01\": 0},\n", | |
| " \"gov.contrib.reconciliation.ctc.in_effect\": {\"2026-01-01\": True},\n", | |
| " \"gov.irs.credits.ctc.amount.base[0].amount\": {\"2026-01-01\": 2200},\n", | |
| "}, country_id=\"us\")\n", | |
| "\n", | |
| "sim = Microsimulation(reform=reform, dataset=DATASET)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Check Both Tax Units" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Get tax unit data\n", | |
| "tax_unit_ids = sim.calculate(\"tax_unit_id\", period=YEAR).values\n", | |
| "itemizes = sim.calculate(\"tax_unit_itemizes\", period=YEAR).values\n", | |
| "tax_if_item = sim.calculate(\"tax_liability_if_itemizing\", period=YEAR).values\n", | |
| "tax_if_std = sim.calculate(\"tax_liability_if_not_itemizing\", period=YEAR).values\n", | |
| "\n", | |
| "# Find the two tax units in household 4428\n", | |
| "tu1_idx = np.where(tax_unit_ids == 442801)[0][0]\n", | |
| "tu2_idx = np.where(tax_unit_ids == 442802)[0][0]\n", | |
| "\n", | |
| "print(\"Tax Unit 442801 (parents + 4 kids):\")\n", | |
| "print(f\" Itemizes: {bool(itemizes[tu1_idx])}\")\n", | |
| "print(f\" Tax if itemizing: ${tax_if_item[tu1_idx]:,.2f}\")\n", | |
| "print(f\" Tax if standard: ${tax_if_std[tu1_idx]:,.2f}\")\n", | |
| "print(f\" Optimal: {'Same either way' if tax_if_item[tu1_idx] == tax_if_std[tu1_idx] else 'Itemize' if tax_if_item[tu1_idx] < tax_if_std[tu1_idx] else 'Standard'}\")\n", | |
| "\n", | |
| "print(\"\\nTax Unit 442802 (23-year-old):\")\n", | |
| "print(f\" Itemizes: {bool(itemizes[tu2_idx])}\")\n", | |
| "print(f\" Tax if itemizing: ${tax_if_item[tu2_idx]:,.2f}\")\n", | |
| "print(f\" Tax if standard: ${tax_if_std[tu2_idx]:,.2f}\")\n", | |
| "print(f\" Optimal: {'Standard' if tax_if_std[tu2_idx] < tax_if_item[tu2_idx] else 'Itemize'}\")\n", | |
| "\n", | |
| "print(\"\\n✓ Both tax units make optimal decisions!\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## The Real Issue\n", | |
| "\n", | |
| "The confusion arose from looking at household-level aggregates. When mapped to household level:\n", | |
| "- `tax_unit_itemizes` shows True (from the first tax unit)\n", | |
| "- But the tax liability values are summed across both tax units\n", | |
| "\n", | |
| "This creates the appearance of irrational behavior when it's actually two rational decisions." | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3", | |
| "language": "python", | |
| "name": "python3" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 4 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment