I am not very familiar with filters. The Hodrick-Prescott filter as one can find it e.g. in wikipedia is two-sided. I also found an R implementation for this in the R package mFilter. There the filter is given as: find $(\tau_t)_{t=1}^T$ such that $$ \left(\sum_{t=1}^T (y_t - \tau_t)^2 + \lambda \sum_{t=2}^{T-1} (\tau_{t+1}-2 \tau_{t} + \tau_{t-1} )^2\right) \rightarrow Min. $$

If I try to formulate a one-sided version of it myself, then I would take backward looking second order differences. I.e. find $(\tau_t)_{t=1}^T$ such that $$ \left(\sum_{t=1}^T (y_t - \tau_t)^2 + \lambda \sum_{t=3}^{T} (\tau_{t-2}-2 \tau_{t-1} + \tau_t )^2\right) \rightarrow Min. $$

How is the usual formulation of a one-sided Hodrick-Prescott filter and does there exist a robust R implementation?

  • $\begingroup$ Well, the sum on the right is the same in this formulation ... just a shift in indexation ... but what can we do? $\endgroup$ – Richard Jan 18 '13 at 12:36
  • $\begingroup$ Of course, my formulation of the one-sided version is just a guess, if you have/find the correct form then please forget the second formula. $\endgroup$ – Richard Jan 18 '13 at 15:47
  • 1
    $\begingroup$ The only way out seems to be an application of the Kalman filter as e.g. in home.ubalt.edu/ntsbarsh/stat-data/cardamone.pdf $\endgroup$ – Richard Jan 20 '13 at 15:06
  • $\begingroup$ I have posted another question in this context: stats.stackexchange.com/questions/48326/… $\endgroup$ – Richard Jan 23 '13 at 11:24

An implementation in R using the dlm package is shown below. It's a bit hackish, but it does the job nonetheless. You may be able to take it and adjust it to your need. I may come back and tidy this up and put the corresponding equations to help.


filterHP <- function(series,lambda=1600){
  # Function description: HP filter using DLM package.
  if(!"ts" %in% class(series)) stop("series is not a \"ts\" object.")

  # Set state priors
  level <- series[1]
  slope <- mean(diff(series),na.rm=TRUE)

  # Set up HP filter in a DLM model
  model <- function(param){
    trend <- dlmModPoly(dV = 1,
                        dW = c(0,1/lambda),
                        m0 = c(level,slope),
                        C0 = 2 * diag(2))

    # AR(2) model
    cycle <- dlmModARMA(ar     = ARtransPars(c(0,0)),
                        sigma2 = 1e-07)      

    hp_filter_dlm <- trend  + cycle


  # MLE Estimation
  MLE       <- dlmMLE(series,c(0.5,0.4),model)
  # Estimated parameters
  EstParams <- model(MLE$par)
  # Smoothed series
  Smooth_Estimates <- dlmSmooth(series,EstParams)

  # Trend and Cycle
  trend <- Smooth_Estimates$s[,1]
  cycle <- series - trend

  # Plot the data ---
  par(mfrow = c(2,1),
      oma = c(1,3,0,0) + 0.1,
      mar = c(1.5,1,1,1) + 0.1)
  title(main="HP Filter - Trend")
  par(mar = c(1,1,1.5,1) + 0.1)
  title(main="HP Filter - Cycle")
  par(mfrow = c(1,1),
      oma = c(0,0,0,0),
      mar = c(5.1,4.1,4.1,2.1))  

  # Return the data
  data <- ts.union(series,trend,cycle)

# Load some data

# Compare two implementations


# The data used is annual, so arguably lambda = 1600 should really be 6.25.
  • $\begingroup$ The function actually works! Some parts are tricky: the param is not used in MLE part, the AR(2) specification was switched off, and the smoother is a two-sided filter, while the dlmFilter would be one-sided version (real-time) estimates. The original idea works, so could be used to augment for trend-cycle universal decomposition. $\endgroup$ – Dmitrij Celov May 7 at 15:18
  • $\begingroup$ @DmitrijCelov I answered this question way back in 2015. To be honest, I could (and should) update it with some improvements. Thanks for flagging this and I'll come back to it again. Glad it works after this time! $\endgroup$ – Graeme Walsh May 7 at 19:55
  • $\begingroup$ Sure, @Graeme, I have worked through your original function yesterday and made modification to allow for constant drift too and play with the order of polynomial. The one-sided filter is just dlmFilter(series,EstParams) isntead smoother. Thanks a million again for inspiration. AR(2) model add-on is also handy. I guess, you were using the function for a particular project. $\endgroup$ – Dmitrij Celov May 8 at 6:50

It turns out that the Kalman filter representation as one can find here: State Space formulation of Hodrick-Prescott filter

yields a solution.

Having formulated the equations one can use the package SSPiR to estimate the solution.


This is the one sided version: Stock; Watson (1999). "Forecasting Inflation". Journal of Monetary Economics 44: 293–335. doi:10.1016/s0304-3932(99)00027-6.

  • 1
    $\begingroup$ Can you give a summary of the information in the paper to help future readers decide if they want to pursue it? $\endgroup$ – gung May 8 '15 at 23:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.