"object not found" in foreach loop

2.9k views Asked by At

I am running vector autoregression models in R using vars library and I want to utilize the foreach function to run models in parallel but it yields an error saying

Error in { : task 1 failed - "object 'exogen.train' not found"

The code runs fine if no exogenous variables are included but once I add them to the model, the error occurs. Below is a minimal example of the error:

library(vars)
library(doParallel)

set.seed(123)
dat <- ts(matrix(rnorm(600), 200, 3), start = c(1961, 1), frequency = 12)
dat.train <- dat[1:100, ]
dat.test <- dat[101:200, ]

label <- sample(1:5, nrow(dat), replace = T)
exogen.train <- cbind(label = label[1:100])
exogen.test <- cbind(label = label[101:200])

ncores <- 6
cl <- makeCluster(ncores)
registerDoParallel(cl)

res <- foreach(i = 1:6, .combine = rbind, .packages = c("vars")) %dopar% {
    fit.VAR <- VAR(dat.train, p = i, type = "none", exogen = exogen.train)
    
    pred.valid <- predict(fit.VAR, dat.test, dumvar = exogen.test, n.ahead = nrow(dat.test))
    res <- lapply(pred.valid$fcst, sd)
    return(list(c(i, res)))
}
stopCluster(cl)
res

Even if I move everything inside the loop, the error persists. But if no exogenous variables are included, then the code runs fine:

ncores <- 6
cl <- makeCluster(ncores)
registerDoParallel(cl)

res <- foreach(i = 1:6, .combine = rbind, .packages = c("vars")) %dopar% {
    fit.VAR <- VAR(dat.train, p = i, type = "none")
    
    pred.valid <- predict(fit.VAR, dat.test, n.ahead = nrow(dat.test))
    res <- lapply(pred.valid$fcst, sd)
    return(list(c(i, res)))
}
stopCluster(cl)
res

The error is reproducible on Windows and Mac with R 4.2, and on Linux with R 3.62.

1

There are 1 answers

1
JonasV On BEST ANSWER

This is apparently some issue with the VAR() function internally trying to access exogen again from the global environment. See the thread here.

So the solution for you is adding .GlobalEnv$exogen.train <- exogen.train into your loop:

res <- foreach(i = 1:6, .combine = rbind, .packages = c("vars")) %dopar% {
  .GlobalEnv$exogen.train <- exogen.train
  fit.VAR <- VAR(dat.train, p = i, type = "none", exogen = exogen.train)
  pred.valid <- predict(fit.VAR, dat.test, dumvar = exogen.test, n.ahead = nrow(dat.test))
  res <- lapply(pred.valid$fcst, sd)
  return(list(c(i, res)))
}