Skip to content

Commit

Permalink
Merge pull request #43 from PolicyEngine/api-parity
Browse files Browse the repository at this point in the history
Add all remaining general economy impacts
  • Loading branch information
nikhilwoodruff authored Nov 25, 2024
2 parents e21cb8d + 0d6e545 commit 6166d55
Show file tree
Hide file tree
Showing 14 changed files with 909 additions and 92 deletions.
432 changes: 341 additions & 91 deletions docs/schema.ipynb

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions policyengine/outputs/macro/comparison/decile/income.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from policyengine import Simulation
from microdf import MicroSeries


def income(simulation: Simulation):
baseline = simulation.calculate("macro/baseline")
reform = simulation.calculate("macro/reform")

baseline_income = MicroSeries(
baseline["household"]["finance"]["household_net_income"],
weights=baseline["household"]["demographics"]["household_weight"],
)
reform_income = MicroSeries(
reform["household"]["finance"]["household_net_income"],
weights=baseline_income.weights,
)

# Filter out negative decile values
decile = MicroSeries(
baseline["household"]["finance"]["household_income_decile"]
)
baseline_income_filtered = baseline_income[decile >= 0]
reform_income_filtered = reform_income[decile >= 0]

income_change = reform_income_filtered - baseline_income_filtered
rel_income_change_by_decile = (
income_change.groupby(decile).sum()
/ baseline_income_filtered.groupby(decile).sum()
)

avg_income_change_by_decile = (
income_change.groupby(decile).sum()
/ baseline_income_filtered.groupby(decile).count()
)
rel_decile_dict = rel_income_change_by_decile.to_dict()
avg_decile_dict = avg_income_change_by_decile.to_dict()
result = dict(
relative={int(k): v for k, v in rel_decile_dict.items()},
average={int(k): v for k, v in avg_decile_dict.items()},
)
return result
42 changes: 42 additions & 0 deletions policyengine/outputs/macro/comparison/decile/wealth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from policyengine import Simulation
from microdf import MicroSeries


def wealth(simulation: Simulation):
if simulation.country != "uk":
return {}

baseline = simulation.calculate("macro/baseline")
reform = simulation.calculate("macro/reform")

baseline_income = MicroSeries(
baseline["household"]["finance"]["household_net_income"],
weights=baseline["household"]["demographics"]["household_weight"],
)
reform_income = MicroSeries(
reform["household"]["finance"]["household_net_income"],
weights=baseline_income.weights,
)

# Filter out negative decile values
decile = MicroSeries(baseline["household"]["finance"]["wealth_decile"])
baseline_income_filtered = baseline_income[decile >= 0]
reform_income_filtered = reform_income[decile >= 0]

income_change = reform_income_filtered - baseline_income_filtered
rel_income_change_by_decile = (
income_change.groupby(decile).sum()
/ baseline_income_filtered.groupby(decile).sum()
)

avg_income_change_by_decile = (
income_change.groupby(decile).sum()
/ baseline_income_filtered.groupby(decile).count()
)
rel_decile_dict = rel_income_change_by_decile.to_dict()
avg_decile_dict = avg_income_change_by_decile.to_dict()
result = dict(
relative={int(k): v for k, v in rel_decile_dict.items()},
average={int(k): v for k, v in avg_decile_dict.items()},
)
return result
17 changes: 17 additions & 0 deletions policyengine/outputs/macro/comparison/detailed_budget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from policyengine import Simulation


def detailed_budget(simulation: Simulation):
baseline = simulation.calculate("macro/baseline")
reform = simulation.calculate("macro/reform")
result = {}
if simulation.country == "uk":
for program in baseline["gov"]["programs"]:
# baseline[programs][program] = total budgetary impact of program
result[program] = dict(
baseline=baseline["gov"]["programs"][program],
reform=reform["gov"]["programs"][program],
difference=reform["gov"]["programs"][program]
- baseline["gov"]["programs"][program],
)
return result
23 changes: 23 additions & 0 deletions policyengine/outputs/macro/comparison/inequality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from policyengine import Simulation


def inequality(simulation: Simulation):
baseline = simulation.calculate("macro/baseline")["household"][
"inequality"
]
reform = simulation.calculate("macro/reform")["household"]["inequality"]

