optimiser le temps d’exécution

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

Mokhtaria Benaouali
Messages : 15
Enregistré le : 18 Fév 2019, 12:21

optimiser le temps d’exécution

Messagepar Mokhtaria Benaouali » 20 Mai 2019, 12:51

bonjour à tous,
j'ai un problème dans le temps d’exécution dans ma boucle for
je travaille sur une longue table de longueur 87726 lignes

un exemple pour une personne

Code : Tout sélectionner

[id_personne   id_dossier      Date.sortie        Mode_sortie ...]
[1                        d1           12/12/2018           2                   ]
[1                        d2           12/08/2018           1                   ]
[1                        d3           12/03/2018           3                   ]
[2                        d1           12/08/2018            1                  ]
[2                        d1           12/03/2018           2                   ]

pour chaque personne qui ont plusieurs dossiers je devrai vérifier plusieurs conditions pour calculer le indice le nombre de dossier index(nbr_dossier_index) et le nombre h
j'avais travaillé avec une boucle for mais ça me prend beaucoup de temps
est ce que quelqu'un peux m'aide pour gérer mes condition sans utiliser la boucle ?

Code : Tout sélectionner

personne<- unique(tbl_annee_en_cour[,"id_personne"])


nbr_h=0
nbr_dossier_index=0
date_deb_annee_cour<- as.Date("01/01/2018",format="%d/%m/%Y")
date_fin_annee_cour<- as.Date("31/12/2018",format="%d/%m/%Y")
time1<-Sys.time()

for (i in 1:nrow(personne)) {
  dossier_pour_chaque_per<-tbl_annee_en_cour %>% filter(id_personne==personne$id_personne[i] )
 
 
  if(dossier_pour_chaque_per$Mode.ent.G[1]=="1" | dossier_pour_chaque_per$Mode.ent.G[1]=="2"){
    if(dossier_pour_chaque_per$Mode.sor.G[1]=="1" | dossier_pour_chaque_per$Mode.sor.G[1]=="8"  ){
     
      if(dossier_pour_chaque_per$Date.sortie.dossier[1] > date_deb_annee_cour & dossier_pour_chaque_per$Date.sortie.dossier[1] < date_fin_annee_cour){
        nbr_dossier_index=nbr_dossier_index+1
      }
    }
  }
  if(nrow(dossier_pour_chaque_per)>2){
    if(substr(dossier_pour_chaque_per$varible3[1],1,5)=="02jkl" | substr(dossier_pour_chaque_per$variable3[1],1,5)=="02jll"){
     
      if((dossier_pour_chaque_per$Date.entree.dossier[2] - dossier_pour_chaque_per$Date.sortie.dossier[1])  <= 7){
        if(substr(dossier_pour_chaque_per$variable3[2],1,5)=="02C5l" | substr(dossier_pour_chaque_per$variable3[2],1,5)=="02m2l"){
          if((dossier_pour_chaque_per$Date.entree.dossier[3] - dossier_pour_chaque_per$Date.sortie.dossier[2] ) <=7){
            nbr_h=nbr_h+1
          }
          else{
            nbr_h=nbr_h
          }
        }
        else{
          nbr_h=nbr_h+1
        }
      }
    }
    else{
     
      if((dossier_pour_chaque_per$Date.entree.dossier[2]  - dossier_pour_chaque_per$Date.sortie.dossier[1] ) <= 7){
       
        if(dossier_pour_chaque_per$Mode.ent.G[2]=="1" | dossier_pour_chaque_per$Mode.ent.G[2]=="2"){
          nbr_h=nbr_h+1
        }
      }
    }
   
  }
 
}

time2<-Sys.time()
difftime(time2, time1)


Merci
Cordialement
MimiaBenna

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

Re: optimiser le temps d’exécution

Messagepar Serge Rapenne » 20 Mai 2019, 13:33

Bonjour,

Il serait bon de fournir une jeu de données pour faire des tests (cf viewtopic.php?f=1&t=3302)

Je n'ai pas vraiment le temps d’éplucher le code pour comprendre les conditions de sélections, il serait plus efficace de décrire les conditions de calcul plutot de nous demander de comprendre ton code.

toutefois qq remarques :
1- dans les tests de date tu as mis des inégalités stricts donc si la personne a une date de sortie le 01/01 ou le 31/12, elle n'est pas compté
2- les substr(dossier_pour_chaque_per$varible3[1],1,5) vont sélectionner 5 caractères, si la variables dossier_pour_chaque_per$varible3[1] fait plus de 4 caractère, les tests sur les valeurs "02jk", "02jl" ne seront jamais vrai et si elle fait 4 caractères ou moins le substr est inutile.

Serge

Mokhtaria Benaouali
Messages : 15
Enregistré le : 18 Fév 2019, 12:21

Re: optimiser le temps d’exécution

Messagepar Mokhtaria Benaouali » 21 Mai 2019, 09:03

Bonjour ,
au début j'ai dataframe de 87726 ligne avec 66450 id_dossier et 5 colonnes (id_personne,id_dossier,variable3,Mode.entree,Mode.sortie,date.entree et Date.sortie)
pour chaque personne a plusieurs dossiers

Code : Tout sélectionner

