3
votes

R - Temps d'exécution par ligne de code dans dplyr

Lorsque je souhaite estimer la durée d'exécution d'un code R, j'utilise la fonction system.time().

library(dplyr)

system.time({
    Titanic %>%
        as.data.frame() %>%
        mutate(Dataset = 1) %>%
        bind_rows(as.data.frame(Titanic)) %>%
        mutate_all(funs(replace_na(., NA))) %>% 
        filter(Dataset != 1)
})

# utilisateur     système      écoulé 
#        0.02        0.00        0.02

Question: Existe-t-il un moyen de connaître le temps d'exécution de chaque opération, les opérations entre chaque tube (le mutate , puis le bind_rows , puis le filtre , etc.) sans exécuter chacun par un ou sans écrire plusieurs system.time () ?

Dans cet exemple ce n'est pas utile, mais parfois j'ai reçu un long script, avec longue durée, et j'aimerais identifier les opérations les plus faibles.

J'ai fait quelques recherches mais je n'ai pas trouvé quelque chose d'utile.


3 commentaires

Éventuellement lié: stackoverflow.com/ questions / 30119628 /…


J'aime la bibliothèque tictoc pour cela. Ajoutez un tictoc: tic ("Step 1") pour démarrer une horloge et tictoc :: toc () pour la terminer. Ou si vous voulez être plus chic, rstudio.github.io/profvis


En savoir plus sur le profilage: support.rstudio.com/hc / fr-fr / articles /…


3 Réponses :


4
votes

Vous pouvez utiliser le package profvis:

library(tidyverse)    
library(profvis)

profvis({
  Titanic %>%
    as.data.frame() %>%
    mutate(Dataset = 1) %>%
    bind_rows(as.data.frame(Titanic)) %>%
    mutate_all(funs(replace_na(., NA))) %>% 
    filter(Dataset != 1)
})

entrez la description de l'image ici


1 commentaires

peut-être ai-je manqué quelque chose, mais je ne suis pas sûr que la fonction profvis réponde exactement à mon besoin, elle ne m'a pas donné le temps d'exécution par ligne de pipe-code. L'utilisation de % L>% semble être plus appropriée.



4
votes

Vous pourriez être intéressé par le tube % L>% de mon package tubes :

# devtools::install_github("moodymudskipper/pipes")
library(pipes)
Titanic %L>%
  as.data.frame() %L>%
  mutate(Dataset = 1) %L>%
  bind_rows(as.data.frame(Titanic)) %L>%
  mutate_all(list(~replace_na(., NA))) %L>% 
  filter(Dataset != 1)

# as.data.frame(.)   ~  0.03 sec
# mutate(., Dataset = 1)   ~  0 sec
# bind_rows(., as.data.frame(Titanic))   ~  0 sec
# mutate_all(., list(~replace_na(., NA)))   ~  0 sec
# filter(., Dataset != 1)   ~  0.03 sec
# [1] Class    Sex      Age      Survived Freq     Dataset 
# <0 rows> (or 0-length row.names)


2 commentaires

Impressionnant ! Une question à propos de % L>% : augmente-t-il la durée de fonctionnement du code (en calculant les différents temps et en imprimant le résultat) ou pas tellement? Disons que j'ai un long code de tuyauterie, que j'exécute plusieurs fois. Je peux utiliser % L>% une fois pour voir quelle partie de ce code est chère, puis supprimer le % L>% , ou je peux le conserver et l'exécuter à chaque fois, cela n'aura pas un tel impact?


Vous pouvez imprimer % L>% (entouré de backticks) et vous verrez quel code supplémentaire est utilisé, il s'agit d'une manipulation de chaîne de base et d'un appel à system.time , il ne devrait donc pas avoir d'impact significatif, et certainement pas à côté d'un appel coûteux.



2
votes

Voici une option qui a fonctionné pour moi (modifier votre remplacement NA puisque funs est déconseillé en logiciel) ... certes, c'est assez long:

library(dplyr)
library(magrittr)
library(tictoc)

Titanic %T>%
  {tic("as.data.frame")} %>%
  as.data.frame() %T>%
  {toc(); tic("mutate")} %>%
  mutate(Dataset = 1) %T>%
  {toc(); tic("bind.rows")} %>%
  bind_rows(as.data.frame(Titanic)) %T>%
  {toc(); tic("replace.na")} %>%
  replace(is.na(.), 0) %T>% 
  {toc(); tic("filter")} %>%
  filter(Dataset != 1) %T>%
  {toc(); tic("head")} %>%
  head() %T>%
  {toc()}

as.data.frame: 0 sec elapsed
mutate: 0 sec elapsed
bind.rows: 0 sec elapsed
replace.na: 0 sec elapsed
filter: 0 sec elapsed
head: 0 sec elapsed
  Class    Sex   Age Survived Freq Dataset
1   1st   Male Child       No    0       0
2   2nd   Male Child       No    0       0
3   3rd   Male Child       No   35       0
4  Crew   Male Child       No    0       0
5   1st Female Child       No    0       0
6   2nd Female Child       No    0       0


0 commentaires