*

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

Elsa Nario
Messages : 83
Enregistré le : 22 Mar 2019, 09:06

*

Messagepar Elsa Nario » 04 Nov 2019, 09:11

*

Elsa Nario
Messages : 83
Enregistré le : 22 Mar 2019, 09:06

*

Messagepar Elsa Nario » 04 Nov 2019, 09:13

*

Michaël Delorme
Messages : 67
Enregistré le : 04 Avr 2016, 10:21

Re: Fonction ou boucle

Messagepar Michaël Delorme » 04 Nov 2019, 09:26

Ce que tu souhaites en fait c'est pivoter ta table si j'ai bien compris.
Il n'est pas nécessaire de découper puis réassembler, tu peux utiliser la fonction pivot_longer de tidyr :
tu précises quelles colonnes vont passer en ligne (celles qui commencent par note), tu nommes la variable qui contiendra les types de note (num), tu nommes la variable qui contiendra les valeurs (note) ; on peut enlever avec names_prefix la partie note de la chaine de caractère et préciser le type de num (entier)

Code : Tout sélectionner

library(tidyverse)
Table <- data.frame(id=c(1,2,3,4,5),
                    nom=c("Paul","Matthieu","Camille","Mireille","Capucine"),
                    ville=c("Paris", "Marseille", "Lyon", "Lille", "Nantes"),
                    animal=c("Chat", "Chien", "Chat", "Chat", "Chien"),
                    note1=c(12,8,11,16,15),
                    note2=c(9,13,15,10,12),
                    note3=c(11,14,12,9,12),
                    note4=c(18,16,15,19,11))
table_note <- Table %>%
  pivot_longer(starts_with("note"), names_to = "num", values_to = "note",
               names_ptypes = list("num" = integer()), names_prefix = "note")


Tu obtiens :

Code : Tout sélectionner

# A tibble: 20 x 6
      id nom      ville     animal num    note
   <dbl> <fct>    <fct>     <fct>  <int> <dbl>
 1     1 Paul     Paris     Chat   1        12
 2     1 Paul     Paris     Chat   2         9
 3     1 Paul     Paris     Chat   3        11
 4     1 Paul     Paris     Chat   4        18
 5     2 Matthieu Marseille Chien  1         8
 6     2 Matthieu Marseille Chien  2        13
 7     2 Matthieu Marseille Chien  3        14
 8     2 Matthieu Marseille Chien  4        16
 9     3 Camille  Lyon      Chat   1        11
10     3 Camille  Lyon      Chat   2        15
11     3 Camille  Lyon      Chat   3        12
12     3 Camille  Lyon      Chat   4        15
13     4 Mireille Lille     Chat   1        16
14     4 Mireille Lille     Chat   2        10
15     4 Mireille Lille     Chat   3         9
16     4 Mireille Lille     Chat   4        19
17     5 Capucine Nantes    Chien  1        15
18     5 Capucine Nantes    Chien  2        12
19     5 Capucine Nantes    Chien  3        12
20     5 Capucine Nantes    Chien  4        11

Elsa Nario
Messages : 83
Enregistré le : 22 Mar 2019, 09:06

*

Messagepar Elsa Nario » 04 Nov 2019, 13:13

*

Michaël Delorme
Messages : 67
Enregistré le : 04 Avr 2016, 10:21

Re: Fonction ou boucle

Messagepar Michaël Delorme » 04 Nov 2019, 14:58

Par contre que signifie names_ptypes = list("num" = integer()) ?