return dict(
gini=dict(
baseline=baseline["gini"],
reform=reform["gini"],
),
top_10_pct_share=dict(
baseline=baseline["top_10_percent_share"],
reform=reform["top_10_percent_share"],
),
top_1_pct_share=dict(
baseline=baseline["top_1_percent_share"],
reform=reform["top_1_percent_share"],
),
)
109 changes: 109 additions & 0 deletions policyengine/outputs/macro/comparison/labor_supply_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from policyengine import Simulation
from microdf import MicroSeries
import numpy as np


def labor_supply_response(simulation: Simulation) -> dict:
baseline = simulation.calculate("macro/baseline")
reform = simulation.calculate("macro/reform")

substitution_lsr = (
reform["household"]["labor_supply"]["substitution_lsr"]
- baseline["household"]["labor_supply"]["substitution_lsr"]
)
income_lsr = (
reform["household"]["labor_supply"]["income_lsr"]
- baseline["household"]["labor_supply"]["income_lsr"]
)
total_change = substitution_lsr + income_lsr
revenue_change = (
reform["household"]["labor_supply"]["budgetary_impact_lsr"]
- baseline["household"]["labor_supply"]["budgetary_impact_lsr"]
)

substitution_lsr_hh = np.array(
reform["household"]["labor_supply"]["substitution_lsr_hh"]
) - np.array(baseline["household"]["labor_supply"]["substitution_lsr_hh"])
income_lsr_hh = np.array(
reform["household"]["labor_supply"]["income_lsr_hh"]
) - np.array(baseline["household"]["labor_supply"]["income_lsr_hh"])
decile = np.array(
baseline["household"]["finance"]["household_income_decile"]
)
household_weight = baseline["household"]["demographics"][
"household_weight"
]

total_lsr_hh = substitution_lsr_hh + income_lsr_hh

emp_income = MicroSeries(
baseline["household"]["finance"]["employment_income_hh"],
weights=household_weight,
)
self_emp_income = MicroSeries(
baseline["household"]["finance"]["self_employment_income_hh"],
weights=household_weight,
)
earnings = emp_income + self_emp_income
original_earnings = earnings - total_lsr_hh
substitution_lsr_hh = MicroSeries(
substitution_lsr_hh, weights=household_weight
)
income_lsr_hh = MicroSeries(income_lsr_hh, weights=household_weight)

decile_avg = dict(
income=income_lsr_hh.groupby(decile).mean().to_dict(),
substitution=substitution_lsr_hh.groupby(decile).mean().to_dict(),
)
decile_rel = dict(
income=(
income_lsr_hh.groupby(decile).sum()
/ original_earnings.groupby(decile).sum()
).to_dict(),
substitution=(
substitution_lsr_hh.groupby(decile).sum()
/ original_earnings.groupby(decile).sum()
).to_dict(),
)

relative_lsr = dict(
income=(income_lsr_hh.sum() / original_earnings.sum()),
substitution=(substitution_lsr_hh.sum() / original_earnings.sum()),
)

decile_rel["income"] = {
int(k): v for k, v in decile_rel["income"].items() if k > 0
}
decile_rel["substitution"] = {
int(k): v for k, v in decile_rel["substitution"].items() if k > 0
}

hours = dict(
baseline=baseline["household"]["labor_supply"]["weekly_hours"],
reform=reform["household"]["labor_supply"]["weekly_hours"],
change=reform["household"]["labor_supply"]["weekly_hours"]
- baseline["household"]["labor_supply"]["weekly_hours"],
income_effect=reform["household"]["labor_supply"][
"weekly_hours_income_effect"
]
- baseline["household"]["labor_supply"]["weekly_hours_income_effect"],
substitution_effect=reform["household"]["labor_supply"][
"weekly_hours_substitution_effect"
]
- baseline["household"]["labor_supply"][
"weekly_hours_substitution_effect"
],
)

return dict(
substitution_lsr=substitution_lsr,
income_lsr=income_lsr,
relative_lsr=relative_lsr,
total_change=total_change,
revenue_change=revenue_change,
decile=dict(
average=decile_avg,
relative=decile_rel,
),
hours=hours,
)
71 changes: 71 additions & 0 deletions policyengine/outputs/macro/comparison/poverty/age.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from policyengine import Simulation
from microdf import MicroSeries


