2016-02-10 3 views
0

J'ai un M de table avec beaucoup de colonnes et de lignes, obtenues à partir d'un fichier texte:chutes de neige R: parallèle applique sur les colonnes de table

M <- read.table("text.csv",header=TRUE,sep="\t") 

Pour obtenir les rangs de colonnes I utilisé avec succès:

M <- apply(M,2,rank) 

Je voudrais accélérer le calcul mais je n'ai pas réussi à implémenter cette fonction dans les chutes de neige.

J'ai essayé:

library(snowfall) 
sfStop() 
nb.cpus <- 8 
sfInit(parallel=TRUE, cpus=nb.cpus, type = "SOCK") 
M <- sfClusterApplyLB(M, rank) # does not work 
M <- sfClusterApply(M,2,rank) # does not work 
M <- sfClusterApplyLB(1:8, rank,M) # does not work 

Quel est l'équivalent de M <- apply(M,2,rank) des chutes de neige?

Merci d'avance pour votre aide!

+0

Le second argument de "sfClusterApply" doit être une fonction. Il ne prend pas un argument de "marge". –

Répondre

1

L'équivalent de apply chute de neige est sfApply. Voici un exemple:

library(snowfall) 
sfInit(parallel=TRUE, cpus=4, type="SOCK") 
M <- data.frame(matrix(rnorm(40000000), 2000000, 20)) 
r <- sfApply(M, 2, rank) 
sfStop() 

Cet exemple fonctionne presque deux fois plus rapide que la version séquentielle sur ma machine Linux en utilisant quatre cœurs. Ce n'est pas trop mal vu que rank n'est pas très intensif en calcul.

0

Voici un exemple de travail:

rank_M_df_col_fx=function(i){ 
    #M<- read.table("text.csv",header=TRUE,sep="\t") 
    col_rank=rank(M[,i]) 
    return(col_rank) 
} 

M=data.frame(replicate(10,sample(0:100,1000,rep=TRUE))) 
n_cols=ncol(M) 

library(snowfall) 
sfInit(parallel=TRUE) # 
sfExportAll() 
rank_results_list=sfLapply(x=c(1:n_cols), fun=rank_M_df_col_fx) 
rank_dataframe <- data.frame(matrix(unlist(rank_results_list), nrow=nrow(M), byrow=F)) 

sfRemoveAll() 
sfStop() 

Cependant, après avoir montré comment le faire, c'est un type d'opération rapide que parallélisation ne donnera probablement des résultats beaucoup plus rapidement, étant donné les frais généraux de démarrage des instances , etc.

+0

Merci beaucoup pour cette très bonne réponse! J'ai fait quelques tests et, comme vous l'avez souligné, le code parallèle n'est pas plus rapide au moins sur mon exemple. – Fred

+0

Pas de problème! Si ma réponse répond à votre question, vous devez vérifier que la bonne réponse ... –

0

Merci beaucoup pour votre aide!

je combine enfin la solution de Lucas et Steve pour obtenir la solution idéale pour mon problème.

Je pense que mon code ne fonctionnait pas avec M < - sfClusterApply (M, 2, rang) car sfExportAll() manquait.

Donc finalement la solution la plus simple pour moi de travailler est:

M <- read.table("text.csv",header=TRUE,sep="\t") 
n_cols=ncol(M) 
nb.cpus <- 4 
library(snowfall) 
sfStop() 
sfInit(parallel=TRUE, cpus=nb.cpus, type = "SOCK") 
sfExportAll() 
M <- sfApply(M,2,rank) 
sfRemoveAll() 
sfStop() 
+0

La fonction « rang » n'a pas besoin de données de l'environnement mondial pour fonctionner correctement, alors que la fonction « rank_M_df_col_fx » dans la réponse de Lucas fait. Utiliser "sfExportAll" dans votre réponse ne fait que gaspiller du temps à créer des variables globales sur les travailleurs qui ne seront pas utilisés. La raison pour laquelle "sfClusterApply" n'a pas fonctionné pour vous est parce qu'elle équivaut à "lapply", pas à "apply". –

+0

Merci pour ce commentaire Lucas. C'est vrai que dans l'exemple simple du rang "sfExportAll" est inutile. Dans un autre calcul plus complexe, j'avais besoin de "sfExportAll". – Fred