Cela transforme la portion de chaine contenant num en entier (ce n'est pas indispensable, ça dépend de ce que tu fais de cette variable par la suite)

Est-ce que cela pourrait venir de mon intitulé de colonne ? car dans ma véritable table il s'agit d'un nom suivi d'un saut de ligne et d'une année.

Oui car

Code : Tout sélectionner

names_prefix = "note"
implique qu'on supprime le "note" de "note1", "note2", etc. Il faut que tu le modifies pour que ça s'applique à ton nom de colonne.

Code : Tout sélectionner

names_prefix = "nom\\n"
peut-être ?

Elsa Nario
Messages : 83
Enregistré le : 22 Mar 2019, 09:06

*

Messagepar Elsa Nario » 04 Nov 2019, 16:34

*

Florent Aubry
Messages : 324
Enregistré le : 25 Juin 2010, 10:21

Re: Fonction ou boucle

Messagepar Florent Aubry » 04 Nov 2019, 17:05

@Elsa question de novice : qu'est-ce qui justifie d'utiliser comme tu le fais :

Code : Tout sélectionner

table_note <- Table %>%
  pivot_longer(starts_with("note\r\n"), names_to = "num", values_to = "note",
               names_ptypes = list("num" = integer()), names_prefix = "note\r\n")
et non

Code : Tout sélectionner

table_note <-
  pivot_longer(Table, starts_with("note\r\n"), names_to = "num", values_to = "note",
               names_ptypes = list("num" = integer()), names_prefix = "note\r\n")
pourtant plus lisible et plus rapide ?

Serge Rapenne
Messages : 1426
Enregistré le : 20 Aoû 2007, 15:17
Contact :

Re: Fonction ou boucle

Messagepar Serge Rapenne » 04 Nov 2019, 18:21

Bonjour,

Personnellement je trouve l'écriture avec %>% plus lisible. On lit tout de la gauche vers la droite, on voit tout de suite quel sont les données d'entrée et avec RStudio le %>% s'obtient avec Ctrl + M donc question rapidité ça ne change pas grand chose
Dés que tu as plusieurs fonctions imbriquées, je trouve que ça fait une grandes différence. lire x<-F(G(H(K(y))) et, là encore pour moi bien, moins lisible que x<-y %>% K()%>%H()%>%G()%>%F() et si de surcroit, les fonctions admettent des paramétres, c'est encore plus facile à lire, on a moins besoin de faire attention au parenthésage.

Mes 2 centimes

Serge

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

Re: Fonction ou boucle

Messagepar Pierre-Yves Berrard » 04 Nov 2019, 20:20

Florent Aubry a écrit :plus rapide
À écrire ou à s'exécuter ?
PY

Florent Aubry
Messages : 324
Enregistré le : 25 Juin 2010, 10:21

Re: Fonction ou boucle

Messagepar Florent Aubry » 04 Nov 2019, 21:32

On lit tout de la gauche vers la droite
Ne serait-ce pas plus logique d'écrire alors :

Code : Tout sélectionner

x %>% F() -> y
?
Personnellement, je me perds rapidement avec une accumulation de %>%, mais je comprends que ce n'est pas le cas de tout le monde et qu'on peut trouver cela plus esthétique, même si cela peut couter très cher en temps dans une boucle. Si cela peut se justifier dans le cas d'imbrication que tu cites, je n'en vois aucune à écrire par exemple x %>% plot(), comme je l'ai déjà vu, surtout si on écrit par ailleurs sin( x) ou sqrt( x).

À écrire ou à s'exécuter ?
Les deux.

Par exemple, soit le code suivant :

Code : Tout sélectionner

x <- runif( 1000000)
microbenchmark( identity( x), x %>% identity, times=1000000)

donne

Code : Tout sélectionner

Unit: nanoseconds
           expr   min    lq        mean median    uq       max neval cld
    identity(x)     0     0    90.51562      1     1   2621936 1e+06  a
 x %>% identity 44048 47470 50534.02021  48753 49608 132129977 1e+06   b
Warning message:
In microbenchmark(identity(x), x %>% identity, times = 1e+06) :
  Could not measure a positive execution time for 51102 evaluations.

De même dans le cas d'imbrication, y <- F( G( H( x))), on arrive au résultat que cette imbrication est la plus rapide, même si trop de parenthèses la rend peu lisible, qu'ensuite :

Code : Tout sélectionner

y1 <- H( x)
y2 <- G( y1)
y <- F( y2)
est un peu plus lent et qu'en règle général y <- x %>% H() %>% G() %>% F() est de plusieurs ordres de grandeurs plus lent. Je préfère donc la deuxième écriture, d'autant que c'est celle qui facilite le debogage. Si les différences sont peu sensibles in fine quand il n'y a que peu d'itérations, cela peu se révéler catastrophique dans certains cas en passant de quelques minutes à plus d'une heure de calcul.

Donc, je pense quand dehors de la question de la lisibilité qui est un ressenti personnel qui diffère de l'un à l'autre, il faut aussi tenir compte de paramètres comme l'utilisation des ressources informatiques (CPU, mémoire, temps...)

Peut-être que cet échange mériterait son propre fil de discussion ?

Elsa Nario
Messages : 83
Enregistré le : 22 Mar 2019, 09:06

*

Messagepar Elsa Nario » 05 Nov 2019, 08:20

*

Michaël Delorme
Messages : 67
Enregistré le : 04 Avr 2016, 10:21

Re: Fonction ou boucle

Messagepar Michaël Delorme » 05 Nov 2019, 09:11

Qu'est-ce qui justifie d'utiliser comme tu le fais %>% ?


Je me joins aux arguments de Serge : plus lisible.
De plus c'est simple d'ajouter ou retirer une opération dans une chaine de plusieurs instructions.

Ne serait-ce pas plus logique d'écrire alors :
x %>% F() -> y


Je me pose aussi la question et il y a des débat à ce sujet... Je trouve que c'est plus logique aussi mais on voit moins bien qu'il s'agit d'une affectation ; à chacun de faire sa religion...

https://style.tidyverse.org/syntax.html#assignment
https://twitter.com/rdataberlin/status/1189632440685551616
http://www.win-vector.com/blog/2016/12/the-case-for-using-in-r/comment-page-1/

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Fonction ou boucle

Messagepar Mickael Canouil » 05 Nov 2019, 09:42

Bonjour,

J'utilise également le pipe pour des questions de lisibilité, mais pas de façon systématique pour des questions de performances.

L'abus de pipe est déconseillé, en particulier les longues suites de 25 fonctions ou le fameux x %>% plot().
Dans ces cas là, au lieu "d'alléger" le code et d'accroître la lisibilité, il augmente la complexité de débogage et diminue la lisibilité (surtout si on enlève les parenthèses des fonctions).

(Welcome in hell)

Code : Tout sélectionner

10 %>%
  rnorm %>%
  plot(10 %>% runif)


Pour ce qui est de l'affection au terme de droite, même si c'est logique d'un point de vue lecture, on en vient à perdre l'objet qui contient le résultat.

Pour moi, la question n'est pas d'opter pour le pipe ou non, mais de l'utiliser avec parcimonie.

EDIT : peut-être que cela mériterait en effet son propre sujet.
Mickaël
mickael.canouil.fr | rlille.fr


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité