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 :

macro variable numérique?


Sujet :

Macro

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    statisticienne
    Inscrit en
    Mai 2011
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : statisticienne
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2011
    Messages : 40
    Points : 37
    Points
    37
    Par défaut macro variable numérique?
    Bonjour à tous,

    J'ai un petit souci dans ma programmation que je ne m'explique pas...

    Dans une macro :
    J'ai une variable, dont je récupère le minimum dans une table SAS. Avec un call symput, j'attribue cette valeur à une macro-variable.
    Je cherche ensuite (et c'est là que j'ai un souci!) à avoir une condition sur la suite de la macro sur cette macro variable. Le problème est que cette condition est "si macro-variable<0", et que SAS la reconnait comme caractère et non numérique. Et avec un %eval, ça ne marche pas non plus...

    Voilà ma macro (simplifiée au maximum pour cet exemple) :

    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
    %macro test(tabin, var);
     
    proc univariate data=&tabin noprint; var &var; output out=temp0 min=min;
    run;
    data null; set temp0;
    call symput('Min',min);
    run;
     
    %put Mininimum = &Min;
     
    %if (%eval(&Min)<0) %then %do;
    %put toto;
    %end;
     
    %mend;
    => SAS n'arrive pas à reconnaitre en ma macro-variable Min une variable numérique, malgré le %eval...

    Avez-vous une idée?
    Merci d'avance pour toute piste!!

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

    Pour commencer je te propose une autre syntaxe via la proc sql qui évite de créer une table temporaire et optimise le traitement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    proc sql;
    select min(&var) into :minvar
    from &tabin
    ; quit;
    au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    proc univariate DATA=&tabin noprint; var &var; output out=temp0 min=min;
    run;
    DATA NULL; SET temp0;
    call symput('Min',min);
    run;
    les macros variables sont enregistrées au type caractère, y a rien qu'on puisse faire la dessus. mais normalement ca passe quand même lorsque l'on utilise du numérique. ca donne quoi sans le %eval. D'une manière générale, je te conseille plutôt d'utiliser la macro fonction %sysevalf. Sinon tu n'as pas à priori besoin du %do %end, bien que cette sécurité ne soit pas gênante en soit. Elle dit quoi la log?

  3. #3
    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
    tes instructions sont un peu trop mal placées.

    on utilise le
    pour ne pas créer une table.

    le call symput est une façon s'assigner des macros variables à des OBS, et là toi tu ne récupére qu'une seule valeur. donc un %let pourra faire l'affaire.

  4. #4
    Nouveau membre du Club
    Femme Profil pro
    statisticienne
    Inscrit en
    Mai 2011
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : statisticienne
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2011
    Messages : 40
    Points : 37
    Points
    37
    Par défaut
    Merci pour vos réponses!

    Super pour l'astuce de la proc sql Manoutz, je n'y pense jamais à celle là!
    Sinon tu n'as pas à priori besoin du %do %end, bien que cette sécurité ne soit pas gênante en soit.
    C'est qu'en réalité j'ai beaucoup plus d'instructions que %put toto (!) et j'ai oublié de les enlever, j'ai simplifié le code au maximum pour vous montrer mon problème...

    Voici mon code amélioré:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    %macro test(tabin, var);
     
    proc sql;
    SELECT min(&var) INTO :minvar
    FROM &tabin
    ; quit;
     
    %put Mininimum = &Minvar;
    %if (%eval(&Minvar)<0) %then %do;
    %put toto;
    %end;
    %mend;
    Cependant, cela ne marche toujours pas. La log dit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Mininimum = -3.27591
    ERROR: Opérande caractère trouvé dans la fonction %EVAL ou condition %IF là où un opérande numérique
           est requis. La condition était : -3.27591
    ERROR: L'exécution de la macro TEST va s'arrêter.

    Merci s_a_m pour ta réponse, mais je ne peux pas faire un %let parce que la valeur que je veux récupérer est dans une table SAS, ce n'est pas comme si je savais à l'avance que je voulais écrire %let minvar=-3, là ça va dépendre à chaque fois des données. Pour le data _null_, oui c'est pour ne pas créer de table, ici effectivement je ne veux pas en créer mais recueillir une valeur dans une table pour en faire une condition...

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    statisticienne
    Inscrit en
    Mai 2011
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : statisticienne
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2011
    Messages : 40
    Points : 37
    Points
    37
    Par défaut
    Ah excusez-moi, il y avait beaucoup de choses dans vos réponses j'ai oublié de tout tester!

    Sans le %eval j'avais le même message d'erreur, mais en utilisant %sysevalf cela marche parfaitement, plus d'erreur, c'est génial. MERCI!!!

  6. #6
    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
    utilise plutot %unquote et non pas %eval ( qui sert pour les calcules )

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

    C'est LA REGLE ESSENTIELLE en macro : une macro-variable c'est du texte, rien que du texte ! Il faut utiliser les fonctions macros si l'on veut la traiter en numérique, faire des traitements dessus etc.

    Géraldine Deschamps

  8. #8
    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,
    oui une macro variable est une chaine de caractère. Mais le système ne l'interprète pas toujours de tel.
    Exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    %let a=14;
     
     
    proc sql;
     select * from sashelp.class where age  =&a.;
    quit;

    et j'ai eu ce résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                             Le Système SAS                        3
                                        10:42 Thursday, May 19, 2011
     
              Name      Sex       Age    Height    Weight
              ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
              Alfred     M          14        69        112.5
              Carol      F           14      62.8       102.5
              Henry     M          14      63.5       102.5
              Judy       F          14      64.3         90
    on dirai que SAS a intérpreter ma macro variable comme du numérique. !!!

  9. #9
    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 : 47
    Localisation : France

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

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Non, SAM, ta macro-variable est bien restée du texte.
    C'est le texte 14 (c'est à dire 1 puis 4) qui a été copié par le compilateur macro dans le texte du code SAS, après le signe =.

    Il faut bien distinguer le compilateur macro, qui considère les macro-variables (et quasiment tout ce qui lui passe sous la main d'ailleurs) comme du texte, et le compilateur SAS, qui n'a accès à rien de ce que fait le compilateur macro et en subit uniquement les conséquences.
    L'ordre d'exécution de ta proc SQL est :
    1) le compilateur macro passe : presque tout est du texte qui l'indiffère, seul le &age retient son attention. Il remplace le texte &a par le texte 14.
    2) le compilateur SAS se voit transmettre le résultat de l'étape 1. Il interprète la valeur 14 comme un nombre mais ne sait pas que ça provient d'une macro-variable. Ca aurait tout aussi bien pu être en dur dans le code.

  10. #10
    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
    Merci Olivier pour les explications plus précises.
    Je n'ai pas précisé qu'il y a un compilateur marco et compilateur SAS qui Interprète le code ( que j'ai appelé système).

    Mais le compilateur SAS n'interprète pas toujours tout ce qui est chiffre comme du numérique?!!!
    alors j'ai fais ce teste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    %let a=14;
     
    data test;
    set sashelp.class;
    caractere= put (age,2.); /*PS: j'ai pas mis de $ pour éviter le warning comme quoi la variable est déjà numérique*/
    run;
     
    proc sql;
    select * from test where caractere=&a.;
    quit;
    message LOG:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ERROR: L'expression utilisant égal (=) a des composants qui
           sont de différents types de données.
    370  quit;

    mais avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    proc sql;
    select * from test where caractere="&a";
    quit;
    sa me donne bien le résultat attendu.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 133
    Points : 371
    Points
    371
    Par défaut
    Bonjour

    dans ton programme, tu indiques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    caractere= put (age,2.); /*PS: j'ai pas mis de $ pour éviter le warning comme quoi la variable est déjà numérique*/
    run;
    le "déjà" du PS me pose problème puisque tu utilises la fonction PUT, quel que soit le FORMAT utilisé, la variable créé est une variable caractère.

    aussi, quand tu indiques :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    proc sql;
    SELECT * FROM test WHERE caractere=&a.;
    quit;
    ça ne peut pas fonctionner : CARACTERE est une variable caractère, si tu veux citer une modalité, il faut, puisque la variable est caractère, la préciser entre quotes.

    a+

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

Discussions similaires

  1. Concaténation de macro variable char+numérique
    Par asirier dans le forum Macro
    Réponses: 3
    Dernier message: 31/07/2012, 09h40
  2. Comparaison macro variable numérique
    Par Jennn dans le forum Macro
    Réponses: 8
    Dernier message: 26/07/2012, 14h44
  3. Utiliser la valeur numérique d'une macro-variable?
    Par Laurent Q. dans le forum Macro
    Réponses: 4
    Dernier message: 14/12/2011, 17h17
  4. Forcer une macro variable a être numérique
    Par stefsas dans le forum Macro
    Réponses: 2
    Dernier message: 20/06/2008, 15h43
  5. Réponses: 9
    Dernier message: 14/04/2008, 11h58

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