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.
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)))
}