Les posteurs les plus actifs de la semaine
Eric Wajnberg
 
zezima
 
Nik
 
margotte185
 
c@ssoulet
 
Coco
 
Ayana
 


Les boucles sont déconseillées dans R ?

Voir le sujet précédent Voir le sujet suivant Aller en bas

Les boucles sont déconseillées dans R ?

Message par zezima le Ven 29 Sep 2017 - 14:18

Bonjour,

J'en ai fait les frais lors de simulations, d'avoir un temps de calcul assez long en utilisant des boucles sous R, notamment les boucles "for".

Quel est la méthode optimale pour lancer des itérations sous R ?
Utiliser apply, sapply, lapply ou bien il existe d'autres méthodes ?

Merci d'avance
avatar
zezima

Nombre de messages : 747
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Eric Wajnberg le Ven 29 Sep 2017 - 16:47

Il faut au maximum utiliser la structure vectorielle des données de R.

Dans un exemple simple, si je veux multiplier tout les éléments d'un vecteur x par 2, je peux faire ça avec une boucle, ou bien juste taper 2*x, etc.

On peut également, en cas de nécessiter, utiliser la fonction compile() du package compiler, qui réduit pas mal les temps de calculs, notamment dans des simulations. Je l'utilise fréquemment.

Enfin, la solution que je préfère, est de coder la simulation en C, et d'intégrer le code C compilé dans R, avec la fonction .C(). Ca demande un peu de pratique, mais c'est clairement la solution la plus rapide pour faire de la simulation, et ça offre d'un coup tout les outils statistiques et graphiques de R (par exemple pour analyser les résultats), ce qui est vraiment appréciable.

HTH, Eric.
avatar
Eric Wajnberg

Nombre de messages : 694
Date d'inscription : 14/09/2012

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Ayana le Ven 29 Sep 2017 - 18:00

Je suis d'accord avec Eric. Si toutefois tu n'as pas envie de programmer en C, la fonction apply permet deja de gagner enormement de temps. Une autre solution et de lancer tes simulations en parallele (package parallel), mais la encore, ca demande un peu plus de maitrise.

Ayana
avatar
Ayana

Nombre de messages : 458
Localisation : Londres
Date d'inscription : 18/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Nik le Lun 2 Oct 2017 - 6:36

Salut,

Cette discussion a eu lieu sur toutes les plates-formes d'entraide sur R et la réponse n'est jamais directe. Tu peux parfaitement avoir une boucle plus efficace qu'un apply.
Donc la première chose à faire si tu veux faire de l'optimisation est de screener ton code pour identifier les sources de lenteurs. Certains types d'objets sont à éviter (les listes par exemple et donc les data.frames). Des pratiques sont à proscrire comme construire la sortie au fur et à mesure des itérations: il vaut mieux, quand c'est possible, générer ta sortie dans un objet vide mais avec la structure complète et le remplir avec les itérations de la boucle. Il y a énormément de choses à faire (la vectorisation déjà citée par Eric est une très bonne clef d'optimisation) avant de se lancer dans de la programmation C (ou Python ou Julia ou....) ou le calcul parallèle.

Il en reste pas moins que les solutions C ou calcul parallèle sont diablement efficace ! Shocked Petit rappel au passage et sauf si j'ai loupé une actu là dessus à un moment, R utilise un seul processeur son fonctionnement de base. Donc si tu as un processeur à plusieurs coeurs, tu as des capacités limitées de calcul dans R.

HTH


Nik

Nombre de messages : 1550
Date d'inscription : 23/05/2008

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par droopy le Lun 2 Oct 2017 - 9:20

Bonjour,

Dans la famille des apply, très souvent c'est le vapply le plus rapide. La fonction apply étant la plus lente de sa famille (pour travailler sur un data.frame, un array ou une matrice). Après les fonctions apply and co ne sont que des alias qui renvoient vers des boucles ... via des fonctions compilées. Très souvent la boucle est plus lente que ces fonctions parce que mal programmée. Un exemple, le calcul de la moyenne des colonnes d'un tableau de 1000 * 1000 :
Code:
fun <- function(tab) {
  res <- numeric(ncol(tab))
  u <- 1
  for (i in tab) {
    res[u] <- mean(i)
    u <- u+1
  }
  res
}
fun <- compiler:::cmpfun(fun)

