2015-10-08 2 views
0

У меня возникли проблемы с экспортом рамки данных в %dopar% в пакете foreach. Это работает, если я использую %do% вместе с registerDoSEQ(), но с registerDoParallel() я всегда получаю:Экспортировать переменную в foreach

Error in { : task 1 failed - "object 'kyphosis' not found" 

Вот воспроизводимый пример использования kyphosis данных из rpart пакета. Я пытаюсь распараллеливание ступенчатого регресса немного:

library(doParallel) 
library(foreach) 
library(rpart) 

invars <- c('Age', 'Number', 'Start') 
n_vars <- 2 
vars <- length(invars) 
iter <- trunc(vars/n_vars) 
threads <- 4 
if (vars%%n_vars == 0) iter <- iter - 1 
iter <- 0:iter 

cl <- makeCluster(threads) 
registerDoParallel(cl) 
#registerDoSEQ() 

terms <- '' 
min_formula <- paste0('Kyphosis~ 1', terms) 
fit <- glm(formula = as.formula(min_formula), data = kyphosis, family = 'binomial') 

out <- foreach(x = iter, .export = 'kyphosis') %dopar% { 

    nv <- invars[(x * n_vars + 1):(min(x * n_vars + n_vars, vars))] 
    sfit <- step(object = fit, trace =FALSE, scope = list(
    lower = min_formula, 
    upper = as.formula(paste(min_formula, '+', paste0(nv, collapse = '+')))), 
    steps = 1, direction = 'forward') 
    aic <- sfit$aic 

    names(aic) <- if(nrow(sfit$anova) == 2) sfit$anova$Step[2] 
    aic 
} 
out 
stopCluster(cl) 
+0

(iter - определяемая пользователем переменная) –

+1

У меня нет ответа, почему он не работает, однако вы можете заставить его работать, поставив свой вызов на glm внутри цикла. Надеюсь, это поможет устранить неполадки. Я подозреваю, что проблема заключается в том, как функция step использует данные из объекта fit. –

+0

@ antoine-sac Да, он работает таким образом, но это то, что я пытался избежать, так как нет необходимости подгонять модель к каждому работнику. –

ответ

0

Добавьте это в теле foreach перед вызовом функции step:

.GlobalEnv$kyphosis <- kyphosis 

я не уверен, почему это происходит, но мой intuion что step называет glm внутри себя, используя информацию, хранящуюся в fit$call, которая

glm(formula = as.formula(min_formula), family = "binomial", data = kyphosis) 

с новой обновленной формулой, но часть data = kyphosis остается неизменной. Итак, glm пытается найти kyphosis в глобальной среде.

Смежные вопросы