diff --git a/Documentation/CHANGELOG.md b/Documentation/CHANGELOG.md index 3ac2d1394..dbe66813c 100644 --- a/Documentation/CHANGELOG.md +++ b/Documentation/CHANGELOG.md @@ -20,9 +20,10 @@ Release Data: TBD * Centralizes the definition of value, marginal value, and marginal marginal value functions that use inverse-space interpolation for problems with CRRA utility. See [#888](https://github.com/econ-ark/HARK/pull/888). * MarkovProcess class used in ConsMarkovModel, ConsRepAgentModel, ConsAggShockModel [#902](https://github.com/econ-ark/HARK/pull/902) [#929](https://github.com/econ-ark/HARK/pull/929) +* Adds SSA life tables and methods to extract survival probabilities from them [#986](https://github.com/econ-ark/HARK/pull/906). +* Adds the U.S. CPI research series and tools to extract inflation adjustments from it [#930](https://github.com/econ-ark/HARK/pull/930). * replace HARKobject base class with MetricObject and Model classes [#903](https://github.com/econ-ark/HARK/pull/903/) * Add __repr__ and __eq__ methods to Model class [#903](https://github.com/econ-ark/HARK/pull/903/) -* Adds a SSA life tables and methods to extract survival probabilities from them [#986](https://github.com/econ-ark/HARK/pull/906). * Fix the return fields of `dcegm/calcCrossPoints`[#909](https://github.com/econ-ark/HARK/pull/909). * Corrects location of constructor documentation to class string for Sphinx rendering [#908](https://github.com/econ-ark/HARK/pull/908) diff --git a/HARK/datasets/cpi/__init__.py b/HARK/datasets/cpi/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/HARK/datasets/cpi/us/CPITools.py b/HARK/datasets/cpi/us/CPITools.py new file mode 100644 index 000000000..6e81d6d1a --- /dev/null +++ b/HARK/datasets/cpi/us/CPITools.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jan 20 18:07:41 2021 + +@author: Mateo +""" + +import os +import urllib.request +import pandas as pd +import warnings +import numpy as np + +__all__ = ["get_cpi_series", "cpi_deflator"] + +us_cpi_dir = os.path.dirname(os.path.abspath(__file__)) + + +def download_cpi_series(): + """ + A method that downloads the cpi research series file directly from the + bls site onto the working directory. + After being converted to a .csv, this is the file that the rest of + the functions in this script use and must be placed in HARK/datasets/cpi/us. + This function is not for users but for whenever mantainers want to update + the cpi series as new data comes out. + + Returns + ------- + None. + + """ + urllib.request.urlretrieve( + "https://www.bls.gov/cpi/research-series/r-cpi-u-rs-allitems.xlsx", + "r-cpi-u-rs-allitems.xlsx", + ) + + +def get_cpi_series(): + """ + This function reads the cpi series currently in the toolbox and returns it + as a pandas dataframe. + + Returns + ------- + cpi : Pandas DataFrame + DataFrame representation of the CPI research series file from the + Bureau of Labor Statistics. + + """ + + cpi = pd.read_csv( + os.path.join(us_cpi_dir, "r-cpi-u-rs-allitems.csv"), + skiprows=5, + index_col=0, + ) + return cpi + + +def cpi_deflator(from_year, to_year, base_month=None): + """ + Finds cpi deflator to transform quantities measured in "from_year" U.S. + dollars to "to_year" U.S. dollars. + The deflators are computed using the "r-cpi-u-rs" series from the BLS. + + Parameters + ---------- + from_year : int + Base year in which the nominal quantities are currently expressed. + to_year : int + Target year in which you wish to express the quantities. + base_month : str, optional + Month at which to take the CPI measurements to calculate the deflator. + The default is None, and in this case annual averages of the CPI are + used. + + Returns + ------- + deflator : numpy array + A length-1 numpy array with the deflator that, when multiplied by the + original nominal quantities, rebases them to "to_year" U.S. dollars. + + """ + + # Check years are conforming + assert type(from_year) is int and type(to_year) is int, "Years must be integers." + + # Check month is conforming + if base_month is not None: + + months = [ + "JAN", + "FEB", + "MAR", + "APR", + "MAY", + "JUNE", + "JULY", + "AUG", + "SEP", + "OCT", + "NOV", + "DEC", + ] + + assert base_month in months, ( + "If a month is provided, it must be " + "one of " + ",".join(months) + "." + ) + + column = base_month + + else: + + warnings.warn("No base month was provided. Using annual CPI averages.") + column = "AVG" + + # Get cpi and subset the columns we need. + cpi = get_cpi_series() + cpi_series = cpi[[column]].dropna() + + try: + + deflator = np.divide( + cpi_series.loc[to_year].to_numpy(), cpi_series.loc[from_year].to_numpy() + ) + + except KeyError as e: + + message = ( + "Could not find a CPI value for the requested " + "year-month combinations." + ) + raise Exception(message).with_traceback(e.__traceback__) + + return deflator diff --git a/HARK/datasets/cpi/us/README.md b/HARK/datasets/cpi/us/README.md new file mode 100644 index 000000000..9be324894 --- /dev/null +++ b/HARK/datasets/cpi/us/README.md @@ -0,0 +1,22 @@ +# Inflation adjustments using the CPI research series. + +This folder contains tools for transforming nominal U.S. dollar quantities to different base years using the consumer price index. + +## Data + +The dataset is stored in file `./r-cpi-u-rs-allitems.csv`, which comes from the [U.S. Bureau of Labor Statistics](https://www.bls.gov/cpi/research-series/r-cpi-u-rs-home.htm). +As of January 21, 2021 the direct link to the file was [https://www.bls.gov/cpi/research-series/r-cpi-u-rs-allitems.xlsx](https://www.bls.gov/cpi/research-series/r-cpi-u-rs-allitems.xlsx). The BLS originally distributes the series as a `.xlsx` file. The file found here is a copy of the original, converted to `.csv`. + +The file contains the monthly research series (retroactive, using current methods) of the consumer price index (all items) starting in 1977. + +### Format + +The file is formatted so that each row represents a year, with CPI measurements for each month stored in columns in ascending order. There is an +additional column labeled `AVG` which corresponds to the average of CPI measurements across months. + +## Tools + +`CPITools.py` contains functions to: +- Download the latest series file from the BLS to the working directory. +- Read and format the CPI series as a Pandas DataFrame. +- Produce CPI deflators using the series for any given pair of years (between 1977 and 2019) and taking any month as base. diff --git a/HARK/datasets/cpi/us/__init__.py b/HARK/datasets/cpi/us/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/HARK/datasets/cpi/us/r-cpi-u-rs-allitems.csv b/HARK/datasets/cpi/us/r-cpi-u-rs-allitems.csv new file mode 100644 index 000000000..2ca34748a --- /dev/null +++ b/HARK/datasets/cpi/us/r-cpi-u-rs-allitems.csv @@ -0,0 +1,49 @@ +Consumer Price Index Research Series Using Current Methods (CPI-U-RS),,,,,,,,,,,,, +U.S. city average,,,,,,,,,,,,, +All items,,,,,,,,,,,,, +Not Seasonally Adjusted,,,,,,,,,,,,, +December 1977=100,,,,,,,,,,,,, +YEAR,JAN,FEB,MAR,APR,MAY,JUNE,JULY,AUG,SEP,OCT,NOV,DEC,AVG +1977,,,,,,,,,,,,100, +1978,100.5,101.1,101.8,102.7,103.6,104.5,105,105.5,106.1,106.7,107.3,107.8,104.4 +1979,108.7,109.7,110.7,111.8,113,114.1,115.1,116,117.1,117.9,118.5,119.5,114.3 +1980,120.8,122.4,123.8,124.7,125.7,126.7,127.5,128.6,129.9,130.7,131.5,132.4,127.1 +1981,133.6,135.2,136.3,137.1,137.9,138.7,139.7,140.7,141.8,142.4,142.9,143.4,139.1 +1982,144.2,144.7,144.9,145,146.1,147.5,148.5,148.8,149.5,150.2,150.5,150.6,147.5 +1983,151,151.1,151.2,152.4,153.2,153.7,154.3,154.8,155.6,156,156.2,156.4,153.8 +1984,157.2,158,158.3,159.1,159.5,160,160.5,161.1,161.8,162.2,162.2,162.4,160.2 +1985,162.6,163.2,164,164.6,165.3,165.7,166,166.4,166.9,167.3,167.9,168.2,165.7 +1986,168.7,168.3,167.5,167.1,167.6,168.4,168.4,168.7,169.6,169.7,169.7,169.9,168.6 +1987,170.9,171.5,172.3,173.1,173.6,174.3,174.6,175.5,176.4,176.7,176.9,176.7,174.4 +1988,177.2,177.5,178.3,179.1,179.7,180.4,181.1,181.8,183,183.4,183.6,183.7,180.7 +1989,184.5,185.2,186.2,187.4,188.4,188.8,189.3,189.4,190.1,190.9,191.2,191.4,188.6 +1990,193.3,194.1,195.2,195.5,195.8,196.8,197.6,199.3,200.9,202,202.3,202.3,197.9 +1991,203.2,203.4,203.6,203.8,204.4,204.8,205,205.5,206.4,206.5,207,207.1,205.1 +1992,207.5,208.1,208.9,209.3,209.6,210.1,210.4,210.9,211.5,212.1,212.4,212.3,210.2 +1993,212.9,213.6,214.3,214.9,215.3,215.5,215.6,216.1,216.3,217.1,217.2,217,215.5 +1994,217.4,218,218.7,219,219.2,219.8,220.3,221.1,221.4,221.6,221.8,221.7,220 +1995,222.5,223.2,223.9,224.6,225,225.5,225.6,226,226.5,227,226.9,226.7,225.3 +1996,227.8,228.6,229.8,230.6,231.1,231.3,231.6,231.9,232.7,233.3,233.7,233.7,231.3 +1997,234.4,235.1,235.6,235.8,235.8,236.1,236.2,236.7,237.4,237.8,237.8,237.3,236.3 +1998,237.8,238.1,238.5,239,239.3,239.5,239.7,240.1,240.4,240.9,240.8,240.6,239.5 +1999,241.3,241.6,242.3,244,244,244.1,244.7,245.4,246.5,247.1,247.2,247.2,244.6 +2000,248,249.4,251.4,251.6,251.8,253.2,253.7,253.8,255.1,255.5,255.7,255.5,252.9 +2001,257.2,258.2,258.9,259.8,260.9,261.5,260.7,260.8,261.8,261,260.5,259.5,260.1 +2002,260.2,261.2,262.6,264.1,264,264.2,264.5,265.4,265.8,266.3,266.3,265.7,264.2 +2003,266.9,269,270.6,269.9,269.5,269.9,270.2,271.2,272,271.8,271,270.7,270.2 +2004,272.1,273.6,275.3,276.2,277.7,278.6,278.3,278.4,278.9,280.4,280.6,279.6,277.5 +2005,280.1,281.7,283.9,285.8,285.6,285.7,287,288.5,292,292.6,290.3,289,286.9 +2006,291.3,291.9,293.6,296,297.4,298.1,298.9,299.6,298.1,296.5,296,296.5,296.2 +2007,297.4,299,301.7,303.6,305.5,306.1,306,305.5,306.3,306.9,308.8,308.6,304.6 +2008,310.1,311,313.7,315.6,318.2,321.5,323.2,321.9,321.4,318.2,312.1,308.8,316.3 +2009,310.2,311.7,312.5,313.3,314.2,316.9,316.4,317.1,317.3,317.6,317.8,317.3,315.2 +2010,318.3,318.4,319.7,320.3,320.5,320.2,320.3,320.7,320.9,321.3,321.5,322,320.4 +2011,323.6,325.2,328.3,330.5,332,331.7,332,332.9,333.4,332.7,332.4,331.6,330.5 +2012,333.1,334.6,337.1,338.1,337.7,337.3,336.7,338.6,340.1,340,338.4,337.5,337.5 +2013,338.6,341.4,342.2,341.9,342.5,343.3,343.5,343.9,344.3,343.4,342.8,342.8,342.5 +2014,344.1,345.4,347.6,348.7,350,350.7,350.5,349.9,350.2,349.3,347.5,345.6,348.3 +2015,344,345.5,347.5,348.3,350,351.3,351.3,350.8,350.3,350.2,349.4,348.3,348.9 +2016,348.8,349.1,350.6,352.3,353.7,354.9,354.3,354.7,355.5,356,355.4,355.5,353.4 +2017,357.6,358.7,359,360.1,360.4,360.7,360.5,361.6,363.5,363.2,363.3,363.1,361 +2018,365,366.7,367.5,369,370.5,371.1,371.1,371.3,371.8,372.4,371.2,370,369.8 +2019,370.7,372.2,374.3,376.3,377.1,377.2,377.8,377.8,378.1,379,378.8,378.5,376.5 diff --git a/HARK/datasets/tests/test_load_data.py b/HARK/datasets/tests/test_load_data.py index 7040760b5..2f82827fc 100644 --- a/HARK/datasets/tests/test_load_data.py +++ b/HARK/datasets/tests/test_load_data.py @@ -1,6 +1,6 @@ import unittest from HARK.datasets import load_SCF_wealth_weights - +from HARK.datasets.cpi.us.CPITools import cpi_deflator class test_load_SCF_wealth_weights(unittest.TestCase): def setUp(self): @@ -9,3 +9,26 @@ def setUp(self): def test_shape(self): self.assertEqual(self.SCF_wealth.shape, (3553,)) self.assertEqual(self.SCF_weights.shape, (3553,)) + +# %% US CPI tests +class test_cpi_deflators(unittest.TestCase): + + def test_month_deflators(self): + + # Same year test + defl_same_year = cpi_deflator(2000, 2000, 'SEP') + self.assertEqual(defl_same_year[0], 1.0) + + # Different year test + defl_diff_year = cpi_deflator(1998, 2019, 'SEP') + self.assertAlmostEqual(defl_diff_year[0], 1.57279534) + + def test_avg_deflators(self): + + # Same year test + defl_same_year = cpi_deflator(2000, 2000) + self.assertEqual(defl_same_year[0], 1.0) + + # Different year test + defl_diff_year = cpi_deflator(1998, 2019) + self.assertAlmostEqual(defl_diff_year[0], 1.57202505) \ No newline at end of file