tab <- as.data.frame(matrix(rnorm(1e6),1e3))

Unit: milliseconds
              expr      min       lq     mean   median       uq      max neval
          fun(tab) 10.59437 10.70858 11.03133 10.84903 11.03667 15.22613   100
 sapply(tab, mean) 11.54315 11.68945 11.95098 11.81234 11.99111 15.68220   100
Moralité c'est pareil dans cet exemple si la boucle est bien programmée.

Après je partage (en partie) l'avis de Nik. La question des boucles est récurrente et dépend du contexte et de ce que l'on souhaite faire.
La chose certaine à éviter ce sont les boucles emboitées. Plusieurs boucles les unes dans les autres et c'est vite la catastrophe. Mais pour éviter ça on peut générer l'ensemble des combinaisons i, j, k, ... dans un data.frame via expand.grid et ne faire qu'une boucle sur les lignes de ce data.frame par exemple.

Ce qui semble important de faire aussi avec les boucles dans les dernières version de R qui utilisent la compilation Just In Time par défaut (fonction enableJIT du package compiler), c'est des les "encapsuler" dans une fonction, pour que cette dernière soit compilée et que le calcul aille plus vite (voir précédent exemple). Je ne suis pas réellement arrivé à savoir si les boucles étaient elles aussi compiler (tous mes tests en ce sens ne se sont pas révélés concluants).

De manière générale, Nik à raison il te faut identifier via du profiling les sources de lenteur de ton code, voir si tu ne peux pas les programmer autrement en les vectorisant par exemple. L'autre chose est aussi de sortir de la boucle toutes les opérations qui peuvent ne se faire qu'une seule fois. Par exemple si à chaque itération tu divises un résultat par 1000, alors il vaut mieux attendre la fin de toutes les itérations et diviser plutôt que de diviser par 1000 à chaque itération. C'est la fameuse vectorisation.

Une chose qui peut-être faite très simplement c'est de compiler ces fonctions avec la fonction cmpfun du package compiler. Des fois juste en utilisant la version normale ou la version compilée d'une même fonction le gain de temps peut-être appréciable.
Code:
Unit: milliseconds
      expr      min      lq    mean  median      uq      max neval
  fun(tab)  9.232556 10.95115 11.19212 11.14314 11.37778 21.72108  100
 fun2(tab) 10.947756 13.07807 13.43691 13.30158 13.57454 17.09574  100
fun2 n'était pas compilée et la compilation JIT désactivée dans cet exemple.

Le choix des objets est aussi important. Si tu ne travailles que sur des données de même type alors privilégie la matrice au data.frame par exemple. Si je reprends le premier exemple et que j'applique la fonction colMeans par exemple, sur le data.frame et son clone sous forme de matrice :
Code:
mat <- as.matrix(tab)
Unit: milliseconds
          expr       min        lq      mean    median        uq        max neval
 colMeans(tab) 15.158924 15.403197 21.473626 15.783954 20.193335 171.183964   100
 colMeans(mat)  1.835638  1.862822  1.916679  1.867541  1.872638   2.907118   100
Suivant le type d'objet la même fonction sera plus ou moins performante.

Nik a raison quand il dit que R ne travaille par défaut qu'avec un seul cœur de ton ordi. Si tu fais pas de calculs matriciels ou appel à des fonctions qui sont basées dessus, comme tout ce qui concerne les analyses multivariées, les modèles linéaires, etc. Alors je te conseille d'installer la version de R développée par Microsoft R Open. Elle est basée sur des librairies différentes pour les calculs matricielles. Ces librairies sont parallélisées et sans que tu t'en rendes compte tu fais du calcul matriciel en parallèle, ce qui permet dans ce cas précis de gagner du temps aussi.

