Compare outcomes for large population scenarios¶
Use Simulation.calculate_economy_comparison()
to use PolicyEngine’s tax-benefit model to compare how taxes, benefits and other household properties change under a reform scenario. This notebook demonstrates how to use this function.
from policyengine import Simulation
sim = Simulation(
scope="macro", # Required for this
country="us", # or "us"
time_period=2025, # Defaults to 2025
reform={
"gov.usda.snap.income.deductions.earned_income": {
"2025": 0.05
}
}
)
sim.calculate_economy_comparison()
/opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
No data provided, using default dataset: gs://policyengine-us-data/cps_2023.h5
Downloading cps_2023.h5 from bucket policyengine-us-data
INFO:root:Using Google Cloud Storage for download.
---------------------------------------------------------------------------
DefaultCredentialsError Traceback (most recent call last)
Cell In[1], line 3
1 from policyengine import Simulation
----> 3 sim = Simulation(
4 scope="macro", # Required for this
5 country="us", # or "us"
6 time_period=2025, # Defaults to 2025
7 reform={
8 "gov.usda.snap.income.deductions.earned_income": {
9 "2025": 0.05
10 }
11 }
12 )
14 sim.calculate_economy_comparison()
File ~/work/policyengine.py/policyengine.py/policyengine/simulation.py:109, in Simulation.__init__(self, **options)
105 if not isinstance(self.options.data, dict) and not isinstance(
106 self.options.data, Dataset
107 ):
108 logging.debug("Loading data")
--> 109 self._set_data(self.options.data)
110 logging.info("Data loaded")
111 self._initialise_simulations()
File ~/work/policyengine.py/policyengine.py/policyengine/simulation.py:171, in Simulation._set_data(self, file_address)
166 version = None
168 else:
169 # All official PolicyEngine datasets are stored in GCS;
170 # load accordingly
--> 171 filename, version = self._set_data_from_gs(file_address)
172 self.data_version = version
174 time_period = self._set_data_time_period(file_address)
File ~/work/policyengine.py/policyengine.py/policyengine/simulation.py:405, in Simulation._set_data_from_gs(self, file_address)
401 version = self.options.data_version
403 print(f"Downloading {filename} from bucket {bucket}", file=sys.stderr)
--> 405 filepath, version = download(
406 filepath=filename,
407 gcs_bucket=bucket,
408 version=version,
409 return_version=True,
410 )
412 return filename, version
File ~/work/policyengine.py/policyengine.py/policyengine/utils/data_download.py:17, in download(filepath, gcs_bucket, version, return_version)
10 def download(
11 filepath: str,
12 gcs_bucket: str,
13 version: Optional[str] = None,
14 return_version: bool = False,
15 ) -> Tuple[str, str] | str:
16 logging.info("Using Google Cloud Storage for download.")
---> 17 downloaded_version = download_file_from_gcs(
18 bucket_name=gcs_bucket,
19 file_name=filepath,
20 destination_path=filepath,
21 version=version,
22 )
23 if return_version:
24 return filepath, downloaded_version
File ~/work/policyengine.py/policyengine.py/policyengine/utils/google_cloud_bucket.py:41, in download_file_from_gcs(bucket_name, file_name, destination_path, version)
23 def download_file_from_gcs(
24 bucket_name: str,
25 file_name: str,
26 destination_path: str,
27 version: Optional[str] = None,
28 ) -> str | None:
29 """
30 Download a file from Google Cloud Storage to a local path.
31
(...)
38 version (str): The version of the file that was downloaded, if available.
39 """
---> 41 version = _get_client().download(
42 bucket_name,
43 file_name,
44 Path(destination_path),
45 version=version,
46 return_version=True,
47 )
48 return version
File ~/work/policyengine.py/policyengine.py/policyengine/utils/google_cloud_bucket.py:14, in _get_client()
12 if _caching_client is not None:
13 return _caching_client
---> 14 _caching_client = CachingGoogleStorageClient()
15 return _caching_client
File ~/work/policyengine.py/policyengine.py/policyengine/utils/data/caching_google_storage_client.py:19, in CachingGoogleStorageClient.__init__(self)
18 def __init__(self):
---> 19 self.client = SimplifiedGoogleStorageClient()
20 self.cache = diskcache.Cache()
File ~/work/policyengine.py/policyengine.py/policyengine/utils/data/simplified_google_storage_client.py:19, in SimplifiedGoogleStorageClient.__init__(self)
18 def __init__(self):
---> 19 self.client = Client()
File /opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/google/cloud/storage/client.py:247, in Client.__init__(self, project, credentials, _http, client_info, client_options, use_auth_w_custom_endpoint, extra_headers, api_key)
244 no_project = True
245 project = "<none>"
--> 247 super(Client, self).__init__(
248 project=project,
249 credentials=credentials,
250 client_options=client_options,
251 _http=_http,
252 )
254 # Validate that the universe domain of the credentials matches the
255 # universe domain of the client.
256 if self._credentials.universe_domain != self.universe_domain:
File /opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/google/cloud/client/__init__.py:338, in ClientWithProject.__init__(self, project, credentials, client_options, _http)
337 def __init__(self, project=None, credentials=None, client_options=None, _http=None):
--> 338 _ClientProjectMixin.__init__(self, project=project, credentials=credentials)
339 Client.__init__(
340 self, credentials=credentials, client_options=client_options, _http=_http
341 )
File /opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/google/cloud/client/__init__.py:286, in _ClientProjectMixin.__init__(self, project, credentials)
283 project = getattr(credentials, "project_id", None)
285 if project is None:
--> 286 project = self._determine_default(project)
288 if project is None:
289 raise EnvironmentError(
290 "Project was not passed and could not be "
291 "determined from the environment."
292 )
File /opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/google/cloud/client/__init__.py:305, in _ClientProjectMixin._determine_default(project)
302 @staticmethod
303 def _determine_default(project):
304 """Helper: use default project detection."""
--> 305 return _determine_default_project(project)
File /opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/google/cloud/_helpers/__init__.py:152, in _determine_default_project(project)
140 """Determine default project ID explicitly or implicitly as fall-back.
141
142 See :func:`google.auth.default` for details on how the default project
(...)
149 :returns: Default project if it can be determined.
150 """
151 if project is None:
--> 152 _, project = google.auth.default()
153 return project
File /opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/google/auth/_default.py:685, in default(scopes, request, quota_project_id, default_scopes)
677 _LOGGER.warning(
678 "No project ID could be determined. Consider running "
679 "`gcloud config set project` or setting the %s "
680 "environment variable",
681 environment_vars.PROJECT,
682 )
683 return credentials, effective_project_id
--> 685 raise exceptions.DefaultCredentialsError(_CLOUD_SDK_MISSING_CREDENTIALS)
DefaultCredentialsError: Your default credentials were not found. To set up Application Default Credentials, see https://cloud.google.com/docs/authentication/external/set-up-adc for more information.
Output schema¶
calculate_economy_comparison
or calculate
(when scope=household
and reform is not None
) return the following schema.
from policyengine.outputs.macro.comparison.calculate_economy_comparison import EconomyComparison
EconomyComparison.model_json_schema()
{'$defs': {'DecileImpacts': {'properties': {'income': {'$ref': '#/$defs/IncomeMeasureSpecificDecileImpacts'},
'wealth': {'anyOf': [{'$ref': '#/$defs/IncomeMeasureSpecificDecileImpacts'},
{'type': 'null'}]}},
'required': ['income', 'wealth'],
'title': 'DecileImpacts',
'type': 'object'},
'FiscalComparison': {'properties': {'baseline': {'$ref': '#/$defs/FiscalSummary'},
'reform': {'$ref': '#/$defs/FiscalSummary'},
'change': {'$ref': '#/$defs/FiscalSummary'},
'relative_change': {'$ref': '#/$defs/FiscalSummary'}},
'required': ['baseline', 'reform', 'change', 'relative_change'],
'title': 'FiscalComparison',
'type': 'object'},
'FiscalSummary': {'properties': {'tax_revenue': {'title': 'Tax Revenue',
'type': 'number'},
'federal_tax': {'title': 'Federal Tax', 'type': 'number'},
'federal_balance': {'title': 'Federal Balance', 'type': 'number'},
'state_tax': {'title': 'State Tax', 'type': 'number'},
'government_spending': {'title': 'Government Spending', 'type': 'number'},
'tax_benefit_programs': {'additionalProperties': {'type': 'number'},
'title': 'Tax Benefit Programs',
'type': 'object'},
'household_net_income': {'title': 'Household Net Income',
'type': 'number'}},
'required': ['tax_revenue',
'federal_tax',
'federal_balance',
'state_tax',
'government_spending',
'tax_benefit_programs',
'household_net_income'],
'title': 'FiscalSummary',
'type': 'object'},
'Headlines': {'properties': {'budgetary_impact': {'title': 'Budgetary Impact',
'type': 'number'},
'poverty_impact': {'title': 'Poverty Impact', 'type': 'number'},
'winner_share': {'title': 'Winner Share', 'type': 'number'}},
'required': ['budgetary_impact', 'poverty_impact', 'winner_share'],
'title': 'Headlines',
'type': 'object'},
'IncomeMeasureSpecificDecileImpacts': {'properties': {'income_change': {'$ref': '#/$defs/IncomeMeasureSpecificDecileIncomeChange'},
'winners_and_losers': {'$ref': '#/$defs/IncomeMeasureSpecificDecileWinnersLosers'}},
'required': ['income_change', 'winners_and_losers'],
'title': 'IncomeMeasureSpecificDecileImpacts',
'type': 'object'},
'IncomeMeasureSpecificDecileIncomeChange': {'properties': {'relative': {'additionalProperties': {'type': 'number'},
'title': 'Relative',
'type': 'object'},
'average': {'additionalProperties': {'type': 'number'},
'title': 'Average',
'type': 'object'}},
'required': ['relative', 'average'],
'title': 'IncomeMeasureSpecificDecileIncomeChange',
'type': 'object'},
'IncomeMeasureSpecificDecileWinnersLosers': {'properties': {'deciles': {'additionalProperties': {'$ref': '#/$defs/IncomeMeasureSpecificDecileWinnersLosersGroupOutcomes'},
'title': 'Deciles',
'type': 'object'},
'all': {'$ref': '#/$defs/IncomeMeasureSpecificDecileWinnersLosersGroupOutcomes'}},
'required': ['deciles', 'all'],
'title': 'IncomeMeasureSpecificDecileWinnersLosers',
'type': 'object'},
'IncomeMeasureSpecificDecileWinnersLosersGroupOutcomes': {'properties': {'lose_more_than_5_percent_share': {'title': 'Lose More Than 5 Percent Share',
'type': 'number'},
'lose_less_than_5_percent_share': {'title': 'Lose Less Than 5 Percent Share',
'type': 'number'},
'lose_share': {'title': 'Lose Share', 'type': 'number'},
'no_change_share': {'title': 'No Change Share', 'type': 'number'},
'gain_share': {'title': 'Gain Share', 'type': 'number'},
'gain_less_than_5_percent_share': {'title': 'Gain Less Than 5 Percent Share',
'type': 'number'},
'gain_more_than_5_percent_share': {'title': 'Gain More Than 5 Percent Share',
'type': 'number'}},
'required': ['lose_more_than_5_percent_share',
'lose_less_than_5_percent_share',
'lose_share',
'no_change_share',
'gain_share',
'gain_less_than_5_percent_share',
'gain_more_than_5_percent_share'],
'title': 'IncomeMeasureSpecificDecileWinnersLosersGroupOutcomes',
'type': 'object'},
'InequalityComparison': {'properties': {'baseline': {'$ref': '#/$defs/InequalitySummary'},
'reform': {'$ref': '#/$defs/InequalitySummary'},
'change': {'$ref': '#/$defs/InequalitySummary'},
'relative_change': {'$ref': '#/$defs/InequalitySummary'}},
'required': ['baseline', 'reform', 'change', 'relative_change'],
'title': 'InequalityComparison',
'type': 'object'},
'InequalitySummary': {'properties': {'gini': {'title': 'Gini',
'type': 'number'},
'top_10_share': {'title': 'Top 10 Share', 'type': 'number'},
'top_1_share': {'title': 'Top 1 Share', 'type': 'number'}},
'required': ['gini', 'top_10_share', 'top_1_share'],
'title': 'InequalitySummary',
'type': 'object'},
'LaborSupplyMetricImpact': {'properties': {'elasticity': {'enum': ['income',
'substitution',
'all'],
'title': 'Elasticity',
'type': 'string'},
'decile': {'enum': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'all'],
'title': 'Decile'},
'unit': {'enum': ['earnings', 'hours'], 'title': 'Unit', 'type': 'string'},
'baseline': {'title': 'Baseline', 'type': 'number'},
'reform': {'title': 'Reform', 'type': 'number'},
'change': {'title': 'Change', 'type': 'number'},
'relative_change': {'title': 'Relative Change', 'type': 'number'},
'average_change': {'title': 'Average Change', 'type': 'number'}},
'required': ['elasticity',
'decile',
'unit',
'baseline',
'reform',
'change',
'relative_change',
'average_change'],
'title': 'LaborSupplyMetricImpact',
'type': 'object'},
'PovertyRateMetricComparison': {'properties': {'age_group': {'enum': ['child',
'working_age',
'senior',
'all'],
'title': 'Age Group',
'type': 'string'},
'gender': {'enum': ['male', 'female', 'all'],
'title': 'Gender',
'type': 'string'},
'racial_group': {'enum': ['white', 'black', 'hispanic', 'other', 'all'],
'title': 'Racial Group',
'type': 'string'},
'relative': {'title': 'Relative', 'type': 'boolean'},
'poverty_rate': {'enum': ['regular',
'deep',
'uk_hbai_bhc',
'uk_hbai_bhc_half',
'us_spm',
'us_spm_half'],
'title': 'Poverty Rate',
'type': 'string'},
'baseline': {'title': 'Baseline', 'type': 'number'},
'reform': {'title': 'Reform', 'type': 'number'},
'change': {'title': 'Change', 'type': 'number'},
'relative_change': {'title': 'Relative Change', 'type': 'number'}},
'required': ['age_group',
'gender',
'racial_group',
'relative',
'poverty_rate',
'baseline',
'reform',
'change',
'relative_change'],
'title': 'PovertyRateMetricComparison',
'type': 'object'}},
'properties': {'headlines': {'$ref': '#/$defs/Headlines'},
'fiscal': {'$ref': '#/$defs/FiscalComparison'},
'inequality': {'$ref': '#/$defs/InequalityComparison'},
'distributional': {'$ref': '#/$defs/DecileImpacts'},
'poverty': {'items': {'$ref': '#/$defs/PovertyRateMetricComparison'},
'title': 'Poverty',
'type': 'array'},
'labor_supply': {'items': {'$ref': '#/$defs/LaborSupplyMetricImpact'},
'title': 'Labor Supply',
'type': 'array'}},
'required': ['headlines',
'fiscal',
'inequality',
'distributional',
'poverty',
'labor_supply'],
'title': 'EconomyComparison',
'type': 'object'}