объект не найден в цикле foreach

Я запускаю модели векторной авторегрессии в R, используя библиотеку vars, и я хочу использовать функцию foreach для параллельного запуска моделей, но это приводит к ошибке:

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

Код работает нормально, если не включены экзогенные переменные, но как только я добавляю их в модель, возникает ошибка. Ниже приведен минимальный пример ошибки:

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

Даже если я перемещаю все внутри цикла, ошибка сохраняется. Но если экзогенные переменные не включены, код работает нормально:

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

Ошибка воспроизводится в Windows и Mac с R 4.2 и в Linux с R 3.62.


person tylar J    schedule 04.08.2020    source источник


Ответы (1)


Очевидно, это какая-то проблема с внутренней функцией VAR(), пытающейся снова получить доступ к exogen из глобальной среды. См. ветку здесь.

Итак, решение для вас - добавить .GlobalEnv$exogen.train <- exogen.train в ваш цикл:

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)))
}
person JonasV    schedule 04.08.2020
comment
Это действительно решает проблему, большое спасибо! - person tylar J; 04.08.2020