Sinon pour ce qui concerne le calcul parallèle, je te dis juste de faire attention. Comme pour tout, mal pensé et/ou mal programmé il peut s'avérer encore plus long que le calcul en série. Si le calcul à chaque itération n'est pas trop long alors ça ne vaudra pas le coup. Pour une boucle de 1000 itérations et 4 coeurs, il est parfois plus rentable de paralléliser une boucle 250 itérations sur chaque cœur (4 * 250 = 1000),  que de lancer la boucle de 1000 en parallèle avec une seule itération faite à chaque fois sur un coeur. Au final on aura bien fait 1000 itérations, en parallèle, mais de manières différentes avec des temps de calculs très différents. Le choix du type de cluster, "SOCK", "FORK", etc. dépendra aussi de ta plateforme et aura un impact sur le temps de calcul. Si tu es sous Linux privilégie plutôt le FORK au SOCK. Sous windows pas le choix ça sera du SOCK. Après il y a aussi le type de parallélisation qui va jouer. Si toutes tes itérations sont supposées prendre le même temps alors tu gardes le types de parallélisation par défaut, si tu penses au contraire qu'il peut y avoir de grandes disparité en temps dans le calcul alors pars plutôt pour de la parallélisation de type load balancing et les fonctions de parallélisation se terminant par LB (parSapplyLB, etc.).

Pour résumé le plus rapidement ce que tu peux faire :
- compiler tes fonctions si ce n'est pas fait par défaut
- vectoriser tes calculs, sortir de la boucle tout ce qui peut-être fait en dehors
- profiler ton code ou utiliser microbenchmark pour comparer le temps d'exécution deux fonctions qui font le même travail
- utiliser MRO si tu fais du matriciel
- paralleliser

HTH
cdlt
avatar
droopy

Nombre de messages : 1070
Date d'inscription : 04/09/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par zezima le Mar 3 Oct 2017 - 8:03

Merci à tous pour ces informations,

Eric Wajnberg
Ayana

D'accord, je vais utiliser cette fonction compile() et également optimiser mon code afin de réduire les itérations inutiles.
Pensez-vous que ça vaut le coup de se former au langage C, pour les gains qu'on peut avoir, au détriment du temps de formation ? Je réalise assez souvent des simulations et je me vois utiliser R toute ma vie.

Nik
Ce que tu expliques au niveau des coeurs est-il lié au fait d'utiliser Intel core I7 ou Intel core I5 ? Je suis sous le 5 et j'ai malheureusement 4Go de RAM sur mon PC professionnel.
J'entends bien ce que tu dis mais je n'arrive pas à le visualiser, est-ce que le fait de créer des objets vides à remplir au fur et à mesure ressemble au code suivant ?

Code:

a=vector()
for(i in 1:10){
a[i]=i+1
}

Droopy
Merci pour toutes ces astuces, il est vrai que j'ai pour mauvaise habitude d'appliquer une même formule itérée sur chacun de mes objets (ce qui au final est stupide).

Le parallélisme est donc le fait de lancer le code sur plusieurs cores (qu'ils soient tous issus du même ordinateur ou non) ?

Concernant Microsoft R Open, je vais le tester chez moi, dans mon labo on n'a malheureusement pas d'autorisations sur l'installation de logiciels.

Ah et une dernière question d'ailleurs, si tu es dans un cas de figure où tu es obligé de lancer 3 boucles for() (du moins dans la théorie) pour un hypercube, le mieux à faire est donc de lancer 2 boucles for avec 1 vapply() ? (si j'ai bien compris)

Bon je me rends compte que mon code est assez loin d'être optimisé, tout ça va me faire gagner des journées et des journées de simulations.
Merci beaucoup à tous pour tous vos conseils, je m'en vais de ce pas essayer ces méthodes.
avatar
zezima

Nombre de messages : 747
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par droopy le Mar 3 Oct 2017 - 9:01

Bonjour,

la plupart des processeurs actuels, i3, i5 et i7 sont multicœurs, mais R par défaut n'utilise qu'un seul cœur pour faire les calculs. Ce qui veut dire que si tu as un ordi avec 8 cœurs alors tu n'utilises qu'un huitième de sa puissance pour faire les calculs. Ce qui est dommage non ?

L'exemple que tu donnes est effectivement a proscrire puisque à chaque itération tu l'écrases.
Code:
# mauvaise pratique n°1
a <- vector()
for (i in in 1:10)
  a[i] <- i+1
# mauvaise pratique n°2 :
a <-  NULL
for (i in 1:10)
  a <- c(a, i+1)

# bonne pratique :
a <- integer(10)
for (i in seq_along(a))
  a[i] <- i + 1
