2017-10-12 4 views
0

J'ai un cas d'utilisation où j'essaie de lancer appel mon Rscript sur un tas de fichiers. Je l'ai écrit l'extrait ci-dessous -Calcul parallèle en R pour les commandes shell

for(i in 1:length(fileNames)){ 

    generateTolerancesCommand = paste(c("Rscript ",modelScriptName, 
             " --inp=",paste(c("'",dimensionsFolder, "/", fileNames[i],"'"), collapse = ""), 
             " --sea=",seasonal, 
             " --freq=",freq, 
             " --outp=",paste(c("'",outputFolder,"/","'"), collapse=""), 
             " --tp=",tp, 
             " --sd=",sd, 
             " --end=",end, 
             " --op=",op, 
             " --tls=",tls, 
             " --pts=",pts, 
             " --userf=",paste(c("'",dimensionsFeedbackFolder, "/", fileNames[i],"'"), collapse = "") 
            ),collapse="") 
    system(generateTolerancesCommand) 
} 

Cela fonctionne très bien, mais il prend habituellement environ 3-4 minutes pour 1 boucle pour terminer finalement prendre environ 2 heures actuellement pour terminer le script. Je pense que je peux le faire mieux en le rendant parallèle. Dans chaque itération, je produis un extrait indépendant de l'exécution R qui peut fonctionner sur un ensemble de données indépendant. J'ai essayé de lire sur des bibliothèques parallèles comme parallel, doParallel dans R, mais je ne suis pas en mesure de comprendre la meilleure façon qui peut être appliquée pour mon utilisation. Quelqu'un d'expérimenté dans ce domaine peut-il me suggérer un moyen?

+0

Vos scripts retournent quelque chose? Ecrire à l'env global? Que veux-tu en tirer? –

+0

Oui, ils produisent une sortie dans le dossier défini transmis en tant qu'argument de ligne de commande. –

+0

FYI, au lieu d'ajouter manuellement des guillemets shell, utilisez 'shQuote (str)'; il est spécifique au système d'exploitation et prend soin d'échapper certains caractères, etc. – HenrikB

Répondre

0

Si vous ne voulez pas créer de variables dans l'environnement mais simplement écrire des fichiers de sortie, vous pouvez simplement remplacer votre boucle par foreach.

library(foreach) 
cl <- parallel::makeCluster(parallel::detectCores() - 1) 
doParallel::registerDoParallel(cl) 
foreach(i = seq_along(fileNames), .combine = 'c') %dopar% { 

    ## PUT YOUR CODE HERE 

    NULL 
} 
parallel::stopCluster(cl) 

Le NULL ici avec le .combine = 'c' est juste pour que rien foreach rendement (juste un NULL), parce que foreach fonctionne plus d'une lapply qu'une boucle for. Vous pouvez en apprendre plus avec this tutorial.

+0

J'ai exécuté mon code comme suggéré par vous. Laissez-moi évaluer la performance. Est-il possible de vérifier combien de commandes shell parallèles s'exécutent en parallèle. Essentiellement mon code à l'intérieur du foreach appelle le système(). –

+0

@PrakharGupta Ouvrez votre moniteur système. Vous aurez un processus appelé 'R' pour chaque noyau utilisé. –

+0

Merci. Ça a marché. Pouvez-vous me recommander de bonnes implémentations de modèles de design dans R blog aussi. –