Application d'une fonction sur une variable d'un tibble sans perte de performance
Bonjour,
je suis passé depuis quelques temps à R, et j'ai sans doute encore un peu de mal avec les fondamentaux du langage.
J'ai une grosse table à valider, et je veux appliquer une fonction que j'ai créé par ailleurs pour vérifier certaines colonnes.
La fonction que j'utilise ici n'est qu'un exemple.
Je créé une table
Code:
1 2 3 4 5
|
library(dplyr)
random <- tibble( a=sample(1:1000,500000,replace=TRUE),
datenaissance=sample(c('20181201','20190505','20180603','20200000'),500000,replace=TRUE)
) |
Je créé ma function "complexe"
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
valide_date <- function(date_a_valider) {
dtt = as.Date(as.character(date_a_valider),format="%Y%m%d")
if (is.na(dtt)) {
result="Date incorrecte"
} else {
result="Date correcte"
}
} |
et je cherche naïvement à appliquer la fonction à une colonne du tibble.
DCT1 <- random %>% mutate(test8=valide_date(datenaissance))mais bon ce n'est pas si simple
> DCT1 <- random %>% mutate(test8=valide_date(datenaissance))
Warning message:
Problem with `mutate()` column `test8`.
ℹ `test8 = valide_date(datenaissance)`.
ℹ the condition has length > 1 and only the first element will be used
>
Bon je commence à chercher et je trouve bien deux solutions
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
# avec Vectorize()
valide_datev <- Vectorize(valide_date, vectorize.args = "date_a_valider")
start_time <- Sys.time()
DCT1 <- random %>% mutate(test8=valide_datev(datenaissance))
end_time <- Sys.time()
dif1=end_time-start_time
# avec map_chr()
start_time <- Sys.time()
DCT2 <- random %>% mutate(test8=map_chr(datenaissance,valide_date))
end_time <- Sys.time()
dif2=end_time-start_time |
Néanmoins en testant "en dehors" de ma fonction , on voit bien que ces deux solutions ne sont que des pis-aller et il doit certainement avoir une autre façon de faire.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
start_time <- Sys.time()
DCT3 <- random %>% mutate(test8=ifelse(is.na(as.Date(as.character(datenaissance),format="%Y%m%d")),"Date incorrecte","Date correcte"))
end_time <- Sys.time()
dif3=end_time-start_time
dif1 # Vectorize()
dif2 # map_chr()
dif3 # en dehors de la fonction |
>
> dif1 # Vectorize()
Time difference of 47.44273 secs
> dif2 # map_chr()
Time difference of 46.01426 secs
> dif3 # en dehors de la fonction
Time difference of 0.4939759 secs
>
Bref il y a clairement un problème de performance à appliquer la fonction comme je le fait. Mais je n'arrive pas à trouver d'autres écritures plus performantes
Si vous avez des idées.
Merci.