def age(simulation: Simulation):
baseline = simulation.calculate("macro/baseline")["household"]["finance"]
reform = simulation.calculate("macro/reform")["household"]["finance"]
baseline_demographics = simulation.calculate("macro/baseline")[
"household"
]["demographics"]

baseline_poverty = MicroSeries(
baseline["person_in_poverty"],
weights=baseline_demographics["person_weight"],
)
baseline_deep_poverty = MicroSeries(
baseline["person_in_deep_poverty"],
weights=baseline_demographics["person_weight"],
)
reform_poverty = MicroSeries(
reform["person_in_poverty"], weights=baseline_poverty.weights
)
reform_deep_poverty = MicroSeries(
reform["person_in_deep_poverty"], weights=baseline_poverty.weights
)
age = MicroSeries(baseline_demographics["age"])

poverty = dict(
child=dict(
baseline=float(baseline_poverty[age < 18].mean()),
reform=float(reform_poverty[age < 18].mean()),
),
adult=dict(
baseline=float(baseline_poverty[(age >= 18) & (age < 65)].mean()),
reform=float(reform_poverty[(age >= 18) & (age < 65)].mean()),
),
senior=dict(
baseline=float(baseline_poverty[age >= 65].mean()),
reform=float(reform_poverty[age >= 65].mean()),
),
all=dict(
baseline=float(baseline_poverty.mean()),
reform=float(reform_poverty.mean()),
),
)

deep_poverty = dict(
child=dict(
baseline=float(baseline_deep_poverty[age < 18].mean()),
reform=float(reform_deep_poverty[age < 18].mean()),
),
adult=dict(
baseline=float(
baseline_deep_poverty[(age >= 18) & (age < 65)].mean()
),
reform=float(reform_deep_poverty[(age >= 18) & (age < 65)].mean()),
),
senior=dict(
baseline=float(baseline_deep_poverty[age >= 65].mean()),
reform=float(reform_deep_poverty[age >= 65].mean()),
),
all=dict(
baseline=float(baseline_deep_poverty.mean()),
reform=float(reform_deep_poverty.mean()),
),
)

return dict(
poverty=poverty,
deep_poverty=deep_poverty,
)
55 changes: 55 additions & 0 deletions policyengine/outputs/macro/comparison/poverty/gender.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from policyengine import Simulation
from microdf import MicroSeries


def gender(simulation: Simulation):
baseline = simulation.calculate("macro/baseline")["household"]["finance"]
reform = simulation.calculate("macro/reform")["household"]["finance"]
baseline_demographics = simulation.calculate("macro/baseline")[
"household"
]["demographics"]

if baseline_demographics["is_male"] is None:
return {}
baseline_poverty = MicroSeries(
baseline["person_in_poverty"],
weights=baseline_demographics["person_weight"],
)
baseline_deep_poverty = MicroSeries(
baseline["person_in_deep_poverty"],
weights=baseline_demographics["person_weight"],
)
reform_poverty = MicroSeries(
reform["person_in_poverty"], weights=baseline_poverty.weights
)
reform_deep_poverty = MicroSeries(
reform["person_in_deep_poverty"], weights=baseline_poverty.weights
)
is_male = MicroSeries(baseline_demographics["is_male"])

poverty = dict(
male=dict(
baseline=float(baseline_poverty[is_male].mean()),
reform=float(reform_poverty[is_male].mean()),
),
female=dict(
baseline=float(baseline_poverty[~is_male].mean()),
reform=float(reform_poverty[~is_male].mean()),
),
)

deep_poverty = dict(
male=dict(
baseline=float(baseline_deep_poverty[is_male].mean()),
reform=float(reform_deep_poverty[is_male].mean()),
),
female=dict(
baseline=float(baseline_deep_poverty[~is_male].mean()),
reform=float(reform_deep_poverty[~is_male].mean()),
),
)

return dict(
poverty=poverty,
deep_poverty=deep_poverty,
)
Loading

0 comments on commit 6166d55

Please sign in to comment.