25
votes

Say I've got a data.frame with prices in one column and years in another:

prices <- rnorm(200, mean=10, sd=3)
years <- round(rnorm(200, mean=2006, sd=5))
df <- data.frame(prices, years)

Now say I want to normalize all these prices to 2008 dollars using the consumer price index. I could go look the conversion values up and do the calculation manually, but my intuition tells me that there is probably a package to do this automagically. A search of r-seek and cran did not yield anything obvious.

Does anyone know of anything?

4
You can use getSymbols from quantmod to download CPI data from FRED. I'm not sure which you want, but you can look here. e.g. getSymbols("CPIAUCSL", src='FRED') will download the Consumer Price Index for All Urban Consumers: All Items - GSee
@GSee why a comment and not an answer? This seems pretty complete. - Gregor Thomas

4 Answers

27
votes

You can get CPI data from FRED using the FRED method of the getSymbols function in the quantmod package

getSymbols("CPIAUCSL", src='FRED') #Consumer Price Index for All Urban Consumers: All Items
#[1] "CPIAUCSL"
tail(CPIAUCSL)
#           CPIAUCSL
#2012-03-01  229.098
#2012-04-01  229.177
#2012-05-01  228.527
#2012-06-01  228.618
#2012-07-01  228.723
#2012-08-01  230.102

# make an `xts` object of prices
set.seed(1)
p <- xts(rnorm(63, mean=10, sd=3), seq(from=as.Date('1950-12-01'), by='years', length.out=63))
colnames(p) <- "price"

The CPI inflation calculator at the BLS

... uses the average Consumer Price Index for a given calendar year... For the current year, the latest monthly index value is used.

(For this answer, I'm going to ignore the second part of the above quote...)

So, calculate an annual average

avg.cpi <- apply.yearly(CPIAUCSL, mean)

Then divide all index levels by the base price to create a conversion factor

cf <- avg.cpi/as.numeric(avg.cpi['2008']) #using 2008 as the base year
dat <- merge(p, cf, all=FALSE)
dat$adj <- dat[, 1] * dat[, 2]

tail(dat)
#               price  CPIAUCSL       adj
#2006-12-01  8.898336 0.9363693  8.332128
#2007-12-01  6.867596 0.9632483  6.615200
#2008-12-01 11.709159 1.0000000 11.709159
#2009-12-01  9.594836 0.9967933  9.564069
#2010-12-01 17.204853 1.0131453 17.431015
#2011-12-01  9.882280 1.0449769 10.326754
9
votes

There is a much simpler solution for acquiring the annual CPI (e.g., CPIAUCSL) that does not require use of the quantmod package, which seems to always have compatibility issues for one reason or another, at least in my experience.

require(lubridate) || install.packages("lubridate")
require(dplyr) || install.packages("dplyr")
monthly_cpi <-
  read.table("http://research.stlouisfed.org/fred2/data/CPIAUCSL.txt",
             skip = 53, header = TRUE)
monthly_cpi$cpi_year <- year(monthly_cpi$DATE)
yearly_cpi <- monthly_cpi %.% group_by(cpi_year) %.% summarize(cpi = mean(VALUE))

Then, to create your adjustment factor relative to say, last year's prices:

yearly_cpi$adj_factor <- yearly_cpi$cpi/yearly_cpi$cpi[yearly_cpi$cpi_year == 2013]

You have to find out how many lines to skip, but then again, that causes you to actually look at the lines that are skipped by viewing the actual data source, which happens to have useful preamble information.

BUT WAIT! THERE'S MORE!

Thanks to @GSee (who gave the checked answer) for noting that there is a .csv version for which you need not skip any rows! Using this version, the code is:

require(lubridate) || install.packages("lubridate")
require(dplyr) || install.packages("dplyr")
monthly_cpi <-
  read.csv("http://research.stlouisfed.org/fred2/data/CPIAUCSL.csv", header = TRUE)
monthly_cpi$cpi_year <- year(monthly_cpi$DATE)
yearly_cpi <- monthly_cpi %.% group_by(cpi_year) %.% summarize(cpi = mean(VALUE))
yearly_cpi$adj_factor <- yearly_cpi$cpi/yearly_cpi$cpi[yearly_cpi$cpi_year == 2013]
2
votes

Use priceR, like so:

set.seed(123)
prices <- rnorm(200, mean=10, sd=3)
years <- round(rnorm(200, mean=2006, sd=5))
df <- data.frame(prices, years)

library(priceR)
adjust_for_inflation(prices, years, "US", to_date = 2008)
# [1]  6.707112  8.102301 16.228195  9.785813 11.795624 17.197669 13.589684  7.210790  6.744690  9.250294 14.267029 11.561430  9.921566 12.007162 10.244619

Notes

  • This approach automagically uses up-to-date CPI data from World Bank
  • adjust_for_inflation() works for all countries - you can see a full list with show_countries()
0
votes

I think it should be noted that GSee's solution is technically correct but probably isn't want most people want when they talk about adjusting for inflation.

In my experience most people want to know how much an item purchased in years past would cost in today's dollars.

Based on GSee's code, this yields:

as.numeric(avg.cpi['2008'])/avg.cpi
dat <- merge(p, cf, all=FALSE)
dat$adj <- dat[, 1] * dat[, 2]