Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > Macro
Macro Forum d'entraide sur le langage Macro de SAS
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/01/2012, 18h46   #1
Invité de passage
 
Homme
Inscription : novembre 2011
Messages : 6
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : novembre 2011
Messages : 6
Points : 2
Points : 2
Par défaut Macro au sein d'une étape data

Bonjour,

Pour les besoins de mon programme, j'ai crée au sein d'une étape data (plus précisément au sein d'une boucle array) une macro, cette macro dépend de i qui est mon compteur de boucle array

J'explique brièvement le but de mon programme:
J'ai plusieurs lignes dans ma table, chaque ligne contient des informations sur une personne, et pour chaque personne je dois calculer la variable indice en fonction de l'age de la personne projeté sur 10 années.
J'ai dans ma table une variable Age et des variables var1, var2,...var100. Je calcule la variable indice en fonction de la variable Age et de i, si Age+i=25 alors indice(i)=var25.

Je voudrais savoir si le fait de créer des macros au sein de mon étape data peut poser problème?
Ces macros dépendent de i qui varie avec ma boucle, est ce deconseillé?

Merci d'avance.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
DATA Calcul(DROP=i);
SET Calcul;
 
array indice(15);
 
do i=1 TO dim(indice);
 
  %MACRO test;
  %DO j=1 %TO 100;
  IF Age+i=&j. then do; indice(i)=var&j.; end;
  %end;
  %MEND;
 
%test; 
 
end;
run;
gui82 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/01/2012, 20h59   #2
Membre Expert
 
Inscription : mars 2005
Messages : 1 011
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 011
Points : 1 259
Points : 1 259
Envoyer un message via Yahoo à bahraoui
Je ne pense pas que le compilateur acceptera ce genre de syntaxe.
Je testerai demain ton code.
Je l'écrirai plutôt comme ça.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
%MACRO test;
DATA Calcul(DROP=i);
SET Calcul;
 
array indice(15);
 
do i=1 TO dim(indice);
 
 
  %DO j=1 %TO 100;
  IF Age+i=&j. then do; indice(i)=var&j.; end;
  %end;
 
 
end;
run;
  %MEND;
 
%test;
__________________
Consultez les FAQs et les anciens postes avant de poser vos questions. Merci
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/01/2012, 21h57   #3
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 828
Points : 2 828
Bonjour.
Ta macro n'est pas créée "au sein de l'étape DATA" même si le code en donne l'impression. Elle est créée avant l'exécution de l'étape DATA car le compilateur macro travaille toujours avant le compilateur SAS.
Tu aurais donc pu même définir le macro-programme (de %MACRO à %MEND) avant le début de l'étape DATA, ça n'aurait rien changé. C'est au moment de l'appel (%test) que tout se joue : soit le code SAS généré par le compilateur macro s'intègre bien au contexte (et tout va bien), soit ce n'est pas le cas et en découvrant le résultat, le compilateur SAS va tordre du nez.
Dans le code que tu donnes, le %DO ne fait jamais qu'un copier/coller. Le code SAS généré (tu peux le visualiser avec OPTION MPRINT ; et constater par toi-même) est correct, même s'il est un peu bavard.

Mais pourquoi tant de macros ? Alors que 2 arrays iraient si bien ensemble !!!
Code :
1
2
3
4
5
6
7
8
DATA Calcul (DROP=i);
SET Calcul;
array indice(15);
array vv var1-var100 ;
do i=1 TO dim(indice);
  indice(i)=vv(Age+i) ;
end;
run;
J'espère que ce code est équivalent au précédent car je n'ai rien testé.
Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 31/01/2012, 10h02   #4
Invité de passage
 
Homme
Inscription : novembre 2011
Messages : 6
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : novembre 2011
Messages : 6
Points : 2
Points : 2
Merci pour vos réponses Olivier et Bahraoui.

Merci pour ton code avec les 2 array Olivier, mais je ne peux pas l’utiliser car j’ai créé plusieurs macros dans mon étape data, certaines macro faisant des calculs. J’ai simplifié la macro pour mon post, car ma question repose plus sur la logique de programmation.

Mon code fonctionne correctement, mais je veux savoir si ma façon de programmer est correcte, car en général on créé les macros en dehors de l’étape data.
Je me demandais aussi si c’est courant d’utiliser i à l’intérieur de la macro alors que la boucle sur i est à l’extérieur de la macro.

Je vous pose ces questions pour savoir quelle est la logique de programmation en SAS pour éviter de faire des erreurs à l’avenir.
gui82 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2012, 13h14   #5
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 828
Points : 2 828
Bonjour.
Citation:
Envoyé par gui82 Voir le message
je veux savoir si ma façon de programmer est correcte, car en général on créé les macros en dehors de l’étape data.
Comme je te le disais, que tu écrives la définition du macro-programme (de %MACRO à %MEND) entre DATA et RUN, ou avant, ou même pendant une procédure qui précède, peu importe. Ce morceau-là de code n'a qu'une finalité : faire stocker au compilateur macro un ensemble de code auquel, dans l'immédiat, il ne prête presque pas attention.
C'est au moment où on utilise (appel) le macro-programme (%test) que le compilateur macro s'active. Et il travaille avant le compilateur SAS, c'est à dire avant que l'étape DATA ne démarre.
Donc tu peux écrire avec le même résultat
Code :
1
2
3
4
5
6
7
8
%MACRO test (variable) ;
  IF &variable > 0 THEN &variable=0 ;
%MEND test ;
DATA work.rien ;
  SET sashelp.class ;
  %test(weight) ;
  %test(height) ;
RUN ;
ou
Code :
1
2
3
4
5
6
7
8
9
 
DATA work.rien ;
  SET sashelp.class ;
%MACRO test (variable) ;
  IF &variable > 0 THEN &variable=0 ;
%MEND test ;
  %test(weight) ;
  %test(height) ;
RUN ;
C'est exactement la même chose.

Un macro-programme, c'est surtout du copier/coller. Et le but premier est d'avoir un code réutilisable. Donc la définition du macro-programme à l'intérieur (visuellement) d'une étape DATA est déroutante, mais pas inexacte.
Cela dit, sans doute ma solution n'est pas adaptée dans ton cas réel, mais l'idée de faire des boucles supplémentaires dans l'étape DATA est souvent une alternative aux macro-programmes.
Citation:
Envoyé par gui82 Voir le message
Je me demandais aussi si c’est courant d’utiliser i à l’intérieur de la macro alors que la boucle sur i est à l’extérieur de la macro.
Ce qui compte, c'est le code SAS qui sera généré au final, et le compilateur auquel on demande d'évaluer des conditions. Si tu voulais te servir de la valeur de la variable I dans une condition macro (%IF) ça ne fonctionnerait pas, car le compilateur macro, on l'a dit, va travailler avant le début de l'étape DATA.
Dans le sens inverse (tu utilises la valeur de la macro-variable &J dans une condition SAS), pas de souci : le compilateur macro écrit le IF de SAS (sans le comprendre car ça ne le concerne pas) en remplaçant les &J par la valeur qui va bien, autant de fois qu'il passe dans la boucle %DO. Si le code SAS qui en résulte est correct, tout va pour le mieux.

Et bon courage pour la suite.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 31/01/2012, 13h46   #6
Invité de passage
 
Homme
Inscription : novembre 2011
Messages : 6
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : novembre 2011
Messages : 6
Points : 2
Points : 2
Tes explications sont très claires, ça m'aide à mieux comprendre le fonctionnement de SAS pour mieux coder.
Merci encore Olivier.
gui82 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h02.


 
 
 
 
Partenaires

Hébergement Web