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

Débutez Discussion :

proc TRANSPOSE avec 2 tables


Sujet :

Débutez

  1. #1
    Membre habitué
    Homme Profil pro
    Consultant informatique
    Inscrit en
    mars 2002
    Messages
    238
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : mars 2002
    Messages : 238
    Points : 197
    Points
    197
    Par défaut proc TRANSPOSE avec 2 tables
    Bonjour,

    Quelqu'un peut-il m'aider avec le problème suivant?

    J'ai 2 tables: Client et Contrats qui sont liées par l'id du Client (idcl)
    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
    data client1;
    	length idcl $3. client $8.;
    	input idcl client;
    datalines;
    001 Bernard
    002 Laurent
    003 Fabian
    ;
    run;
     
    data contrat2;
    	length idct $3. nom $5. idcl $3. am 3.;
    	input idct nom idcl am;
    datalines;
    101 AAAAA 001 150
    102 BBBBB 001 200
    103 CCCCC 003 500
    ;
    run;

    Le but est d'obtenir une table finale avec à chaque fois une ligne qui contient:
    Le client et tous ses contrats les unes à la suite des autres (ainsi que les infos du contrat).

    J'ai essayé avec un proc transpose mais je n'y arrive pas puisque je suis avec 2 table et des données en plus.

    Ci dessous une exemple du code que j'ai essayé:
    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
    data client1;
    	length idcl $3. client $8.;
    	input idcl client;
    datalines;
    001 Bernard
    002 Laurent
    003 Fabian
    ;
    run;
     
    data contrat2;
    	length idct $3. nom $5. idcl $3. am 3.;
    	input idct nom idcl am;
    datalines;
    101 AAAAA 001 150
    102 BBBBB 001 200
    103 CCCCC 003 500
    ;
    run;
     
    proc sort data=client1 out= client;
    	by idcl;
    run;
     
    proc sort data=contrat2 out= contrat;
    	by idcl;
    run;
     
    data test;
    	merge client (In = InCl)
     		contrat (In= InCt);
    	by idcl;
     
    	if InCl and InCt;
    run;
     
    proc sort data=test;
    	by client;
    run;
     
    proc transpose data=test out=pivot;
    	by client;
    	var nom;
    run;
    J'obtiens bien une table avec:
    ligne1: Bernard AAA BBB
    ligne2: Fabian CCC

    mais je n'arrive pas à mettre les données supplémentaires du contrat, par exemple son montant (am)

    Quelqu'un peut-il m'aider?

    Ou existe-t-il une meilleure solution que TRANSPOSE?

    Merci

  2. #2
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    la solution via une transpose est une option envisageable, il est plus simple dans ce cas que tu transpose en premier ta table contrat2 de sorte à obtenir une ligne par idcl. Forme ensuite une table finale en joignant tes deux table (à identifiant unique), comme tu l'as fait par un data step par exemple

  3. #3
    Membre habitué
    Homme Profil pro
    Consultant informatique
    Inscrit en
    mars 2002
    Messages
    238
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : mars 2002
    Messages : 238
    Points : 197
    Points
    197
    Par défaut
    il est plus simple dans ce cas que tu transpose en premier ta table contrat2 de sorte à obtenir une ligne par idcl
    Ok, je pense que mon problème se situe plus spécifiquement ici.
    Quand je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    proc transpose data=contrat out=pivot2;
    	by idcl;
    	var nom;
    run;
    je n'obtiens pas toutes les infos de contrat.

    mais si je change mon var en J'obtiens deux lignes par colonnes.

    Je ne comprend pas toute la subtilité du transpose mais comment y ajouter toutes mes variables?

  4. #4
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    bon j'abdique avec la proc transpose. ya surement un moyen mais pour être franc je ne l'utilise quasiment jamais et je ne suis pas fan du tout. si qqn à la soluce uniquementvia transpose je suis preneur.

    voici en tout cas une solution

    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 contrat;
    	length idct $3. nom $5. idcl $3. am 3.;
    	input idct nom idcl am;
    datalines;
    101 AAAAA 001 150
    102 BBBBB 001 200
    103 CCCCC 003 500
    ;
     
    proc transpose DATA=contrat out=pivot2;
    	var nom idct am; 
    	by idcl;
    run;
     
    data sortie;
    merge pivot2(where=(_name_ in ("nom"))) 
    		pivot2(where=(_name_ in ("idct"))rename=(col1=col3 col2=col4))
    		pivot2(where=(_name_ in ("am"))rename=(col1=col5 col2=col6));
    	by idcl;
    run;

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    Chargée d'étude statistique
    Inscrit en
    mars 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Chargée d'étude statistique
    Secteur : Finance

    Informations forums :
    Inscription : mars 2011
    Messages : 25
    Points : 31
    Points
    31
    Par défaut
    Bonjour,

    J'ai déjà rencontré le même problème et je n'avais pas trouvé comment transposer plusieurs variables dans un même transpose.

    J'ai donc fait de l'ensemble de mes variables à transposer une seule variable dans une étape data préalable à la proc transpose.
    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 contrat2 (drop = IDCT NOM AM COMPTEUR);
        set contrat2 ;
        by IDCL;
        if first.IDCL then COMPTEUR = 0;
        COMPTEUR + 1;
        LIB    =  COMPRESS("idct"||COMPTEUR);
        VALEUR =  idct;
        output;
        LIB    =  COMPRESS("nom"||COMPTEUR);
        VALEUR =  nom;
        output;
        LIB    =  COMPRESS("am"||COMPTEUR);
        VALEUR =  am;
        output;
    run;
    Ne reste plus ensuite qu'à faire le transpose selon cette nouvelle variable.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    proc transpose data= contrat2 
                   out = contrat2 (drop = _NAME_);
        var VALEUR;
        by idcl;
        id LIB;
    run;
    On obtient alors :
    Obs idcl idct1 nom1 am1 idct2 nom2 am2
    1 001 101 AAA 150 102 BBB 200
    2 003 103 CCC 500


    La dernière étape étant le merge avec la table client1 pour récupérer le nom du client.

  6. #6
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    Bonjour Aline,

    La solution que j'avais donné au dessus présente une alternative à la proc transpose. As tu essayé avec cette approche?

    Si jamais tu n'y arrive pas, merci de nous donner tes données en entrée (ou leur forme au moins), ainsi que la présentation que tu souhaites en sortie..

    Manoutz

  7. #7
    Nouveau membre du Club
    Femme Profil pro
    Chargée d'étude statistique
    Inscrit en
    mars 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Chargée d'étude statistique
    Secteur : Finance

    Informations forums :
    Inscription : mars 2011
    Messages : 25
    Points : 31
    Points
    31
    Par défaut
    Bonjour Manoutz,

    Excuse-moi, je n'ai pas été claire.

    Le code que je proposais permet également de répondre à la question de L0007 avec des étapes préalables à la proc transpose.

    Je le réutilise parfois, particulièrement quand j'ai besoin de transposer de nombreuses variables.
    Ci-dessous le code dans son intégralité.
    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
    DATA client1;
    	length idcl $3. client $8.;
    	input idcl client;
    datalines;
    001 Bernard
    002 Laurent
    003 Fabian
    ;
    run;
     
    DATA contrat2;
    	length idct $3. nom $5. idcl $3. am 3.;
    	input idct nom idcl am;
    datalines;
    101 AAAAA 001 150
    102 BBBBB 001 200
    103 CCCCC 003 500
    ;
    run;
     
    * Création d une seule variable pour les variables à transposer;
    data contrat2 (drop = IDCT NOM AM COMPTEUR);
        set contrat2 ;
        by IDCL;
        if first.IDCL then COMPTEUR = 0;
        COMPTEUR + 1;
        %macro CHANGEVAR (liste=, n=);
            %do i=1 %to &n;
                %let type= %scan(&liste,&i,%str( ));
                LIB    =  COMPRESS("&type."||COMPTEUR);
                VALEUR =  &type.;
                output;
            %end;
        %mend; 
        %CHANGEVAR (liste = idct nom am , n = 3);
    run;
     
    proc transpose data= contrat2 
                   out = contrat2 (drop = _NAME_);
        var VALEUR;
        by idcl;
        id LIB;
    run;
     
    proc sort data = contrat2; by idcl; run;
    proc sort data = client1 ; by idcl; run;
     
    data contrat2;
        merge client1 
              contrat2;
        by idcl;
    run;
    La méthode utilisée étant un peu différente de celle que tu proposais, je me suis permise de la rajouter.

    Bonne soirée,

  8. #8
    Membre expérimenté
    Avatar de MEGAMIND2
    Homme Profil pro
    Paris
    Inscrit en
    janvier 2011
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Paris

    Informations forums :
    Inscription : janvier 2011
    Messages : 1 029
    Points : 1 489
    Points
    1 489
    Par défaut
    Voici une solution à ton problème.

    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
    DATA client1;
    	length idcl $3. client $8.;
    	input idcl client;
    datalines;
    001 Bernard
    002 Laurent
    003 Fabian
    ;
    run;
     
    DATA contrat2;
    	length idct $3. nom $5. idcl $3. am 3.;
    	input idct nom idcl am;
    datalines;
    101 AAAAA 001 150
    102 BBBBB 001 200
    103 CCCCC 001 300
    104 DDDDD 001 400
    104 EEEEE 002 700
    105 FFFFF 003 500
    ;
    run;
    proc sort data=contrat2  ;
    by idcl;
    run;
    proc sort data=client1 ;
    by idcl;
    run;
    data clicontra;
    merge client1 contrat2;
    by idcl;
    run;
     
    /* calcul du nombre de colonnes maximale */
    proc sql;
    create table M as select  count(*) as NB from clicontra group by idcl;
    select max (NB) into:maxx from M;
    quit;
    %put maxx=&maxx;
    /*maxx=4 car on a le client 001 sur 4 lignes*/
     
    /* une table par variable à dupliquer==> montants en ligne*/
    proc transpose data=clicontra out=am(drop=_name_ );
    	var am;
    	by idcl;
    run;
    /* une table par variable à dupliquer==> contrats en ligne*/
    proc transpose data=clicontra out=idct(drop=_name_ );
    	var idct;
    	by idcl;
    run;
    /* renommage de COL1-COL&maxx par am&i(i=1 to maxx) et idct&i (i=1 to maxx)*/
    %macro M(table=,var=);
    	data &table.;
    	set &table.; 
    	%do i=1 %to &maxx.;
    	rename Col&i=&var&i.;
    	%end;
    	run;
    %mend;
    %M(table=am,var=am);
    %M(table=idct,var=idct);
     
    /* on ne garde que idct et le nom du client*/
    proc sort data=client1 out=Client(keep=idcl client);
    	by idcl;
    run;
     
    /* fusion des 3 tables */
    data CLICONTRAT;
    	merge Client am client idct;
    	by idcl;
    run;

  9. #9
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    Bonjour Aline,

    Je ne sais pas si la solution de megamind te convient, il y a peut être plus direct

    Permets moi de reposer la question: transposer, oui, mais comment? Quelle forme veux tu en sortie?

  10. #10
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : avril 2008
    Messages : 2 064
    Points : 4 476
    Points
    4 476
    Par défaut
    Bonjour.
    Une petite solution sans TRANSPOSE mais avec des ARRAYS. Pour transposer élégamment plusieurs variables, il faut préparer la table comme le fait Aline si on veut utiliser la proc TRANSPOSE. Sinon on bricole.
    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
    DATA client1;
    	length idcl $3. client $8.;
    	input idcl client;
    datalines;
    001 Bernard
    002 Laurent
    003 Fabian
    ;
    run;
     
    DATA contrat2;
    	length idct $3. nom $5. idcl $3. am 3.;
    	input idct nom idcl am;
    datalines;
    101 AAAAA 001 150
    102 BBBBB 001 200
    103 CCCCC 003 500
    ;
    run;
     
    PROC SQL NOPRINT ;
      CREATE TABLE work.tout AS
      	SELECT cli.*,
    	       ct.*
    	FROM work.client1 AS cli
    	  NATURAL INNER JOIN
    	     work.contrat2 AS ct
      ;
      SELECT idcl,
             COUNT(*)
    	INTO : rien, : nbMax
      FROM work.tout
      GROUP BY idCl
      ORDER BY 2 DESC
      ;
    QUIT ;
     
    DATA work.tout_en_ligne (DROP=num nom idcl am) ;
      SET work.tout ;
      BY idCl ;
      ARRAY idCont  {&nbMax} $ ;
      ARRAY nomCont {&nbMax} $ ;
      ARRAY amCont  {&nbMax}   ;
      RETAIN ;
      IF FIRST.idCl THEN DO ;
    	num = 0 ;
    	CALL MISSING(OF idCont(*)) ;
    	CALL MISSING(OF nomCont(*)) ;
    	CALL MISSING(OF amCont(*)) ;
      END ;
      num + 1 ;
      idCont(num) = idCt ;
      nomCont(num) = nom ;
      amCont(num) = am ;
      IF LAST.idCl THEN OUTPUT ;
    RUN ;
    Bonne journée.
    Olivier
    Bon courage.
    Olivier

Discussions similaires

  1. PROC TRANSPOSE avec variable texte
    Par sniper75 dans le forum SAS Base
    Réponses: 2
    Dernier message: 19/11/2013, 12h47
  2. Proc transpose avec des doublons
    Par tassia dans le forum Débutez
    Réponses: 2
    Dernier message: 22/10/2012, 15h28
  3. Alignement des colonnes avec la proc Transpose
    Par CSpot dans le forum SAS Base
    Réponses: 1
    Dernier message: 23/07/2012, 19h13
  4. Transposer une table avec proc transpose
    Par shudmeyer dans le forum SAS Base
    Réponses: 1
    Dernier message: 06/04/2012, 15h33
  5. Problème avec la proc Transpose
    Par ash_rmy dans le forum SAS Base
    Réponses: 3
    Dernier message: 07/04/2008, 11h16

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