IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SAS Base Discussion :

Minimums sur des intersections d'intervalles


Sujet :

SAS Base

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 33
    Points : 34
    Points
    34
    Par défaut Minimums sur des intersections d'intervalles
    Bonjour,
    je ne sais pas comment traiter sous SAS le problème suivant:

    Je dispose de personnes (identifiées par leur numéro NOPE),
    qui disposent de plusieurs contrats (NOCT),
    qui possèdent plusieurs garanties (NOGA),
    qui ont chacunes différentes dates de couverture(date de début=DDCA, date de fin =DDFA). A chaque date de couverture, correspond une franchise en jours (FR).

    Je souhaite déterminer par numéro personne NOPE, et par période de couverture, la plus petite franchise qui s'applique à l'assuré NOPE (quels que soient les contrats NOCT, et les numéros de garantie NOGA).

    C'est à dire, à partir de:

    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
    18
    19
    20
    Data entree ;
    format DDCA DFCA ddmmyy10.;
    NOPE='0001';NOCT='CT0001';NOGA='GAR001' ;
    DDCA='01JAN1999'd ;DFCA='08FEB1999'd ;FR=14 ;output;
    DDCA='08FEB1999'd ;DFCA='03JAN2000'd ;FR=7 ;output;
     
    NOPE='0001';NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN1999'd ;DFCA='06FEB1999'd ;FR=5 ;output;
    DDCA='06FEB1999'd ;DFCA='31JAN2000'd ;FR=16 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR003' ;
    DDCA='01JAN2000'd ;DFCA='08FEB2000'd ;FR=113 ;output;
    DDCA='08FEB2000'd ;DFCA='03JAN2001'd ;FR=118 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR004' ;
    NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN2000'd ;DFCA='06FEB2000'd ;FR=114 ;output;
    DDCA='06FEB2000'd ;DFCA='31JAN2001'd ;FR=117 ;output;
     
    run;
    obtenir:
    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
    Data sortie ;
    format DDCA DFCA ddmmyy10.;
    NOPE='0001';
    DDCA='01JAN1999'd ;DFCA='02JAN1999'd ;FR=14 ;output;
    DDCA='03JAN1999'd ;DFCA='05FEB1999'd ;FR=5 ;output;
    DDCA='06FEB1999'd ;DFCA='07FEB1999'd ;FR=16 ;output;
    DDCA='08FEB1999'd ;DFCA='03JAN2000'd ;FR=7 ;output;
     
    NOPE='0002';
    DDCA='01JAN2000'd ;DFCA='02JAN2000'd ;FR=113 ;output;
    DDCA='03JAN2000'd ;DFCA='05FEB2000'd ;FR=114 ;output;
    DDCA='06FEB2000'd ;DFCA='07FEB2000'd ;FR=117 ;output;
    DDCA='08FEB2000'd ;DFCA='03JAN2001'd ;FR=118 ;output;
     
    run;
    Merci pour votre aide.

    PS:
    1.Cette transformation revient à prendre par NOPE le minimum des dates de début DDCA (appelons le Min1_debut), puis à choisir comme fin de cette période le Min(Min_des_dates_de_debut_differentes_Min1_debut -1,Date_de_fin_DDFA_de_la_ligne_de_Min1_debut),et affecter à cette lignée crée la franchise de Min1_debut.

    Ensuite on recommence à choisir un minimum des dates début parmi les dates début différentes de Min1_debut.

    Cependant une telle ligne ne peut être éliminée de la sélection dans le cas où sa date de fin est postérieure à toutes les autres par exemple.


    2.cette transformation permet ensuite de base pour un calcul d'exposition, ie permet de connaitre par année quelle est la répartition en pourcentage des différents types de franchise.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Bonsoir

    Je ne sais pas si tu t'es mal expliqué ou bien si tu as mal choisi tes exemples ou encore si je n'ai rien compris , mais je n'obtiens pas tout à fait ce que tu souhaite.

    J'ai fait un code pour identifier les périodes de jour consécutifs de même franchise minimale, où la franchise minimale d'un jour donné est la plus petite franchise des garanties valides ce jour là (les intervalles de période de garantie étant fermés jour_debut_garantie<=jour_de_garantie_valide<=jour_de_fin_garantie )


    J'ai rajouté un contrat à ton premier individu pour traiter le cas des périodes non chevauchantes

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    DATA entree ;
    format DDCA DFCA ddmmyy10.;
    NOPE='0001';NOCT='CT0001';NOGA='GAR001' ;
    DDCA='01JAN1999'd ;DFCA='08FEB1999'd ;FR=14 ;output;
    DDCA='08FEB1999'd ;DFCA='03JAN2000'd ;FR=7 ;output;
     
    NOPE='0001';NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN1999'd ;DFCA='06FEB1999'd ;FR=5 ;output;
    DDCA='06FEB1999'd ;DFCA='31JAN2000'd ;FR=16 ;output;
     
    NOPE='0001';NOCT='CT0002';NOGA='GAR003' ;
    DDCA='03JAN2010'd ;DFCA='06FEB2011'd ;FR=17 ;output;
    DDCA='06FEB2010'd ;DFCA='31JAN2011'd ;FR=5 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR003' ;
    DDCA='01JAN2000'd ;DFCA='08FEB2000'd ;FR=113 ;output;
    DDCA='08FEB2000'd ;DFCA='03JAN2001'd ;FR=118 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR004' ;
    NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN2000'd ;DFCA='06FEB2000'd ;FR=114 ;output;
    DDCA='06FEB2000'd ;DFCA='31JAN2001'd ;FR=117 ;output;
     
    run;
     
    PROC SORT DATA=entree; BY nope;
    DATA entree; SET entree END=EOF; 
    RETAIN numero 0 nbMaxGarantie 0;
    LENGTH var $8. ;
    BY nope;
    IF first.nope THEN numero=1;ELSE numero=numero+1;
    var="FR"!!STRIP(numero);valeur=FR;OUTPUT;
    var="DDCA"!!STRIP(numero);valeur=DDCA;OUTPUT;
    var="DFCA"!!STRIP(numero);valeur=DFCA;OUTPUT;
    KEEP NOPE var valeur;
    IF last.nope THEN nbMaxGarantie=Max(nbMaxGarantie,numero);
    IF EOF THEN CALL SYMPUT('nbMaxGarantie',strip(nbMaxGarantie));
    run;
     
     
    proc transpose data=entree out=transposee(drop=_name_);
    var valeur;
    id var;
    by nope;
    run;
    options mprint;
     
    DATA calcul; SET transposee;
     
    ARRAY Debut {&nbMaxGarantie} DDCA1-DDCA&nbMaxGarantie ;
    ARRAY Fin {&nbMaxGarantie} DFCA1-DFCA&nbMaxGarantie ;
    ARRAY FRC {&nbMaxGarantie} FR1-FR&nbMaxGarantie ;
    dateMin=MIN (OF DDCA1-DDCA&nbMaxGarantie) ; /** Date inférieure des périodes de NOPE */
    dateMax=MAX (OF DFCA1-DFCA&nbMaxGarantie) ; /** Date supérieure des périodes de NOPE */
    frMax=MAX (OF FR1-FR&nbMaxGarantie); /* Franchise maximale de NOPE */
    dateCourante=dateMin; /** On initialise à la plus petite date **/
     
    DO UNTIL (dateCourante>dateMax);
     
    frMin=frMax+1; /* on intialise la franchise minimale à une valeur maximale */
     
    maxDate=DateCourante-1; /* maxDate : fin de l interval correspondant
    à la période de franchise minimale correspondant à la date courante
    initialisée à DateCourante-1 */
     
    numero=0; /** numéro de la ligne de garantie correspondant à la franchise minimale
    intialisée à 0 **/
     
     
    /** recherche du niveau de la franchise minimale */
    			DO I=1 TO &nbMaxGarantie; /* on explore toutes les garanties */
     
    /** Test : Une garantie pour une date courante est préférée 
    à une autre lorsque sa franchise est inférieure ou égale 
    à la franchise de la référence (frMin) et que la garantie est valide
    ce jour là  soit Debut(garantie)>=dateCourante>=Fin(garantie)
    et que sa durée de validité est plus longue soit maxDate<=Fin(garantie) **/
     
     
    			IF FRC{i}<=frMin 
    				AND dateCourante>=Debut{i}  
    				AND dateCourante<=Fin{i}
    				AND (FRC{i}<frMin or maxDate<=Fin{i})
       /** Dans ce cas la nouvelle franchise minimale est égale
    		à la franchise de la garantie et s étend jusqu a la fin de la garantie */
    					THEN 	DO;	FRmin=FRC{i};
    								maxDate=Fin{i};
    								numero=i;
     
    							END;
    		END;
    /** Fin de la recherche du niveau de la franchise minimale **/
     
    /** Recherche de la période de validité de la franchise minimale
    		précédement calculée **/
     
    DO K=1 TO &nbMaxGarantie; /* on explore toutes les garanties */
    /* Test : la garantie retenue est minimale jusqu à ce qu une autre
    garantie valide sur la période considérée soit valide et
    de franchise inférieure :
    elle doit donc être différente de la garantie retenue 
    et donc numero^=k
    elle doit commencer après la garantie actuellement retenue
    donc Debut de la garantie > date courante
    mais inférieure ou égale à la fin de la période actuelle
    et doit avoir un niveau de franchise inférieure */
     
    IF numero^=K 
    AND Debut{k}<=maxDate
    AND Debut{k}>dateCourante
    AND FRC{k}<FRmin
    THEN maxDate=Debut{k}-1; /** dans ce cas la période de garantie minimale
    s arrête le jour précédant le début de cette période identifiée */
    END;
     
    DDCA=dateCourante;
    DFCA=maxDate;
    FR=FRmin;
    OUTPUT; /** la détermination de la période est terminée
    on écrit la date de début, celle de fin et le nombre minimal de jour
    de franchise correspondant + identifiant d individu */
     
     
    /** on cherche ensuite la date de début de la période suivante
    de franchise minimale **/
     
    dateCourante=maxDate+1; /** elle commence forcément après
    la période de validité de la période précédente -> intialisation
    à maxDate+1 */
    dateCouranteMin=dateMax+1;/** elle est forcément inférieur
    à la plus grande date + 1 --> intialisation */
     
    		DO I=1 TO &nbMaxGarantie; /** on explore toutes les garanties */
     
    /* si une garantie est valide ce jour là alors dateCourante est bien
    		le début valide d une période */
    			IF 	Debut{i}<=dateCourante AND Fin{i}>=dateCourante
    						THEN 	DO;dateCouranteMin=dateCourante;
    								I=&nbMaxGarantie+1;
    								END;
    /* sinon la plus petite date de début de garantie et supérieur à la date courante fait l affaire (cas des périodes non chevauchantes )*/
    						ELSE IF 	Debut{i}<=dateCouranteMin
    								 	AND Debut{i}>DateCourante
    									THEN dateCouranteMin=Debut{i};
    		END;
    dateCourante=dateCouranteMin;
    END; 
    format DDCA DFCA ddmmyy10.;
    KEEP NOPE DDCA DFCA FR;
    RUN;
     
     
    PROC PRINT DATA=CALCUL;RUN;
    et le résultat qui semble différent du résultat que tu semblais attendre, d'ou mon interrogation introductive

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
                               Obs    NOPE          DDCA          DFCA     FR
     
                                  1    0001    01/01/1999    02/01/1999     14
                                  2    0001    03/01/1999    06/02/1999      5
                                  3    0001    07/02/1999    07/02/1999     14
                                  4    0001    08/02/1999    03/01/2000      7
                                  5    0001    04/01/2000    31/01/2000     16
                                  6    0001    03/01/2010    05/02/2010     17
                                  7    0001    06/02/2010    31/01/2011      5
                                  8    0001    01/02/2011    06/02/2011     17
                                  9    0002    01/01/2000    08/02/2000    113
                                 10    0002    09/02/2000    31/01/2001    117
    Enfin si c'est ce que tu cherchais, tu peux peut être le faire en une seule étape data mais je pense que ce sera assez indigeste (d'ailleurs je n'ai même pas essayé de m'y aventurer et donc je n'ai pas essayé de réfléchir si c'est même possible...).
    Mon codage n'est sans doute pas optimal mais j'ai trouvé qu'il était beaucoup plus naturel de travailler en transposant et en lplaçant toutes les périodes en variables d'abord plutôt que de laisser les périodes d'un même individus sur des observations distinctes.
    Si ça peut t'inspirer...

  3. #3
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Je ne comprends toujours pas d'où provient DFCA='02JAN1999'd en sortie ...
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  4. #4
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Salut Datametric,

    pour l'individu 1 on a de défini

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    NOPE='0001';NOCT='CT0001';NOGA='GAR001' ;
    DDCA='01JAN1999'd ;DFCA='08FEB1999'd ;FR=14 ;output;
    DDCA='08FEB1999'd ;DFCA='03JAN2000'd ;FR=7 ;output;
     
    NOPE='0001';NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN1999'd ;DFCA='06FEB1999'd ;FR=5 ;output;
    DDCA='06FEB1999'd ;DFCA='31JAN2000'd ;FR=16 ;output;
     
    NOPE='0001';NOCT='CT0002';NOGA='GAR003' ;
    DDCA='03JAN2010'd ;DFCA='06FEB2011'd ;FR=17 ;output;
    DDCA='06FEB2010'd ;DFCA='31JAN2011'd ;FR=5 ;output;
    donc a priori si j'ai bien compris

    Le 1er janvier une seule garantie est valide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    NOCT='CT0001';NOGA='GAR001' ;
    DDCA='01JAN1999'd ;DFCA='08FEB1999'd ;FR=14 ;output;
    Le 2 janvier également, ce contrat est le seul valide.
    Le 3 janvier, un deuxième contrat débute, il y a donc 2 contrat valides ce jour là
    toujours le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    NOCT='CT0001';NOGA='GAR001' ;
    DDCA='01JAN1999'd ;DFCA='08FEB1999'd ;FR=14 ;output;
    mais également le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    NOPE='0001';NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN1999'd ;DFCA='06FEB1999'd ;FR=5 ;output;
    Donc le 3 janvier, la franchise minimale n'est plus de 14 jours mais de 5 jours.

    Donc on a bien une première période du 1er janvier au 2 janvier où la franchise est de 14 jours qui passe ensuite à 5 jours.

    Enfin c'est ce que j'ai compris de ce qui était attendu.

  5. #5
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut

    Merci grand chef.

    Le 3 janvier, un deuxième contrat débute, il y a donc 2 contrat valides ce jour là
    Plutôt une nouvelle garantie GAR002 ?
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  6. #6
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    oui oui plutôt une garantie, pas claire cette histoire !

    Par contre si il y a certains individus avec beaucoup de contrats/garanties pour des raisons d'optimisation faudra penser a prévoir une interruption de la boucle d'exploration des garanties/contrats pour éviter de vérifier du vide...

  7. #7
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Alors je dis ça :

    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
    18
    19
    20
    21
    22
    23
    24
     
    proc sql;
    create table entree2 as 
    select nope, fr, min(ddca) as ddca format=date9. , min(dfca) as olddfca format=date9.
    from entree
    group by nope, fr
    order by 1,3 desc
    ;
    quit;
     
    data entree3;
    set entree2;
    by nope;
    dddca = abs(dif(ddca))-1; /*calcul du délai*/
    if first.nope then dddca=.; /*pour que nope=2 ne prenne la date du nope=1*/
    dfca=ddca+dddca; /* calcul de la borne max*/
    if dddca=. then dfca=olddfca; /*quand on est à la fin on prend la borne max donnée*/
    format dfca date9. ;
    drop dddca olddfca;
    run;
     
    proc sort ;
    by nope ddca ;
    run;
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  8. #8
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Ah bah c'est rassurant ! on ne trouve pas la même chose !

    (Par contre tu trouve bien le résultat attendu mais pas celui décrit littéralement ... (enfin tel que je l'ai compris !!!)
    J'y comprend de moins de moins quelque chose dans cette affaire... :-O)

    @Stéphane : Tu as compris ce qui était recherché alors ?

  9. #9
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    @Stéphane : Tu as compris ce qui était recherché alors ?
    Compris ...
    C'est ton explication sur le 2 janvier qui a tout éclairci .
    D'où l'intérêt d'avoir une table d'arrivée pour voir le résultat attendu
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  10. #10
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Bon j'espère que notre ami labuche passera un peu de temps à nous expliquer ça plus clairement pour nous simples mortels (en tout pour cas moi ^^ ) !

    Je ne capte pas pourquoi vraiment on cherche à avoir

    DDCA='03JAN1999'd ;DFCA='05FEB1999'd ;FR=5 ;output;et pas

    DDCA='03JAN1999'd ;DFCA='06FEB1999'd ;FR=5 ;output;

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 33
    Points : 34
    Points
    34
    Par défaut Erratum
    Bonjour,
    datametric et jerome_pdv2, je vous remercie d'avoir consacré du temps à me répondre. Je m'excuse de n'avoir pu vous répondre plus tôt (je ne dispose pas d'ordinateur cette semaine, et je suis dans un lieu ou je capte mal).

    Je me suis effectivement honteusement trompé dans *les résultats attendus. Ceux de jerome_pdv2 sont effectivement les bons! (l'explication du 02JAN1999 est également la bonne).

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 33
    Points : 34
    Points
    34
    Par défaut
    Une nouvelle fois merci pour ton aide Jérome,
    apparemment ton code fonctionne très bien sur ma base.
    (effectivement l'exécution est un peu longue j'essaierai de l'améliorer si j'y arrive).

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 33
    Points : 34
    Points
    34
    Par défaut Valeur Maximale
    Bonjour,
    je cherche maintenant à déterminer la valeur maximale et non plus la valeur minimale (utile pour un calcul de durée de couverture).

    Le code de Jérôme que j'ai modifié à cette fin ne boucle pas:

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    DATA entree ;
    format DDCA DFCA ddmmyy10.;
    NOPE='0001';NOCT='CT0001';NOGA='GAR001' ;
    DDCA='01JAN1999'd ;DFCA='08FEB1999'd ;FR=14 ;output;
    DDCA='08FEB1999'd ;DFCA='03JAN2000'd ;FR=7 ;output;
     
    NOPE='0001';NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN1999'd ;DFCA='06FEB1999'd ;FR=5 ;output;
    DDCA='06FEB1999'd ;DFCA='31JAN2000'd ;FR=16 ;output;
     
    NOPE='0001';NOCT='CT0002';NOGA='GAR003' ;
    DDCA='03JAN2010'd ;DFCA='06FEB2011'd ;FR=17 ;output;
    DDCA='06FEB2010'd ;DFCA='31JAN2011'd ;FR=5 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR003' ;
    DDCA='01JAN2000'd ;DFCA='08FEB2000'd ;FR=113 ;output;
    DDCA='08FEB2000'd ;DFCA='03JAN2001'd ;FR=118 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR004' ;
    NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN2000'd ;DFCA='06FEB2000'd ;FR=114 ;output;
    DDCA='06FEB2000'd ;DFCA='31JAN2001'd ;FR=117 ;output;
     
    run;
    PROC SORT DATA=entree; BY nope;
    DATA entree; SET entree END=EOF; 
    RETAIN numero 0 nbMaxGarantie 0;
    LENGTH var $8. ;
    BY nope;
    IF first.nope THEN numero=1;ELSE numero=numero+1;
    var="FR"!!STRIP(numero);valeur=FR;OUTPUT;
    var="DDCA"!!STRIP(numero);valeur=DDCA;OUTPUT;
    var="DFCA"!!STRIP(numero);valeur=DFCA;OUTPUT;
    KEEP NOPE var valeur;
    IF last.nope THEN nbMaxGarantie=Max(nbMaxGarantie,numero);
    IF EOF THEN CALL SYMPUT('nbMaxGarantie',strip(nbMaxGarantie));
    run;
    proc transpose DATA=entree out=transposee(DROP=_name_);
    var valeur;
    id var;
    BY nope;
    run;
    options mprint;
     
    DATA calcul; SET transposee;
     
    ARRAY Debut {&nbMaxGarantie} DDCA1-DDCA&nbMaxGarantie ;
    ARRAY Fin {&nbMaxGarantie} DFCA1-DFCA&nbMaxGarantie ;
    ARRAY FRC {&nbMaxGarantie} FR1-FR&nbMaxGarantie ;
    dateMin=MIN (OF DDCA1-DDCA&nbMaxGarantie) ; /** Date inférieure des périodes de NOPE */
    dateMax=MAX (OF DFCA1-DFCA&nbMaxGarantie) ; /** Date supérieure des périodes de NOPE */
    frMin=Min (OF FR1-FR&nbMaxGarantie); /* Franchise minimale de NOPE */
    dateCourante=dateMin; /** On initialise à la plus petite date **/
     
    DO UNTIL (dateCourante>dateMax);
     
    frMax=frMin+1; /* on initialise la franchise maximale à une valeur minimale */
     
    maxDate=DateCourante-1; /* maxDate : fin de l'interval correspondant
    à la période de franchise maximale correspondant à la date courante
    initialisée à DateCourante-1 */
     
    numero=0; /** numéro de la ligne de garantie correspondant à la franchise maximale
    intialisée à 0 **/
     
     
    /** recherche du niveau de la franchise maximale */
    			DO I=1 TO &nbMaxGarantie; /* on explore toutes les garanties */
     
    /** Test : Une garantie pour une date courante est préférée 
    à une autre lorsque sa franchise est supérieure ou égale 
    à la franchise de la référence (frMinax) et que la garantie est valide
    ce jour là  soit Debut(garantie)>=dateCourante>=Fin(garantie)
    et que sa durée de validité est plus longue soit maxDate<=Fin(garantie) **/
     
     
    			IF FRC{i}>=frMax 
    				AND dateCourante>=Debut{i}  
    				AND dateCourante<=Fin{i}
    				AND (FRC{i}>frMax OR maxDate<=Fin{i})
       /** Dans ce cas la nouvelle franchise maximale est égale
    		à la franchise de la garantie et s'étend jusqu a la fin de la garantie */
    					THEN 	DO;	FRmax=FRC{i};
    								maxDate=Fin{i};
    								numero=i;
     
    							END;
    		END;
    /** Fin de la recherche du niveau de la franchise minimale **/
     
    /** Recherche de la période de validité de la franchise maximale
    		précédement calculée **/
     
    DO K=1 TO &nbMaxGarantie; /* on explore toutes les garanties */
    /* Test : la garantie retenue est maximale jusqu'à ce qu'une autre
    garantie valide sur la période considérée soit valide et
    de franchise supérieure :
    elle doit donc être différente de la garantie retenue 
    et donc numero^=k
    elle doit commencer après la garantie actuellement retenue
    donc Debut de la garantie > date courante
    mais inférieure ou égale à la fin de la période actuelle
    et doit avoir un niveau de franchise supérieure */
     
    IF numero^=K 
    AND Debut{k}<=maxDate
    AND Debut{k}>dateCourante
    AND FRC{k}>FRmax
    THEN maxDate=Debut{k}-1; /** dans ce cas la période de garantie maximale
    s'arrête le jour précédant le début de cette période identifiée */
    END;
     
    DDCA=dateCourante;
    DFCA=maxDate;
    FR=FRmax;
    OUTPUT; /** la détermination de la période est terminée
    on écrit la date de début, celle de fin et le nombre minimal de jour
    de franchise correspondant + identifiant d individu */
     
     
    /** on cherche ensuite la date de début de la période suivante
    de franchise maximale **/
     
    dateCourante=maxDate+1; /** elle commence forcément après
    la période de validité de la période précédente -> intialisation
    à maxDate+1 */
    dateCouranteMin=dateMax+1;/** elle est forcément inférieur
    à la plus grande date + 1 --> intialisation */
     
    		DO I=1 TO &nbMaxGarantie; /** on explore toutes les garanties */
     
    /* si une garantie est valide ce jour là alors dateCourante est bien
    		le début valide d une période */
    			IF 	Debut{i}<=dateCourante AND Fin{i}>=dateCourante
    						THEN 	DO;dateCouranteMin=dateCourante;
    								I=&nbMaxGarantie+1;
    								END;
    /* sinon la plus petite date de début de garantie et supérieur à la date courante fait l affaire (cas des périodes non chevauchantes )*/
    						ELSE IF 	Debut{i}<=dateCouranteMin
    								 	AND Debut{i}>DateCourante
    									THEN dateCouranteMin=Debut{i};
    		END;
    dateCourante=dateCouranteMin;
    END; 
    format DDCA DFCA ddmmyy10.;
    KEEP NOPE DDCA DFCA FR;
    RUN;
     
     
    PROC PRINT DATA=CALCUL;RUN;
    Merci de m'indiquer mon erreur si vous la voyez.

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 33
    Points : 34
    Points
    34
    Par défaut
    Bon apparemment en plus des modification postées dans le code précédent, il faut remplacer ligne 57 par :
    ...

    ce qui donne

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    DATA entree ;
    format DDCA DFCA ddmmyy10.;
    NOPE='0001';NOCT='CT0001';NOGA='GAR001' ;
    DDCA='01JAN1999'd ;DFCA='08FEB1999'd ;FR=14 ;output;
    DDCA='08FEB1999'd ;DFCA='03JAN2000'd ;FR=7 ;output;
     
    NOPE='0001';NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN1999'd ;DFCA='06FEB1999'd ;FR=5 ;output;
    DDCA='06FEB1999'd ;DFCA='31JAN2000'd ;FR=16 ;output;
     
    NOPE='0001';NOCT='CT0002';NOGA='GAR003' ;
    DDCA='03JAN2010'd ;DFCA='06FEB2011'd ;FR=17 ;output;
    DDCA='06FEB2010'd ;DFCA='31JAN2011'd ;FR=5 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR003' ;
    DDCA='01JAN2000'd ;DFCA='08FEB2000'd ;FR=113 ;output;
    DDCA='08FEB2000'd ;DFCA='03JAN2001'd ;FR=118 ;output;
     
    NOPE='0002';NOCT='CT0001';NOGA='GAR004' ;
    NOCT='CT0001';NOGA='GAR002' ;
    DDCA='03JAN2000'd ;DFCA='06FEB2000'd ;FR=114 ;output;
    DDCA='06FEB2000'd ;DFCA='31JAN2001'd ;FR=117 ;output;
     
    run;
    PROC SORT DATA=entree; BY nope;
    DATA entree; SET entree END=EOF; 
    RETAIN numero 0 nbMaxGarantie 0;
    LENGTH var $8. ;
    BY nope;
    IF first.nope THEN numero=1;ELSE numero=numero+1;
    var="FR"!!STRIP(numero);valeur=FR;OUTPUT;
    var="DDCA"!!STRIP(numero);valeur=DDCA;OUTPUT;
    var="DFCA"!!STRIP(numero);valeur=DFCA;OUTPUT;
    KEEP NOPE var valeur;
    IF last.nope THEN nbMaxGarantie=Max(nbMaxGarantie,numero);
    IF EOF THEN CALL SYMPUT('nbMaxGarantie',strip(nbMaxGarantie));
    run;
    proc transpose DATA=entree out=transposee(DROP=_name_);
    var valeur;
    id var;
    BY nope;
    run;
    options mprint;
     
    DATA calcul; SET transposee;
     
    ARRAY Debut {&nbMaxGarantie} DDCA1-DDCA&nbMaxGarantie ;
    ARRAY Fin {&nbMaxGarantie} DFCA1-DFCA&nbMaxGarantie ;
    ARRAY FRC {&nbMaxGarantie} FR1-FR&nbMaxGarantie ;
    dateMin=MIN (OF DDCA1-DDCA&nbMaxGarantie) ; /** Date inférieure des périodes de NOPE */
    dateMax=MAX (OF DFCA1-DFCA&nbMaxGarantie) ; /** Date supérieure des périodes de NOPE */
    frMin=Min (OF FR1-FR&nbMaxGarantie); /* Franchise minimale de NOPE */
    dateCourante=dateMin; /** On initialise à la plus petite date **/
     
    DO UNTIL (dateCourante>dateMax);
     
    frMax=frMin-1; /* on initialise la franchise maximale à une valeur minimale */
     
    maxDate=DateCourante-1; /* maxDate : fin de l'interval correspondant
    à la période de franchise maximale correspondant à la date courante
    initialisée à DateCourante-1 */
     
    numero=0; /** numéro de la ligne de garantie correspondant à la franchise maximale
    intialisée à 0 **/
     
     
    /** recherche du niveau de la franchise maximale */
    			DO I=1 TO &nbMaxGarantie; /* on explore toutes les garanties */
     
    /** Test : Une garantie pour une date courante est préférée 
    à une autre lorsque sa franchise est supérieure ou égale 
    à la franchise de la référence (frMinax) et que la garantie est valide
    ce jour là  soit Debut(garantie)>=dateCourante>=Fin(garantie)
    et que sa durée de validité est plus longue soit maxDate<=Fin(garantie) **/
     
     
    			IF FRC{i}>=frMax 
    				AND dateCourante>=Debut{i}  
    				AND dateCourante<=Fin{i}
    				AND (FRC{i}>frMax OR maxDate<=Fin{i})
       /** Dans ce cas la nouvelle franchise maximale est égale
    		à la franchise de la garantie et s'étend jusqu a la fin de la garantie */
    					THEN 	DO;	FRmax=FRC{i};
    								maxDate=Fin{i};
    								numero=i;
     
    							END;
    		END;
    /** Fin de la recherche du niveau de la franchise maximale **/
     
    /** Recherche de la période de validité de la franchise maximale
    		précédemment calculée **/
     
    DO K=1 TO &nbMaxGarantie; /* on explore toutes les garanties */
    /* Test : la garantie retenue est maximale jusqu'à ce qu'une autre
    garantie valide sur la période considérée soit valide et
    de franchise supérieure :
    elle doit donc être différente de la garantie retenue 
    et donc numero^=k
    elle doit commencer après la garantie actuellement retenue
    donc Debut de la garantie > date courante
    mais inférieure ou égale à la fin de la période actuelle
    et doit avoir un niveau de franchise supérieure */
     
    IF numero^=K 
    AND Debut{k}<=maxDate
    AND Debut{k}>dateCourante
    AND FRC{k}>FRmax
    THEN maxDate=Debut{k}-1; /** dans ce cas la période de garantie maximale
    s'arrête le jour précédant le début de cette période identifiée */
    END;
     
    DDCA=dateCourante;
    DFCA=maxDate;
    FR=FRmax;
    OUTPUT; /** la détermination de la période est terminée
    on écrit la date de début, celle de fin et le nombre minimal de jour
    de franchise correspondant + identifiant d individu */
     
     
    /** on cherche ensuite la date de début de la période suivante
    de franchise maximale **/
     
    dateCourante=maxDate+1; /** elle commence forcément après
    la période de validité de la période précédente -> intialisation
    à maxDate+1 */
    dateCouranteMin=dateMax+1;/** elle est forcément inférieur
    à la plus grande date + 1 --> intialisation */
     
    		DO I=1 TO &nbMaxGarantie; /** on explore toutes les garanties */
     
    /* si une garantie est valide ce jour là alors dateCourante est bien
    		le début valide d une période */
    			IF 	Debut{i}<=dateCourante AND Fin{i}>=dateCourante
    						THEN 	DO;dateCouranteMin=dateCourante;
    								I=&nbMaxGarantie+1;
    								END;
    /* sinon la plus petite date de début de garantie et supérieur à la date courante fait l affaire (cas des périodes non chevauchantes )*/
    						ELSE IF 	Debut{i}<=dateCouranteMin
    								 	AND Debut{i}>DateCourante
    									THEN dateCouranteMin=Debut{i};
    		END;
    dateCourante=dateCouranteMin;
    END; 
    format DDCA DFCA ddmmyy10.;
    KEEP NOPE DDCA DFCA FR;
    RUN;
     
     
    PROC PRINT DATA=CALCUL;RUN;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème sur des intervalles
    Par jamibt dans le forum C
    Réponses: 2
    Dernier message: 11/05/2011, 23h23
  2. Requêtes sur des intervalles de dates
    Par Tidus159 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 09/05/2011, 16h43
  3. Réponses: 10
    Dernier message: 02/02/2008, 11h11
  4. Réponses: 3
    Dernier message: 29/08/2007, 17h17
  5. requête basée sur des intervalles d'heures
    Par lieselotte02 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 02/06/2007, 21h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo