Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"object not found" in foreach loop

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.

like image 412
T. J. Avatar asked Mar 24 '26 12:03

T. J.


1 Answers

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)))
}
like image 117
JonasV Avatar answered Mar 26 '26 00:03

JonasV