df<-data.frame(id_dossier=c(1,1,1,2,2),id_dossier=c(11,11,12,21,22),Mode_entree=c(1,1,8,5,1),
                        date.entree=c("12/12/2018","12/12/2018","25/12/2018","12/04/2018","05/06/2018"), date.sortie=c("25/12/2018","25/12/2018","30/12/2018","30/04/2018","16/06/2018"))




première étape je voulais vérifier pour chaque personne son premier dossier entré dans l'année (dossier indexe) avec les conditions suivante:
si le mode entrée et sortie du premier dossier de cette personne== 1/8 donc si si oui passe à la 2 éme conditions que la date de sorie de dossier est comprise entre 1/1/2018 et 31/12/2018
si c'est deux conditions sont vérifié donc le compteur compte le dossier comme un dossier index(nbr_dossier_index=nbr_dossier_indexe+1)

Code : Tout sélectionner

personne<- unique(tbl_annee_en_cour[,"id_personne"])


nbr_h=0
nbr_dossier_index=0
date_deb_annee_cour<- as.Date("01/01/2018",format="%d/%m/%Y")
date_fin_annee_cour<- as.Date("31/12/2018",format="%d/%m/%Y")
time1<-Sys.time()

for (i in 1:nrow(personne)) {
  dossier_pour_chaque_per<-tbl_annee_en_cour %>% filter(id_personne==personne$id_personne[i] )
 
 
  if(dossier_pour_chaque_per$Mode.ent.G[1]=="1" | dossier_pour_chaque_per$Mode.ent.G[1]=="2"){
    if(dossier_pour_chaque_per$Mode.sor.G[1]=="1" | dossier_pour_chaque_per$Mode.sor.G[1]=="8"  ){
     
      if(dossier_pour_chaque_per$Date.sortie.dossier[1] > date_deb_annee_cour & dossier_pour_chaque_per$Date.sortie.dossier[1] < date_fin_annee_cour){
        nbr_dossier_index=nbr_dossier_index+1
      }
    }
  }
  }

Merci
MimiaBenna

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

Re: optimiser le temps d’exécution

Messagepar Mickael Canouil » 22 Mai 2019, 08:32

Bonjour,

votre jeu de donnée est visiblement erronée (deux fois la même colonne).
Pourquoi ne pas suivre le lien donné par Serge pour fournir un jeu de donnée partiel (sélection d'une dizaine de lignes) ?

De plus, votre code n'est pas du tout reproductible...
Qu'est-ce qu'un code reproductible ?
Comment insérer des données dans un message ?

Code : Tout sélectionner

df<-data.frame(id_dossier=c(1,1,1,2,2),id_dossier=c(11,11,12,21,22),Mode_entree=c(1,1,8,5,1),
                        date.entree=c("12/12/2018","12/12/2018","25/12/2018","12/04/2018","05/06/2018"), date.sortie=c("25/12/2018","25/12/2018","30/12/2018","30/04/2018","16/06/2018"))

personne<- unique(tbl_annee_en_cour[,"id_personne"])
#> Error in unique(tbl_annee_en_cour[, "id_personne"]): object 'tbl_annee_en_cour' not found


nbr_h=0
nbr_dossier_index=0
date_deb_annee_cour<- as.Date("01/01/2018",format="%d/%m/%Y")
date_fin_annee_cour<- as.Date("31/12/2018",format="%d/%m/%Y")
time1<-Sys.time()

for (i in 1:nrow(personne)) {
  dossier_pour_chaque_per<-tbl_annee_en_cour %>% filter(id_personne==personne$id_personne[i] )
 
 
  if(dossier_pour_chaque_per$Mode.ent.G[1]=="1" | dossier_pour_chaque_per$Mode.ent.G[1]=="2"){
    if(dossier_pour_chaque_per$Mode.sor.G[1]=="1" | dossier_pour_chaque_per$Mode.sor.G[1]=="8"  ){
     
      if(dossier_pour_chaque_per$Date.sortie.dossier[1] > date_deb_annee_cour & dossier_pour_chaque_per$Date.sortie.dossier[1] < date_fin_annee_cour){
        nbr_dossier_index=nbr_dossier_index+1
      }
    }
  }
  }
#> Error in nrow(personne): object 'personne' not found




Un exemple de code et donnée reproductible qui devrait quand même être proche de ce que vous souhaitez.

Code : Tout sélectionner

df <- data.frame(
  id_personne = c(1, 1, 1, 2, 2),
  id_dossier = c(11, 11, 12, 21, 22),
  Mode_entree = c(1, 1, 8, 5, 1),
  date.entree = c("12/12/2018", "12/12/2018", "25/12/2018", "12/04/2018", "05/06/2018"),
  date.sortie = c("25/12/2018", "25/12/2018", "30/12/2018", "30/04/2018", "16/06/2018")
)


library(tidyverse)

df %>%
  mutate(
    date.entree = as.Date(date.entree, format = "%d/%m/%Y"),
    date.sortie = as.Date(date.sortie, format = "%d/%m/%Y")
  ) %>%
  group_by(id_personne) %>%
  filter(Mode_entree %in% c(1, 8)) %>%
  filter(
    between(
      x = date.sortie,
      left = as.Date("01/01/2018", format = "%d/%m/%Y"),
      right = as.Date("31/12/2018", format = "%d/%m/%Y")
    )
  ) %>%
  summarise(n = n())
#> # A tibble: 2 x 2
#>   id_personne     n
#>         <dbl> <int>
#> 1           1     3
#> 2           2     1


Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité