2017-07-17 1 views
3

Y a-t-il des cas où il n'est pas avantageux d'utiliser le tuyau magrittr à l'intérieur des fonctions R du point de vue (1) de la vitesse et (2) de la capacité de déboguer efficacement?Tuyau Magrittr dans les fonctions R

+1

Vous posez des questions sur la vitesse d'exécution ou la vitesse en termes de temps de développement? – Dason

+1

De toute façon il y a des gens qui vous demanderaient s'il y a des cas où utiliser des tuyaux magrittr est avantageux en termes de vitesse ou de capacité de débogage ... – Dason

+0

La seule façon de répondre est de mettre en place plusieurs exemples et de les comparer. Avez-vous essayé de le faire? –

Répondre

4

L'utilisation d'un tuyau à l'intérieur d'une fonction comporte des avantages et des inconvénients. Le plus grand avantage est qu'il est plus facile de voir ce qui se passe dans une fonction lorsque vous lisez le code. Les plus grands inconvénients sont que les messages d'erreur deviennent plus difficiles à interpréter et le tuyau brise certaines des règles d'évaluation de R.

Voici un exemple. Disons que nous voulons faire une transformation inutile à l'ensemble de données mtcars. Voici comment nous pourrions le faire avec des tuyaux ...

library(tidyverse) 
tidy_function <- function() { 
    mtcars %>% 
    group_by(cyl) %>% 
    summarise(disp = sum(disp)) %>% 
    mutate(disp = (disp^4)/10000000000) 
} 

Vous pouvez voir clairement ce qui se passe à chaque étape, même si elle ne fait rien utile. Maintenant, regardons le code temporel en utilisant l'approche sandwich Dagwood ...

base_function <- function() { 
    mutate(summarise(group_by(mtcars, cyl), disp = sum(disp)), disp = (disp^5)/10000000000) 
} 

beaucoup plus difficile à lire, même si elle nous donne le même résultat ...

all.equal(tidy_function(), base_function()) 
# [1] TRUE 

La façon la plus courante de éviter d'utiliser soit un tuyau ou un sandwich Dagwood est d'enregistrer les résultats de chaque étape à une variable intermédiaire ...

intermediate_function <- function() { 
    x <- mtcars 
    x <- group_by(x, cyl) 
    x <- summarise(x, disp = sum(disp)) 
    mutate(x, disp = (disp^5)/10000000000) 
} 

plus lisible que la dernière fonction et R vous donnera un peu plus détaillée informations quand il y a une erreur. De plus, il obéit aux règles traditionnelles de l'évaluation. Encore une fois, il donne les mêmes résultats que les deux autres fonctions ...

all.equal(tidy_function(), intermediate_function()) 
# [1] TRUE 

Vous avez demandé spécifiquement de la vitesse, donc Comparons ces trois fonctions en exécutant chacun 1000 fois ...

library(microbenchmark) 
timing <- 
    microbenchmark(tidy_function(), 
       intermediate_function(), 
       base_function(), 
       times = 1000L) 
timing 
#Unit: milliseconds 
        #expr  min  lq  mean median  uq  max neval cld 
     #tidy_function() 3.809009 4.403243 5.531429 4.800918 5.860111 23.37589 1000 a 
#intermediate_function() 3.560666 4.106216 5.154006 4.519938 5.538834 21.43292 1000 a 
     #base_function() 3.610992 4.136850 5.519869 4.583573 5.696737 203.66175 1000 a 

Même dans cet exemple trivial, le tuyau est un peu plus lent que les deux autres options.

Conclusion

Ne hésitez pas à utiliser le tuyau dans vos fonctions si elle est le moyen le plus confortable pour vous d'écrire du code. Si vous commencez à rencontrer des problèmes ou si vous avez besoin que votre code soit le plus rapide possible, passez à un autre paradigme.

+2

Votre sandwich Dagwood a juste besoin de lignes et d'indentations et il est très lisible. – Roland

+1

Est-ce que quelqu'un connaît des paquets où l'opérateur de tuyau est utilisé? Je ne l'ai pas vu utilisé sauf dans des exemples de script. – user2506086

+0

Pour moi, il semble que la tuyauterie est plus proche de la façon dont vous écrivez les instructions pour faire quelque chose, donc je voudrais l'utiliser dans les cas où je veux que mon code soit très lisible. D'un autre côté, j'ai la difficulté de déboguer. Si vous essayez de déboguer dans un tube, vous devez vous frayer un chemin à travers la fonction '%>%', et déterminer dans quelle ligne entrer.On dirait que si j'écris un paquet pour d'autres personnes à utiliser, si j'utilise le tuyau va être un équilibre entre la façon dont je veux qu'il soit naturel de lire le code, et comment je veux qu'il soit facile de déboguer le code. – user2506086