Dans la dernière boucle tu crées au préalable un objet qui stockera ton résultat et qui est définit selon la nature des résultats. Ici on sait qu'on va obtenir des entiers donc on génère un vecteur d'entier.
Après l'exemple n'est valable que pour la forme de la boucle, parce qu'ici ce que tu cherches à faire c'est d'ajouter 1 à des valeurs connues (1 à 10) donc c'est typiquement le genre de calculs qui peut être vectoriser et qui doit être fait en dehors de la boucle. Du genre :
Code:
a <- 1:10
a <- a+1

Oui le parallélisme est le fait de se servir de plusieurs coeurs en même temps au lieu de ne s'en servir que d'un seul (par défaut). Après on entre encore dans un autre monde, parce qu'il y a pas mal de manières différentes et de packages pour faire du parallélisme. Créer la structure qui permet de faire du parallélisme prend du temps, ainsi que les échanges entre les coeurs, donc ça ne vaut le coup que si les temps de calculs sont longs, sinon aucun intérêt. Dans mon précédent exemple, typiquement ça n'aurait pas d'intérêt de paralléliser.
Code:
library(parallel)
cl <- makeCluster(getOption("cl.cores", 4))
microbenchmark(mns <- parSapply(cl, tab, mean), mns <- sapply(tab, mean))
Unit: milliseconds
                            expr        min        lq      mean    median        uq        max neval
 mns <- parSapply(cl, tab, mean) 118.600636 136.918972 152.442330 140.903148 178.542046 211.514523  100
        mns <- sapply(tab, mean)  5.634669  6.077733  6.418282  6.217619  6.489648  8.172988  100
