[RÉSOLU] Alternatives aux boucles for

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Fred Santos
Messages : 106
Enregistré le : 11 Avr 2009, 10:00

[RÉSOLU] Alternatives aux boucles for

Messagepar Fred Santos » 12 Mar 2019, 19:00

Bonjour,

Je souhaiterais avoir une alternative rapide aux boucles for dans un exemple précis, pour lequel je ne vois pas trop comment m'en passer. Le problème est simple : j'ai ci-dessous deux extraits de jeux de données, correspondant à des mesures corporelles prises du côté droit et du côté gauche des mêmes individus :

Code : Tout sélectionner

right<- read.table(text="   Hum_01R Hum_02R Hum_03R Hum_04R Hum_05R
2      350      62      45      23      20
3      309      61      47      24      21
9      307      58      46      21      14
15     348      66      48      24      19
")

left <- read.table(text="   Hum_01 Hum_02 Hum_03 Hum_04 Hum_05
2     354     61     44     24     20
3     313     61     47     23     20
9     308     58     46     20     14
15    345     67     48     23     20
")

right # données côté droit
left # données côté gauche

Mon but est de créer un dataframe donnant, pour chaque paire possible d'individus (donc 4x4=16 paires dans cet exemple), l'écart entre les mesures gauches et les mesures droites, comme ci-dessous :

Code : Tout sélectionner

        ID_left ID_right Hum_01 Hum_02 Hum_03 Hum_04 Hum_05
2 / 2         2        2      4     -1     -1      1      0
2 / 3         2        3     45      0     -3      0     -1
2 / 9         2        9     47      3     -2      3      6
2 / 15        2       15      6     -5     -4      0      1
3 / 2         3        2    -37     -1      2      0      0
3 / 3         3        3      4      0      0     -1     -1
3 / 9         3        9      6      3      1      2      6
3 / 15        3       15    -35     -5     -1     -1      1
9 / 2         9        2    -42     -4      1     -3     -6
9 / 3         9        3     -1     -3     -1     -4     -7
9 / 9         9        9      1      0      0     -1      0
9 / 15        9       15    -40     -8     -2     -4     -5
15 / 2       15        2     -5      5      3      0      0
15 / 3       15        3     36      6      1     -1     -1
15 / 9       15        9     38      9      2      2      6
15 / 15      15       15     -3      1      0     -1      1

Ce tableau est très simple à obtenir avec une bête boucle for. Seulement, mes "vraies données" ne comportent pas 4 individus comme ici, mais beaucoup plus. À titre d'exemple, pour "seulement" 2.000 individus au départ, on a déjà un dataframe de 4 millions de lignes à créer... et mine de rien, c'est déjà long en R avec une boucle for ! (Surtout que je n'ai pas non plus seulement 5 variables, ce qui n'arrange rien.)

Ma question : connaîtriez-vous un moyen plus économe en temps de calcul pour obtenir mon fameux tableau de différences à partir des deux objets "left" et "right" ci-dessus ?

Merci bien !

Pierre-Yves Berrard
Messages : 685
Enregistré le : 12 Jan 2016, 23:30

Re: Alternatives aux boucles for

Messagepar Pierre-Yves Berrard » 12 Mar 2019, 21:08

Bonjour,

Un merge sans spécifier de "by" renvoie le produit cartésien des deux tables :

Code : Tout sélectionner

merge(right, left)
(ajouter au préalable les identifiants sous forme de colonne plutôt que de noms de lignes)

Voir ce sujet à propos du temps d'exécution.
PY

Logez Maxime
Messages : 2890
Enregistré le : 26 Sep 2006, 11:35

Re: Alternatives aux boucles for

Messagepar Logez Maxime » 13 Mar 2019, 07:53

Bonjour,

déjà le plus simple c'est que les deux tableaux de données soit stockés sous forme de matrice et peut-être même d'entier ici.
après tu peux faire comme ça :

Code : Tout sélectionner

tab <- expand.grid(ID_left = rownames(left), ID_right = rownames(right))
left[tab$ID_left,]-right[tab$ID_right,]
Cordialement,
Maxime

Fred Santos
Messages : 106
Enregistré le : 11 Avr 2009, 10:00

Re: Alternatives aux boucles for

Messagepar Fred Santos » 13 Mar 2019, 08:30

Bonjour Pierre-Yves et Maxime,
Wow, merci à vous ! Va vraiment falloir que je commence à regarder sérieusement du côté de ces fonctions de base que je n'utilise pourtant jamais... Je viens de tester vos solutions et effectivement, c'est le jour et la nuit en termes de temps d'exécution. (J'ai l'impression que sur mes données entières, ça doit améliorer les choses d'un facteur 50 ou 100, à vue de pif...)
Grand merci !


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Guillaume Devailly, matthieu faron et 2 invités