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 :

Manipulation de ligne pour regroupement


Sujet :

SAS Base

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut Manipulation de ligne pour regroupement
    Bonjour ,

    J'aimerai regrouper des lignes pour former un groupe lorsqu'il rencontre des caractères. Je sais pas comment l'expliquer correctement mais voici l'exemple :

    Je pars d'une table comme celle ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    DATA tbl_1;
    INPUT bli $    blou$
    ;
    CARDS;
    A     1
    B     1
    A	  4
    C     5
    ;
    run;
    et j'aimerai arriver à ça :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    DATA tbl_2;
    INPUT groupe $    blix$
    ;
    CARDS;
    1     A,B,4,1
    2     C,5
    ;
    run;
    J'arrive pas à voir la logique que je dois appliquer .

    Merci d'avance ,

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 83
    Points : 137
    Points
    137
    Par défaut
    Bonjour,

    C'est pas très clair.

    Une logique possible (en tout cas ça colle avec ton exemple)
    c'est de créer un nouveau groupe lorsqu'on rencontre un nouveau bli ET un nouveau blou sur la même ligne.

    c'est bien ça que tu veux faire?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut
    En gros c'est de regarder quels sont les critères en commun avec les lignes pour former des groupes.
    Je veux que lorsqu'un des caractères est rencontré à la suite suivante il le regroupe dans une même ligne.

    Si je le fais step by step :

    j'ai ligne 1 = A et 1
    à la ligne 2 j'ai B et 1 . J'ai donc 1 en commun entre la ligne 1 et 2 donc je veux former le groupe
    A ,1 ,B , 1 ( soit A, 1 , B car le 1 est déjà présent )
    Ensuite à la ligne 3 j'ai A et 4 , comme j'ai A en commun avec la ligne 1 je veux obtenir : A, 1, B, A, 4
    A la ligne 5 j'ai C et 5 . Il n'y a pas de point commun entre les autres lignes donc il est tout seul.
    J'ai donc deux groupes :
    le groupe 1 : A,1, B,A,4 ou (A , 1 , B , 4 )
    le groupe 2 : C,5

    En gros c'est un peu comme un exemple de recursion par ici sur l'exemple père et fils
    http://www.lexjansen.com/pharmasug/2.../cc12_ward.pdf


    C'est compliqué à expliquer ...

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 83
    Points : 137
    Points
    137
    Par défaut
    Oui donc c'est bien ce que je propose, tu crée un nouveau groupe (=incrémenter un nombre) à chaque fois que tu rencontre deux modalités qui ne sont ni l'une ni l'autre dans le groupe actuel, si ce n'est pas le cas (au moins une des modalités existe déjà dans la liste groupe actuel) tu les ajoute (en enlevant les doublons) à une la liste du groupe actuel.

    Partant de la tu devrait y arriver avec une étape data et la fonction lag.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut
    C'est un peu plus complexe . En effet si je retiens la valeur , que je passe à la ligne suivante qu'il ne reconnait pas les caractère il va donc creer un nouveau groupe. Sauf que la ligne d'après il va comparer au groupe 2 et plus au groupe 1 .

    Plutôt que des mots regarde l'exemple que j'ai essayé de faire qui malheureusement créer trois groupes au lieu de deux.
    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
     
    DATA tbl_1;
    INPUT bli $    blou$
    ;
    CARDS;
    A     1
    B     1
    A	  4
    C     5
    F	  4
    ;
    run;
     
     
    proc sort data = tbl_1 ; 
    by  bli   ; 
    run ;
     
     
     
    %macro test ; 
    data test ; 
    format f $60. ;
    set tbl_1 ; 
    retain f  groupe ;
    if _N_ = 1 then do ; 
    groupe = 1 ; 
    a = compress(bli||','||blou) ; 
    f=a ; 
    end; 
    if _N_ > 1 then do ;
    if  
    %do j = 1 %to  8 ; 
    %if &j. < 8 %then %do ; 
    (scan(f,&j.,',')) = blou
    or 
    (scan(f,&j.,',')) = bli 
    or 
    %end ; 
    %else %do ; 
    (scan(f,&j.,',')) = blou
    or 
    (scan(f,&j.,',')) = bli 
    %end ; 
    %end ;
    then do ;  
    a =compress(bli||','||blou||','||f)  ;
    f = a ; 
    end ; 
    else do ; 
    a= compress(bli||','||blou) ; 
    f= a ;
    groupe = groupe +1 ; 
    end ; end ; 
    run ; 
    %mend ; 
    %test  ;

  6. #6
    Membre éclairé

    Femme Profil pro
    SAS FRANCE - Support Clients France et Europe
    Inscrit en
    Février 2010
    Messages
    289
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : SAS FRANCE - Support Clients France et Europe
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 289
    Points : 886
    Points
    886
    Par défaut
    Bonjour,

    Quel casse-tête ! Quel défi à relever ;-)

    J'ai créée une table permettant de savoir quelles étaient les n° d'observations à prendre en compte pour chaque groupe. Avec des tris, des first et des last, j'ai fini par obtenir la liste des observations où commence un groupe, où termine un groupe. Ensuite il n'y a plus qu'à lire la table initiale.


    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
    DATA tbl_1;
    INPUT bli $    blou$
    ;
    CARDS;
    A     1
    B     1
    A	  4
    C     5
    ;
    run;
     
     
    /* déterminer les groupes d'observations correspondant à chaque groupe */
    /* data1 : contient le n° des lignes pour chaque BLI, data1 a le même nb d'obs que tbl_1*/
    data data1 (keep=bli obs) ;
      length BLI $10. Obs 3. ;
      set tbl_1 ;
      obs=_N_ ;
    run ;
     
    proc sort data=data1 ;
    by bli obs ;
    run ;
     
    /* data2 : contient 1 BLI par ligne donnant la 1ère et la dernière obs dans tbl_1 à prendre en compte pour ce BLI*/
    data data2 ;
    retain FirstObs LastObs 0 ;
    set data1 ;
    by bli  ;
    if first.bli then FirstObs=obs ; 
    If last.bli then do ;
      LastObs=obs ;
      output ;
      FirstObs=0 ; LastObs=0 ;
    end ;
    run ;
     
    proc sort data=data2 ;
      by FirstObs ;
    run ;
     
    /* data3 : supprime les BLI qui sont inclus dans un groupe précédent - cas de B dans l'exemple*/
    data data3 (drop=last);
      retain Last 0 ;
      set data2;
      If FirstObs gt Last then output ;
      last=LastObs ;
    run ;
     
    /* on créée des macros variables pour lister les n° d'obs où un groupe commence, où un groupe termine */
    data _null_;
      Length ListeFirst ListeLast $1000.  ;
      retain ListeFirst ListeLast '0';
      set data3 end=last;
      ListeFirst=compress (ListeFirst !! ',' !! FirstObs) ;
      ListeLast=compress (ListeLast !! ',' !! LastObs) ;
      if last then do ;
        call symput ("ListeFirst", compress(ListeFirst)) ; /* liste des n° d'observations où un groupe commence dans tbl_1*/
        call symput ("ListeLast", compress(ListeLast)) ;
      end ;
     
    run ;
    %put _user_ ;
     
     
     
    /* résultat*/
    data data4 (keep=groupe blix) ; 
      length groupe 3. blix $1000. ; 
      retain groupe 0 blix '' ; 
      set tbl_1;
      if _n_ in (&ListeFirst) then Groupe +1 ;
      if indexw(blix, bli) eq 0 then blix=compbl (blix !!  bli );
      if indexw(blix, blou) eq 0 then blix=compbl (blix !! blou );
      if _n_ in (&ListeLast) then do ; 
        blix=translate (trim(left(blix)), ',', ' ') ;
        output ; 
        blix=''; 
      end ;
    run;
    Ce code devrait demander quelques changements pour répondre à votre besoin, mais je pense que c'est un bon début.

    Bonne journée,

    Cordialement
    Géraldine Cade-Deschamps
    Support Clients SAS

  7. #7
    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
    Bonjour,

    je n'ai pas le temps de te proposer un code mais il y aurait une solution, je pense relativement simple a faire avec des tables hashage (ou des arrays qui doivent aussi s'y prêter du coup mais avec peut-être une programmation un peu plus compliqué).


    Tu créé un objet hash "H_groupe" avec comme clé "var" et comme donnée "groupe".

    La première observation te défini un premier groupe que tu rentre dans ta table de hashage

    (H_groupe)
    var groupe
    A grpe1
    1 grpe1

    ensuite tu lis la deuxième observation

    "B 1"

    tu cherche à quel groupe appartient B
    tu cherche à quel groupe appartient 1

    Tu trouve que B n'apparient à aucun groupe et que 1 appartient au groupe "grpe1" alors tu ajoute "b" comme un élément de "H_groupe" avec la propriété groupe="grpe1" (celui de 1).

    Ensuite tu lis "A" et "4" ,
    la tu trouve encore que "A" est dans H_groupe et appartient au groupe="grpe1" mais pas "4" donc tu ajoute 4 comme élément de H_groupe dans "grpe1"

    a ce moment tu as dans l'objet H_groupe

    var groupe
    1 grpe1
    4 grpe1
    A grpe1
    B grpe1

    Tu passe à "C" "5".

    Tu constate que ces deux clés ne sont pas dans H_groupe
    Tu rajoute alors ces deux clés comme appartenant à un nouveau groupe dans H_groupe

    H_groupe
    var groupe
    1 grpe1
    4 grpe1
    A grpe1
    B grpe1
    C grpe2
    5 grpe2

    Tu continu à lire "F" "4" etc...

    Tu as 3 cas en fait

    Les deux clés ne sont pas dans H_groupe alors on créé un nouveau groupe dans H_groupe avec ces deux clés.

    Une des deux clés est dans H_groupe et pas l'autre, tu rajoute celle qui n'y est pas au groupe de l'autre clé.

    Les deux clés sont dans H_groupe mais avec des appartenance de groupe différentes alors tu fusionne les deux groupes dans H_groupe.

    Une fois terminé, tu affecte à tes observations les groupes ainsi construit.

    La programmation ne doit être au final pas si compliqué que ça.

    bon courage !

    Edit : la solution par tableau temporaire n'est finalement même pas plus compliqué...Le schéma reste le même.

    Par contre il ne faut pas chercher à avoir une seule étape DATA tu te complique les choses pour rien :
    1ère etape une étape data pour construire tes groupes
    2ème étape une SQL pour affecter tes groupes à ta table.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    Déjà merci pour vos réponses. jerome_pdv2 et Géraldine_Cade_SAS
    (désolé par avance mais je vais vous tutoyer)

    J'allai partir sur un truc un peu similaire à ta méthode Jerome_pdv2 mais en mode bourrin.

    tbl_1
    A 1
    B 1
    A 4
    C 5
    F 1



    Type :
    Je numérote mes lignes de tbl_1 .
    Je calcule le max(du nombre de ligne )
    Je boucle jusqu'à ligne 5 (nombre de ligne max )
    - JE prends la ligne 1 : A, 1 que je mets en macro variable (&concat)
    -Je compare &concat à la ligne 2 de tbl_1 , j'ai un truc en commun donc je concatene &concat à la ligne 2 (A,1,B,1) et j'envoie l'observation B,1 dans une table_sortie avec comme champs (bli blou groupe)
    - je répète la même opération pour la ligne 3
    -Je scan la ligne 4 j'ai rien en commun donc j'envoie pas l'observation.
    -Je scan la ligne 5 j'ai un truc en commun avec &concat donc j'envoiedans table_sortie.
    - ma boucle est terminé.
    - Je créer une table_2 qui prend ma tbl_1 en enlevant les lignes de la table_sortie.
    Il me reste donc C 5 j'incémente mon compteur groupe et je procède à la même méthode en rescannant la table avec les observations qu'ils me restent ( dans mon exemple il reste plus d'observation mais imaginons qu'il y en ait d'autres alors ça continue) et je boucle jusqu'à ce que toutes les observations soient dans ma table sortie.
    Mon explication est bordélique mais bon ....
    Je posterai le code lundi , là c'est week end
    Je voulais faire ça en une seule étape data car je me dis que rescanner la table à chaque fois ça pompe du CPU mais bon je crois que y a pas le choix.

    Géraldine_Cade_SAS j'ai pas encore lu ton code mais je vais aussi regarder ce que tu as fait pour comprendre la logique

    A bientôt pour un autre casse tête !!!

Discussions similaires

  1. Pb pour regrouper lignes d'une requête analyse croisée
    Par avry91 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 05/02/2008, 12h01
  2. Réponses: 4
    Dernier message: 29/11/2005, 13h14
  3. [ORACLE 9i] Avoir 12 lignes pour 12 mois de chaque années
    Par Worldofdada dans le forum Oracle
    Réponses: 4
    Dernier message: 17/11/2005, 11h57
  4. Réponses: 2
    Dernier message: 08/06/2004, 14h42
  5. [TDBGrid] Multisélection de lignes pour suppression
    Par littledoudou dans le forum C++Builder
    Réponses: 9
    Dernier message: 05/11/2003, 10h42

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