Moralité ici ça prend 25 fois plus de temps (alors que je n'ai pas pris en compte le temps de création du cluster) que la version non paralléliser. Bon c'est un contre exemple parfait parce qu'ici on a un code qui tourne en quelques millisecondes.

A priori, à tester, de trois boucles tu peux en revenir à une seule :
Code:
loops <- expand.grid(i = 1:3, j = 1:2, k = 1:4)
loops <- loops[do.call(order, loops),]
loops <- as.matrix(loops)
for (v in 1:nrow(loops)) ...
Après c'est même surement plus rentable de transformer loops en matrice et de travailler sur les lignes de loops qui te donne les indices de chacune des trois boucles.

A tester sur des grosses boucles, j'avoue ne pas l'avoir fait.

cdlt
avatar
droopy

Nombre de messages : 1070
Date d'inscription : 04/09/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Eric Wajnberg le Mar 3 Oct 2017 - 16:49

zezima a écrit:Eric Wajnberg
Ayana

D'accord, je vais utiliser cette fonction compile() et également optimiser mon code afin de réduire les itérations inutiles.
Pensez-vous que ça vaut le coup de se former au langage C, pour les gains qu'on peut avoir, au détriment du temps de formation ? Je réalise assez souvent des simulations et je me vois utiliser R toute ma vie.
Je ne vois pas trop bien comment faire un job de statisticien sans connaitre un langage de programmation "évolué", comme le C, par exemple. Ca me parait incontournable. Pour ce qui est de faire de la simulation (mon activité principale), l'utilisation de ce genre de langages me parait encore plus indispensable. Un langage interprété comme R va vite devenir limité/limitant, je le crains.

Mais bon, ça n'engage que moi..

Eric.
avatar
Eric Wajnberg

Nombre de messages : 694
Date d'inscription : 14/09/2012

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par droopy le Mer 4 Oct 2017 - 7:32

Eric Wajnberg a écrit:Je ne vois pas trop bien comment faire un job de statisticien sans connaitre un langage de programmation "évolué", comme le C, par exemple.
Pour ce que ça vaut, je ne connais pas d'autres langages que R ... mais il est vrai que je ne fais que peu de simulations qui demandent beaucoup de temps de calculs et que j'ai aussi accès à une ressource informatique conséquente.

De plus plus ça va et plus R est efficace et après c'est une question de temps disponible pour se former à un autre langage.

Eric Wajnberg a écrit:Mais bon, ça n'engage que moi..
On est d'accord :-)

cdlt
avatar
droopy

Nombre de messages : 1070
Date d'inscription : 04/09/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Ayana le Mer 4 Oct 2017 - 8:28

Je suis d'accord avec Eric pour dire que la maîtrise d'un autre langage est toujours un plus, mais pour une grande majorité d'études de simulations, R suffit. Sur un projet de plusieurs mois, perdre un ou deux jours en temps de calcul n'est pas si désastreux. Je fais énormément de simulations avec R, utilisant des méthodes "lentes" de type imputation multiple par équations chainées. Je ne peux pas faire tourner cela sur mon ordinateur car en temps total ça durerait plus d'un mois, mais en parallèle sur le HPC de mon université, c'est réglé en 24h (ce qui te laisse un peu de répit pour finir d'autres trucs en cours). Par contre, il faut bien tester ton code avant car la moindre petite erreur et tu repars pour une longue attente.
Si ça peut te rassurer, regarde les papiers publiés par des grands biostats contemporains (D Rubin, I White, J Higgins, D Altman...) et ils utilisent principalement R et Stata. La RSS propose des formations à la simulation avec R et Stata, donc ne t'en fais pas. Essaie juste d'optimiser ton code au mieux.
Et au pire, profite des temps de calcul pour prendre un café!
Ayana
avatar
Ayana

Nombre de messages : 458
Localisation : Londres
Date d'inscription : 18/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Eric Wajnberg le Mer 4 Oct 2017 - 10:36

Deux points en supplément de cette discussion.

1) Je fais de très lourds modèles de simulation (Monte Carlo), dans des conditions fortement stochastiques (écologie et comportement d'insectes). Un réplicat, sur une bonne machine, et codé en C, prend au mieux une vingtaine d'heures. Vue la stochasticité, je dois faire plusieurs centaines de réplicats pour récupérer une résultat moyen, et ce dans chacune des conditions comparées. Sur une machine linéaire, il me faudrait rapidement des années. Je fais donc tourner mes codes sur de très grosses grilles (clusters). Je n'ose imaginer comment je m'en sortirais si je devais faire tourner ceci codé en R, même en parallélisant, etc. Tout bonnement impossible.

2) R ok (et je l'utilise énormément), mais ça veut principalement dire utiliser des outils statistiques déjà existants. Parfois, il faut créer ses propres outils statistiques (dans mon cas lorsque j'ai des vraisemblances pas très propres à maximiser, ou bien des algorithmes génétiques avec des tournois, ou bien des calculs qui nécessitent l'usage de librairy de très grande précision, etc.). Dans ce cas, obligé de sortir de R (même si l'offre est riche), et il faut coder tout ceci de son côté.

Eric.


Dernière édition par Eric Wajnberg le Mer 4 Oct 2017 - 13:06, édité 4 fois
avatar
Eric Wajnberg

Nombre de messages : 694
Date d'inscription : 14/09/2012

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par droopy le Mer 4 Oct 2017 - 11:40

Bonjour,

ceci va dans le sens de mon précédent post, tout dépend de l'usage et des stats que l'on fait. Dans un cas comme le tien investir dans un autre langage fait sens, mais dans d'autres non. Le dernier point n'empêche pas de sortir de R, puisque nombres librairies sont développées pour étoffer l'offre. Les auteurs ayant développées de nouvelles méthodes en restant dans le langage. Comme souvent tout est une question de point de vue et d'utilisation.

cdlt
avatar
droopy

Nombre de messages : 1070
Date d'inscription : 04/09/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par zezima le Jeu 5 Oct 2017 - 9:52

Droopy
Merci beaucoup droopy pour ces précisions.

Si je comprends bien, il est conseillé de déterminer la taille des objets qu'on va remplir en amont ?
Par exemple il est mieux de préciser qu'une liste sera de taille 1000 si on veut la remplir de 1000 vecteurs (et qu'on a l'information en amont) ?

A priori, sur des codes longs (qui ne se comptent pas en secondes ou en minutes), le parallélisme l'emportera toujours sur le mono-coeur ?

Penses-tu qu'il est possible de bannir les boucles for() pour tous les cas de figures possibles si on maîtrise totalement le code R ?
Je suis en train de me mettre aux lapply, vapply, sapply, mais il me semble que certains cas de figures ne peuvent pas être réalisés sans une boucles for(), exemple :

Je voudrais créer 1000 vecteurs de 6 valeurs compris dans une liste.
Chaque liste est une courbe pour laquelle on a les valeurs de 6 points dépendant d'une formule :
Code:

result=list(rep("",1000))
d=1:6
a=rnorm(1000,0,1)
b=rnorm(1000,1,2)
c=rnorm(1000,20,1)

#Formule : result=c+(a*d)/(b+d)
result=c+(a*d)/(b+d) #Ce code ne marche pas

for(i in 1:1000){result[[i]]=c[[i]]+(a[[i]]*d)/(b[[i]]+d)} #Ce code marche mais nécessite une boucle for()

#On obtient finalement la liste de vecteurs de taille 6

Bon je divague mais je pense que c'est peut-être toujours dans la même optique.


Eric
Si C fait gagner un temps fou alors je m'y mettrais mais je pense qu'il y a un grand nombre d'étapes qui doivent précéder son utilisation, je ne suis pas un adepte de la programmation pure et dure pour le moment.
Et ça fait parti de mes objectifs car je commence à faire du Monte-Carlo et le nombre d'itérations peut vite devenir long.
avatar
zezima

Nombre de messages : 747
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par droopy le Jeu 5 Oct 2017 - 14:45

Il est clair que C te fera gagner énormément de temps au niveau du calcul. Ce qu'il te faut voir c'est le temps que ça va te prendre de développer le code C + le temps de calcul, par rapport à la même chose en R.

Par rapport à ton exemple je vois deux problème. D'une part la liste qui n'est pas nécessaire. Le résultat de ton calcul est toujours un vecteur de 6 valeurs numériques donc une matrice de 1000 lignes et de 6 colonnes permettra de stocker l'info. Le deuxième problème que je vois, c'est que ce qui change entre chaque opération ce sont les valeurs de d et non pas les autres valeurs, tu auras toujours la même valeur pour a, b et d. Donc tu peux juste boucler sur les valeurs de d plutôt que sur chacune des valeurs de a, b, etc. Donc au final tu passes d'une boucle sur 1000 valeurs à une boucle sur 6, c'est ce dont Eric parlait, il faut vectoriser tes calculs :
Code:
# ton code
result=list(rep("",1000))
d=1:6
a=rnorm(1000,0,1)
b=rnorm(1000,1,2)
c=rnorm(1000,20,1)

#Formule : result=c+(a*d)/(b+d)
# result=c+(a*d)/(b+d) #Ce code ne marche pas

for(i in 1:1000){
  result[[i]]=c[[i]]+(a[[i]]*d)/(b[[i]]+d)
}

# je stocke les résultats en matrice pour les comparer avec la suite
res <- do.call(rbind, result)

# une boucle possible :
mat <- matrix(numeric(), 1e3, 6)
for (i in 1:6){
  mat[,i] <- c + (d[i]*a)/(b+d[i])
}
La dernière boucle est mieux, on passe de 1000 itérations à 6 mais elle n'est pas non plus la plus efficace parce 'c' est ajouter à chaque fois, donc on peut l'ajouter en dehors de la boucle :
Code:
mat2 <- matrix(numeric(), 1e3, 6)
for (i in 1:6){
  mat2[,i] <- (d[i]*a)/(b+d[i])
}
mat2 <- mat2 + c
Après tu peux faire la même chose avec les apply :
Code:
mat3 <- vapply(d, function(x) c + (x*a)/(b+x),  numeric(1000))
mat4 <- sapply(d, function(x) c + (x*a)/(b+x))
Ici l'exemple porte sur des calculs relativement courts donc les différences ne seront pas énormes, mais c'est pour le principe d'optimisation.

Voila ce que ça donne en temps de calculs :
Code:
  expr      min        lq      mean    median        uq      max neval
  liste 1810.726 1872.2205 1948.3374 1892.3100 1924.7085  4643.714  1000
 Vapply  113.487  117.1720  150.9318  118.6790  121.2310  4493.728  1000
 Sapply  166.952  172.5405  267.7713  176.8655  185.4840 55914.830  1000
  Loop6  137.292  142.1725  185.1154  144.1095  147.0465  3755.548  1000

liste : ta boucle et Loop6 la boucle que sur les 6 valeurs de d.

cdlt
avatar
droopy

Nombre de messages : 1070
Date d'inscription : 04/09/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par droopy le Jeu 5 Oct 2017 - 19:54

On aurait pu même ne pas utiliser de boucle :
Code:
d2 <- matrix(as.numeric(d), length(d), length(a))
d2 <- t(d2)
mat <- c + (d2*a)/(b+d2)
Sans que ça soit plus efficace sur cet exemple que le vapply.

cdlt
avatar
droopy

Nombre de messages : 1070
Date d'inscription : 04/09/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par zezima le Mar 10 Oct 2017 - 9:46

Merci énormément pour ce cours interactif droopy.
Excuse-moi du retard de réponse, je suis overbooké en ce moment (surement à cause de mes simulations trop lentes).

C'est très intéressant et je me rends compte que mon code était... horrible avant que je ne crée ce topic.

Mention spéciale à vapply que je trouve particulièrement performant.

Je pense que ma prochaine étape sera de me mettre au langage C et à Rstan (petit à petit bien sur).
avatar
zezima

Nombre de messages : 747
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par zezima le Jeu 2 Nov 2017 - 13:06

Eric Wajnberg a écrit:Enfin, la solution que je préfère, est de coder la simulation en C, et d'intégrer le code C compilé dans R, avec la fonction .C(). Ca demande un peu de pratique, mais c'est clairement la solution la plus rapide pour faire de la simulation, et ça offre d'un coup tout les outils statistiques et graphiques de R (par exemple pour analyser les résultats), ce qui est vraiment appréciable.

Bonjour Eric, lorsque tu dis que C est vraiment le must pour faire tourner des simulations, le concept est de remplacer toutes les boucles et toutes les fonctions qui vont être utilisées dans R, de les compiler et enfin de lancer la simulation ?
Je vais me lancer dans quelques semaine dans le langage C je pense mais je préfère être sur de ce qu'il va falloir prendre en compte avant.
avatar
zezima

Nombre de messages : 747
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Eric Wajnberg le Jeu 2 Nov 2017 - 14:55

Tout ce qui peut être fait en C doit y être fait. C'est à dire, les boucles, les calculs en tout genre, etc. Y compris la lecture des données et/ou des paramètres (if any). Le coeur du code C doit être autonome, jusqu'à la sortie des résultats, qui peuvent être récupérer par R pour faire des graphs, des stats, etc.

Encore une fois, c'est comme ceci que je procède. On peut déléguer R au besoin des parties des calculs (par exemple tirage de valeurs pseudo-aléatoires, calcul matriciel, etc.) mais je préfère éviter pour réduire au maximum les temps de calcul.

HTH, Eric.
avatar
Eric Wajnberg

Nombre de messages : 694
Date d'inscription : 14/09/2012

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par zezima le Jeu 2 Nov 2017 - 15:22

Ah d'accord donc même les simulations doivent potentiellement être faites sous C.

Merci pour ces infos
avatar
zezima

Nombre de messages : 747
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Eric Wajnberg le Jeu 2 Nov 2017 - 16:19

Encore une fois, pas forcément. Mais c'est ce que je fais moi, et ca gagne beaucoup de temps, je pense.

Eric
avatar
Eric Wajnberg

Nombre de messages : 694
Date d'inscription : 14/09/2012

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par zezima le Mar 21 Nov 2017 - 14:25

Bonjour,

Je reviens vers vous au sujet de la parallélisation sous R.

Vous m'aviez conseillé d'installer Microsoft R Open qui réalise le parallélisme sans qu'on s'en rende compte.
Cependant je n'ai pas la possibilité de l'installer dans la structure où je travaille.

Je me penche donc vers les librairies mais il y en a plusieurs apparemment.

library(parallel)     #semble pas mal pour les boucles lapply
library(doRNG)     #idem et fait appel à la librairie foreach donc potentiellement plus évolué
library(doParallel) #idem
library(foreach)    #conseillé pour les matrices et listes
Je ne sais pas quelle librairie serait la plus optimale, j'utilise surtout les fonctions lapply(), sapply(), vapply() et apply() (et parfois les boucles for() pour de petits calculs). Etant donné que je lance neuf milliards de calculs de Residual Sum of Square, je pense que le choix peut avoir un gros impact (pour le moment je prends 3 jours pour tout lancer).

Savez-vous quelle librairie est la plus adaptée ?
(je précise que je suis sous Windows et sous R.3.2.1)

Ah et j'ai également entendu dire que Microsoft R Open est plus rapide que R avec un code optimisé pour la parallélisation (lui-même plus rapide que R-studio), est-ce que vous avez entendu parler de cette comparaison ? Cela peut m'être utile à domicile.

Merci
avatar
zezima

Nombre de messages : 747
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Les boucles sont déconseillées dans R ?

Message par Contenu sponsorisé


Contenu sponsorisé


Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum