2015-10-08 2 views
0

Je rencontre des difficultés pour exporter une trame de données vers %dopar% dans foreach package. Il fonctionne si j'utilise %do% avec registerDoSEQ(), mais avec registerDoParallel() je reçois toujours:Exporter la variable dans foreach

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

Voici un exemple reproductible à l'aide des données kyphosis du package rpart. Je suis en train de paralléliser régression par étapes un peu:

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 est une variable définie par l'utilisateur) –

+1

Je ne sais pas pourquoi cela ne fonctionne pas, mais vous pouvez le faire fonctionner en mettant votre appel à glm dans la boucle. J'espère que cela aidera le dépannage. Je suspecte que le problème est avec la façon dont la fonction d'étape utilise les données de l'objet d'ajustement. –

+0

@ antoine-sac Oui, cela fonctionne de cette façon, mais c'est quelque chose que j'ai essayé d'éviter car il n'est pas nécessaire d'adapter le modèle dans chaque travailleur. –

Répondre

0

Ajouter ce dans le corps de foreach avant d'appeler la fonction step:

.GlobalEnv$kyphosis <- kyphosis 

Je ne sais pas pourquoi cela se produit, mais mon intuion est que step appels glm à l'intérieur lui-même à l'aide des informations stockées dans fit$call, qui est

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

avec une nouvelle formule mise à jour, mais la partie data = kyphosis reste la même. Donc glm essaie de chercher kyphosis dans l'environnement global.