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

Macro Discussion :

Renommer des variables avec une macro SAS


Sujet :

Macro

  1. #1
    Membre du Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Février 2009
    Messages : 81
    Points : 42
    Points
    42
    Par défaut Renommer des variables avec une macro SAS
    Bonjour,

    Je souhaite renommer des variables dans une table.

    J'ai une table avec 46 variables toutes nommées ainsi :
    Arbo_1
    Arbo_2
    Arbo_3
    ...etc...

    J'ai une table de référence WORK.VAR_ARBO avec ces indicateurs : NUM / NOM

    Par exemple :
    NUM / NOM
    1 / LIVRES
    2 / BD
    3 / DVD

    Je voudrais que les variables de ma table de départ passent de :
    Arbo_1 à LIVRES
    Arbo_2 à BD
    Arbo_3 à DVD

    Le NUM correspond au chiffre associé à Arbo_i...

    Avez vous une solution efficace ?

    Merci par avance !

  2. #2
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 1 625
    Points : 3 403
    Points
    3 403
    Par défaut
    Bonjour;

    si tu veux renommer tes variables avec des espaces , saches que c'est impossible sous sas (Arbo_1 à LIVRES) et les caractères accentués non supporté.
    veux tu un résultat comme suite : Arbo_1_a_LIVRES?

  3. #3
    Membre du Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Février 2009
    Messages : 81
    Points : 42
    Points
    42
    Par défaut
    Je me suis un peu mal exprimé...

    les variables de ma table de départ sont :
    Arbo_1
    Arbo_2
    Arbo_3

    et je souhaite que ma table de sortie soit avec les variables renommées ainsi :
    LIVRES
    BD
    DVD

    Merci

  4. #4
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Bonjour,

    voici une première version à améliorer.
    penser à vérifier que le nombre de valeurs dans le referentiel est égale au nombre de variables dans la table...
    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
     
    data VAR_ARBO ;
    length num 3 nom $10;
    input num nom $;
    cards;
    1 livres
    2 bd
    3 dvd
    ;
    run;
    data _null_;set VAR_ARBO ;
    call symput('var'||left(trim(num)),nom);
    call symput('nb',_n_);
    run;
    %put _user_;
    proc sql;
    create table resu  (arbo_1 char(2),arbo_2 char(2),arbo_3 char(2));
    quit;;
    %macro rename;
    proc datasets lib=work;
    modify resu ;
    rename 
    %do i=1 %to &nb;
    	arbo_&i=&&var&i
    %end;;
    quit;
    %mend;
    %rename;

  5. #5
    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
    ce que je ferais , c'est créer une table ou chaque ligne fait corresponde les éléments que tu veux associer.

    ex:ligne 1, colonne 1:Arbo_1
    ligne 1 , colonne 2: LIVRES

    A partir de la je créerais une nouvelle colonne, qui spécifierait sous forme d'une chaine de caractère le rename:


    ligne 1 , colonne 3: Arbo_1=LIVRES.

    ensuite par une proc sql tu peux sélectionner tes 46 lignes et stocker dans une macro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    proc sql;
    select distinct colonne3 into :macrlist separated by " "
    from file
    ;quit;
    puis utiliser la macro variable dans le rename. Attention à la longueur de la macro variable toutefois, bien vérifier que la fin n'a pas été coupée

  6. #6
    Membre du Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Février 2009
    Messages : 81
    Points : 42
    Points
    42
    Par défaut
    SUPER !

    Merci, c'est parfait, c'est exactement ce que je voulais avoir !

  7. #7
    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
    Citation Envoyé par zellinho Voir le message
    SUPER !

    Merci, c'est parfait, c'est exactement ce que je voulais avoir !
    Bonjour,
    Ce que j'aurais fait moi pour automatiser complétement le travail

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    data initial;
    input arbo_1 $ arbo_2 $ arbo_3 $;
    datalines;
    1 2 3
    ;
    run;
    data bd;
    input LIVRE$ BD $ DVD$;
    datalines;
    4 5 6
    ;
    run;
    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
    /* cette macro renomme les variables de la table initiale par les variables 
       de la table pivo
     **> il faut s'assurer qu'on a les mêmes nombre de variables dans les deux tables*/
     
    macro M(table_initial= , table_pivo=);
     
    	proc contents data=&table_initial out=out1(keep=NAME VARNUM);
    	run;
    	proc contents data=&table_pivo out=out2(keep=NAME VARNUM);
    	run;
    	proc sort data=out1;by VARNUM;RUN;
    	proc sort data=out2;by VARNUM;RUN;
    	proc sql;
    	select name into: l1 separated by ' ' from out1;
    	select count(*) into:nb from out1;
    	select name into: l2 separated by ' ' from out2;
    	quit;
    	%put &l1;
    	%put &l2;
    	data &table_initial;
    	set &table_initial;
    	%do i=1 %to &NB.;
    		%let l1&i=%scan(&l1.,&i,' ');
    		%let l2&i=%scan(&l2.,&i,' ');
    		rename &&l1&i=&&l2&i;
    	%end;
    	run;
    %mend;
    %M(table_initial=initial , table_pivo=bd);

  8. #8
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Lire une table juste pour renommer les variables n'est pas une solution optimisée....
    Elle nécessite la lecture et l'écriture de la table.
    Alors qu'avec une proc datasets ou une proc sql (alter table), on travail directement sur le descripteur du fichier.

  9. #9
    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
    Citation Envoyé par bahraoui Voir le message
    Lire une table juste pour renommer les variables n'est pas une solution optimisée....
    Elle nécessite la lecture et l'écriture de la table.
    Alors qu'avec une proc datasets ou une proc sql (alter table), on travail directement sur le descripteur du fichier.
    Tu as raison barahoui, j'ai changé mon étape data par une proc datatests

    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
     
    /* cette macro renomme les variables de la table initiale par les variables 
       de la table pivo
     **> il faut s'assurer qu'on a les mêmes nombre de variables dans les deux tables*/
    %macro M(table_initial= , table_pivo=);
     
    	proc contents data=&table_initial out=out1(keep=NAME VARNUM);
    	run;
    	proc contents data=&table_pivo out=out2(keep=NAME VARNUM);
    	run;
    	proc sort data=out1;by VARNUM;RUN;
    	proc sort data=out2;by VARNUM;RUN;
    	proc sql;
    	select name into: l1 separated by ' ' from out1;
    	select count(*) into:nb from out1;
    	select name into: l2 separated by ' ' from out2;
    	quit;
    	%put &l1;
    	%put &l2;
    	 proc datasets lib=work;
         MODIFY &table_initial ;
           %do i=1 %TO &NB.;
    		%let l1&i=%scan(&l1.,&i,' ');
    		%let l2&i=%scan(&l2.,&i,' ');
    		RENAME &&l1&i=&&l2&i;
     
    %end;;
    	run;
    	quit;
    %mend;
    %M(table_initial=initial , table_pivo=bd);

  10. #10
    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
    Il y encore plus simple je pense. Tout peut se faire en une sql, pas besoin de boucler.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    proc sql;
    SELECT DISTINCT colonne1||"="||colonne2 INTO :macrlist separated BY " "
    FROM file
    ;quit;
    si colonne1 et colonne 2 se trouvent dans deux fichiers différents on peut joindre dans le from du sql.

    Puis modifier le nom de variable via un rename en entrée dans l'étape/procédure suivante.

  11. #11
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Citation Envoyé par MEGAMIND2 Voir le message
    Tu as raison barahoui, j'ai changé mon étape data par une proc datatests

    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
     
    /* cette macro renomme les variables de la table initiale par les variables 
       de la table pivo
     **> il faut s'assurer qu'on a les mêmes nombre de variables dans les deux tables*/
    %macro M(table_initial= , table_pivo=);
     
    	proc contents data=&table_initial out=out1(keep=NAME VARNUM);
    	run;
    	proc contents data=&table_pivo out=out2(keep=NAME VARNUM);
    	run;
    	proc sort data=out1;by VARNUM;RUN;
    	proc sort data=out2;by VARNUM;RUN;
    	proc sql;
    	select name into: l1 separated by ' ' from out1;
    	select count(*) into:nb from out1;
    	select name into: l2 separated by ' ' from out2;
    	quit;
    	%put &l1;
    	%put &l2;
    	 proc datasets lib=work;
         MODIFY &table_initial ;
           %do i=1 %TO &NB.;
    		%let l1&i=%scan(&l1.,&i,' ');
    		%let l2&i=%scan(&l2.,&i,' ');
    		RENAME &&l1&i=&&l2&i;
     
    %end;;
    	run;
    	quit;
    %mend;
    %M(table_initial=initial , table_pivo=bd);
    Je viens de relire ton code et je constate que tu ne réponds pas exactement à la demande.
    Les nouvelles variables se trouve dans une variable d'une table.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    J'ai une table de référence WORK.VAR_ARBO avec ces indicateurs : NUM / NOM
     
    Par exemple :
    NUM / NOM
    1 / LIVRES
    2 / BD
    3 / DVD

  12. #12
    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
    Citation Envoyé par bahraoui Voir le message
    Je viens de relire ton code et je constate que tu ne réponds pas exactement à la demande.
    Les nouvelles variables se trouve dans une variable d'une table.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    J'ai une table de référence WORK.VAR_ARBO avec ces indicateurs : NUM / NOM
     
    Par exemple :
    NUM / NOM
    1 / LIVRES
    2 / BD
    3 / DVD
    Il suffit juste de supprimer la proc contents en trop et remplacer par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    proc sql;
    	SELECT NOM INTO: l1 separated BY ' ' FROM WORK.VAR_ARBO ;
    quit;
    Non barahoui? pour moi il a 0 pb

  13. #13
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    comme ça c'est mieux, la solution répond au besoins du client

  14. #14
    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
    Citation Envoyé par bahraoui Voir le message
    comme ça c'est mieux, la solution répond au besoins du client
    Le client est roi
    Sinon c'est bien de voir différentes approches de chacun (de toi et Manoutz) pour aller à Rôme.
    ça m'a permit aussi d'optimiser mon code.

  15. #15
    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
    Citation Envoyé par MEGAMIND2 Voir le message
    Le client est roi
    Sinon c'est bien de voir différentes approches de chacun (de toi et Manoutz) pour aller à Rôme.
    ça m'a permit aussi d'optimiser mon code.
    Peut mieux faire!

    Voici comment tout gérer en une proc sql

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    proc sql;
    	SELECT DISTINCT compress(A.nameorigin)||"="||B.Varname INTO :macrlist separated BY " "
    	FROM INIT as A inner join
    		(select distinct name as varname, monotonic() as nb 
    		from sashelp.vcolumn
    		where libname in ('SASHELP') and memname in ('CARS')) as B
    	on A.nb=B.nb
    ;
    quit;
     
    %put &macrlist.;
    j'ai au préalable créé le fichier init, ou chaque correspond au nommage d'une variable d'une fichier source. Init est déjà à la disposition de zelinho.

    proc contents et datasets sont inutiles (enfin, non optimales). Reste plus renommer au début de l'étape suivante (c'est même peut être gérable au sein de la sql via un alter table ou un modify...)

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

    Cette problématique est un excellent candidat pour le CALL EXECUTE ! Surtout si l'on ne connait pas le macro-langage. Le tour est joué en 6 lignes de code.

    Pour ma part je propose donc ceci :

    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
    DATA initial;
    input arbo_1 $ arbo_2 $ arbo_3 $;
    datalines;
    1 2 3
    ;
    DATA VAR_ARBO ;
    length num 3 nom $10;
    input num nom $;
    cards;
    1 livres
    2 bd
    3 dvd
    ;
    run;
     
    data _null_ ;
      set VAR_ARBO end=last;
      if _n_=1 then   call execute ("proc datasets lib=work ;  modify initial ;    rename ") ;
     
      call execute ( compress("arbo_" !! num) !! " = " !! nom) ;
     
      if last then call execute (";quit;") ;
      run ;
    CALL EXECUTE permet d'écrire le code qui sera exécuté une fois l'étape DATA en cours terminée. Ainsi on écrit du code en fonction du contenu d'une table.
    J'ai écrit un article à ce sujet il y a quelques années si quelqu'un souhaite aller plus loin :
    http://www.sas.com/offices/europe/fr...port_14_bd.pdf

    Géraldine CADE-DESCHAMPS
    Support Clients SAS

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/03/2015, 09h38
  2. Réponses: 6
    Dernier message: 16/01/2014, 11h21
  3. renommer des variables avec sas
    Par loubna181 dans le forum Macro
    Réponses: 21
    Dernier message: 07/07/2011, 19h05
  4. Modifer des liens avec une macro
    Par NemKa dans le forum VBA Word
    Réponses: 4
    Dernier message: 25/06/2007, 11h45
  5. Générer des variables avec une boucle
    Par Anamelech dans le forum Delphi
    Réponses: 15
    Dernier message: 03/11/2006, 12h33

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