Search code examples
rfor-loopoptimizationforecastingholtwinters

Avoid "optimization failure" in for loop in R


I'm trying to make a lot of time series forecast using the HoltWinters function in R. For this purpose, I use a for loop and inside I call to the function, and save the prediction in a data.frame.

The problem is that some results of the HoltWinters function gives errors, specifically optimization errors:

Error en HoltWinters(TS[[i]]) : optimization failure

This error break the loop.

So what I need is something like "try": if it can make the HoltWinters function, it saves the prediction, otherwise it save the error.

The code below replicates the problem:

data <- list()
data[[1]] <- rnorm(36)
data[[2]] <-
  c(
    24,24,28,24,28,22,18,20,19,22,28,28,28,26,24,
    20,24,20,18,17,21,21,21,28,26,32,26,22,20,20,
    20,22,24,24,20,26
  )
data[[3]] <- rnorm(36)

TS <- list()
Outputs <- list()

for (i in 1:3) {
  TS[[i]] <- ts(data[[i]], start = 1, frequency = 12)
  Function <- HoltWinters(TS[[i]])
  TSpredict <- predict(Function, n.ahead = 1)[1]
  Outputs[[i]] <-
    data.frame(LastReal = TS[[i]][length(TS[[i]])], Forecast = TSpredict)
}

Where i <- 2 The problem is generated.

What I need is that in this example the "Outputs" list is as follows:

> Outputs
[[1]]
   LastReal  Forecast
1 0.5657129 -2.274507

[[2]]
  LastReal Forecast
1    error    error

[[3]]
   LastReal   Forecast
1 0.4039783 -0.9556881

Thanks in advance.


Solution

  • I ran into this same problem with HoltWinters the other day and took Roman's advice by using tryCatch. It's not the most intuitive to implement based on the documentation, but I found this link very helpful for understanding it: How to write trycatch in R

    My solution built off of the sample there.

        data <- list()
    
    data[[1]] <- rnorm(36)
    data[[2]] <- c(
      24,24,28,24,28,22,18,20,19,22,28,28,
      28,26,24,20,24,20,18,17,21,21,21,28,
      26,32,26,22,20,20,20,22,24,24,20,26
    )
    data[[3]] <- rnorm(36)
    
    TS <- list()
    Outputs <- list()
    result <- list()
    
    for (i in 1:3) {
      Outputs[[i]] <- tryCatch({
        #You can enter messages to see where the loop is
        #message(paste("Computing", i))
        TS[[i]] <- ts(data[[i]], start = 1, frequency = 12)
        Function <- HoltWinters(TS[[i]])
        TSpredict <- predict(Function, n.ahead = 1)[1]
        result[[i]] <-
          data.frame(LastReal = TS[[i]][length(TS[[i]])], Forecast = TSpredict)
      },
      error = function(cond) {
        #message(paste("ERROR: Cannot process for time series:", i))
        msg <- data.frame(LastReal = "error", Forecast = "error")
        return(msg)
      })
    }
    

    And for the Outputs

    > Outputs
    [[1]]
       LastReal  Forecast
    1 0.4733632 0.5469373
    
    [[2]]
      LastReal Forecast
    1    error    error
    
    [[3]]
       LastReal   Forecast
    1 0.8984626 -0.5168826
    

    You can use other error handling parameters such as finally and warning to deal with other exceptions that may arise.