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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.