Archive for the ‘Advanced’ Category

h1

Plusieurs mots d’un paramètre de macro à mettre entre guillemets (%QSYSFUNC, %STR(), TRANWRD)

mai 28, 2009

Mettre entre guillemets les mots contenus dans une macro variable SAS et les séparer par des virgules est possible au moyen des fonction %STR(), %QSYSFUNC et TRANWRD. Dans quel cas est-ce utile ? Comment se décompose cette syntaxe ?

1. Dans quel cas a-t-on besoin d’ajouter des guillemets et virgules ?

Lors de l’écriture d’une macro, vous pouvez avoir besoin d’autoriser plus d’un mot dans un des paramètres.

options mprint;

%macro test (multival=);

%mend test;

%test (multival=Alfred William);

Note : l’option MPRINT de l’instruction OPTIONS permettra de voir la résolution de la macro dans la log.

Ensuite, le contenu de ce paramètre traité comme une macro variable peut être appelé dans une condition. Dans l’exemple qui suit « Alfred », »William » sera remplacée par la macro variable mise à jour.

proc print data=sashelp.class (where=(name = (« Alfred », »William »));

run;

Il faut pour cela mettre la macro variable à jour en ajoutant des guillemets et la virgule comme séparateur.

2. Comment ajouter guillemets et virgules ?

2.1 Un mot

Dans le cas d’un paramètre avec un mot, on peut ajouter %str(% ») devant et derrière. Le symbole % permet d’introduire les caractères spéciaux comme le guillemet.

%let multival=%str(% »)&multival.%str(% »);

La macro donne alors :

%macro test (multival=);

%let multival=%str(% »)&multival.%str(% »);

proc print data=sashelp.class (where=(name = &multival.));

run;

%mend test;

%test (multival=Alfred);

2.2 Plus d’un mot

Pour mettre entre guillemets plus d’un mot, l’espace entre les mots sera remplacé par « , » (guillemet, virgule, guillemet) au moyen de la fonction TRANWRD.

%qsysfunc(tranwrd(&multival.,%str( ),%str(% »,% »)))

Pour exécuter cette fonction, qui n’a pas d’équivalent dans les macros fonctions, il faut englober le tout dans %SYSFUNC/%QSYSFUNC. La présence de la virgule oblige dans notre cas à utiliser %QSYSFUNC.

%macro test (multival=);

%let multival=%str(% »)%qsysfunc(tranwrd(&multival.,%str( ),%str(% »,% »)))%str(% »);

proc print data=sashelp.class (where=(name in (&multival.));

run;

%mend test;

%test (multival=Alfred William);

2.3 Plus d’un mot mis en majuscule

Enfin, pour ne pas tenir compte de la case, le texte peut être mis en majuscule au moyen de la fonction %UPCASE.

where=(upcase(name) in (%upcase(&multival.))

Cela donne :

%macro test (multival=);

%let multival=%str(% »)%qsysfunc(tranwrd(&multival.,%str( ),%str(% »,% »)))%str(% »);

proc print data=sashelp.class (where=(upcase(name) in (%upcase(&multival.))));

run;

%mend test;

%test (multival=Alfred William);

Lectures complémentaires

h1

Les pièges d’Excel : Une colonne sans nom (GETNAME=YES)

mai 24, 2009

Lors de l’importation d’un fichier Excel sous SAS au moyen de la procédure PROC IMPORT, la première ligne indique à SAS quel nom donné aux variables au lieu d’utiliser les lettres de l’alphabet. L’option par défaut est GETNAME=YES. Dans un cas, des informations peuvent être perdues. C’est ce que je vous propose de voir ici.

1. Le cas où tout va bien

Le tableau à importer contient 4 colonnes. La première ligne servira à SAS pour attribuer le nom des variables. La seconde ligne contient les données. Le tableau SAS aura 4 variables avec une observation chacune.

La procédure PROC IMPORT

proc import datafile=‘C:/sasref/getname_example1.xls’
out=getname_ex
dbms=xls
replace;
getname=yes;
run;

2. Un nom de colonne manquant

Dans le cas suivant, une des cellules de la première ligne est vide. SAS cherche un nom (GETNAMES=YES) mais n’en trouve pas. SAS n’importe pas la colonne concernée.. Le data set contient alors 3 variables avec une observation chacune.

h1

Evaluer le critère performance TEMPS d’un programme (%SYSFUNC, %SYSEVALF)

avril 10, 2009

Un critère pour évaluer la performance d’un programme est de connaître son temps d’exécution. La fonction système %SYSFUNC permettra de récupérer le temps à un instant donné et la fonction  %SYSEVALF servira à calculer la différence entre deux temps pré-enregistrés. Voici un exemple en 4 étapes.

1. Récupérer le temps en début de programme

Dans un premier temps, le temps de début est sauvegardé dans une macro variable TEMPS_DEBUT. Il est extrait au moyen de la fonction TIME() et est donc exprimé en secondes.

%let temps_debut = %sysfunc(time());

2. Exécuter la partie principale du programme

Pour l’exemple un simple PROC PRINT est ajouté comme partie principale du programme.

proc print data=sashelp.class;
run;

3. Récupérer le temps en fin de programme

Dans un troisième temps, le temps en fin de programme est sauvagardé dans la macro variable TEMPS_FIN. Comme précédemment; la fonction TIME() est utilisée.

%let temps_fin = %sysfunc(time());

4. Evalutation et affichage de la durée écoulée

La durée écoulé entre le début et la fin du programme est sauvegardée dans la macro variable DUREE. Cette durée est ensuite affichée dans la log au moyen de l’instruction %PUT.

Sur le même principe qu’une fonction %EVAL dans une macro, la fonction %SYSEVALF permet de considérer les deux variables TEMPS_DEBUT/TEMPS_FIN comme des nombres le temps du calcul de la différence.

%let duree = %sysevalf(&temps_fin.-&temps_debut.);
%put Durée d’exécution : &duree.;

Lectures complémentaires

www.sasreference.fr

SAS Online Doc

  • Using SAS Language Functions in the Data Step and Macro Facility
  • %SYSFUNC and %QSYSFUNC Functions
  • Summary Descriptions and Syntax
  • %EVAL Function
  • %SYSEVALF Function
  • How the macro processor evaluates Arithmetic Expressions
  • TIME Function
h1

Ajouter une date dans un nom de fichier Excel, Word…

mars 12, 2009

Sous SAS, en créant un fichier .xls ou .rtf avec la syntaxe de l’ODS (Output Delivery System), il est parfois pratique d’ajouter dans le nom du fichier une date. Par exemple : listing_20090311.xls.

Nous verrons ici plusieurs représentations de la date et de l’heure : afin d’avoir des noms triables par ordre chronologique, l’année apparaît avant le mois et le jour.

La syntaxe proposée, %SYSFUNC(fonction, format), s’utilise dans d’autres cas que la définition d’un nom de fichier (.rtf, .xls, …). De manière générale, elle sert à utiliser des fonctions en dehors d’une étape data ou d’une procédure. Par exemple, elle peut être ajoutée dans une instruction TITLE.

1. L’objectif pour un programme exécuté le 11 mars 2009

L’objectif de l’exemple qui suit est d’obtenir un fichier .xls nommé class_20090311.xls dont la date change selon le jour de sa création.

La version fixe se présente ainsi : un fichier .xls est créé au moyen de ODS TAGSETS.EXCELXP. Il contient les données du data set SASHELP.CLASS. La création d’un fichier dans la fenêtre OUTPUT est suspendu le temps de la création du fichier .xls au moyen de l’instruction ODS LISTING CLOSE et ODS LISTING.

ods listing close;
ods tagsets.excelxp file='C:/sasref/class_20090311.xls';
proc print data=sashelp.class;
run;
ods tagsets.excelxp close;
ods listing;

2. Ajouter de la flexibilité avec %SYSFUNC

A présent, la date est définie automatiquement au moyen de la macro fonction %SYSFUNC. Cette fonction est dans ce cas particulier composée de deux paramètres :

  • la date SAS extraite au moins de la fonction TODAY()
  • le format à appliquer sur cette date

Résoudre le contenu de la fonction %SYSFUNC grâce aux guillemets doubles : la fonction %SYSFUNC fait partie du langage macro. Dès lors, pour obtenir la résolution de son contenu, il faut utiliser des guillemets doubles.

Retrouver la date d’exécution du programme grâce aux fonctions TODAY() ou DATE () : La fonction TODAY() retourne la date SAS d’exécution du programme. Une alternative est la fonction DATE(). Dans les deux cas, la fonction ne contient pas de paramètre.

Le format YYMMDDn. pour écrire 20090311 : Le format YYMMDDn. est un sous-ensemble de la fonction YYMMDD composée de 8 caractères, sauf indication contraire, faisant apparaître :

  • l’année en premier,
  • suivi du mois en chiffre et
  • enfin du jour.

Ce format avec l’extension « n » a la particularité de ne pas utiliser de symbole ou espace séparatant le jour, du mois et de l’année. Les 8 caractères par défaut de la fonction laisse de la place à une année exprimée par 4 chiffres.

ods listing close;
ods tagsets.excelxp file="C:/sasref/class_%sysfunc(today(),yymmddn.).xls";
proc print data=sashelp.class;
run;
ods tagsets.excelxp close;
ods listing;

3. Tester d’autres formes d’affichage

3.1 Ajouter des tirets bas entre le jour, le mois et l’année grâce à la fonction TRANSLATE

class_2009_03_11.xls : pour avoir des tirets bas (underscore) entre le jour, le mois et l’année, il n’existe pas de format directement applicable. Une solution est alors d’utilise un autre symbole et de le remplacer avec la fonction TRANSLATE.

Ici le format YYMMDD10 retourne une date de la forme 20009-03-11. Les traits d’union (hyphen) sont remplacés par des tirets bas (underscore).

ods tagsets.excelxp file=« C:/sasref/class_%sysfunc(translate(%sysfunc(today(),yymmdd10.),’_’,’-‘)).xls »;

3.2 Ajouter une heure avec TIME() et PICTURE (class_20090311_113057.xls)

Quelle fonction pour l’heure ? : La fonction TIME() retourne l’heure sous la forme d’un time SAS.

Quels formats pour l’heure ? : Le format HHMM. retournera les heures et les minutes, tandis que le format TIME. retournera en plus les secondes. Dans les deux cas cependant, les heures avant 10h apparaissent avec seulement un chiffre : 9:30 et non 09:30. Un espace remplace le zéro manquant.

L’instruction PICTURE de PROC FORMAT pour un format personalisé : Une solution est de créer un format personalisé au moyen de l’instruction PICTURE (PICTURE statement). Comme les lettres H, M et S n’inclus pas de zéro devant (leading zero) pour les nombres à un chiffres, il faut les ajouter dans l’instruction PICTURE.

Note : %0S fait référence aux secondes. Il n’est obligatoire que si vous voulez des secondes dans votre texte final.

proc format;
   picture sasref other=‘%0H%0M%0S’ (datatype=time);
run;

Ensuite, 

  • pour une heure à quatre chiffres (heure + minutes) , il faudra préciser le nombre 4 dans l’appel du format.
  • pour une heures à six chiffres (heures + minutes + secondes), c’est 6 qui doit être ajouté

ods tagsets.excelxp file=« C:/sasref/class_%sysfunc(today(),yymmddn.)_%sysfunc(time(),sasref6.).xls »;

Lectures complémentaires sur http://www.sasreference.fr

ODS

Les fonctions

Les formats :

Les macros fonctions

h1

Additionner deux macros variables, la fonction %EVAL

janvier 15, 2009

En langage macro sous SAS, la distinction entre les macro variables numériques et les macros variables caractères n’est pas faite. En fait, toutes les macros variables sont de type caractère. Du coup, comment faire l’addition de deux macros variables contenant des nombres ?

1. La fonction %EVAL

La fonction %EVAL indique à SAS de gérer les indications qu’elles contient comme une opération mathématique. Il est alors possible de faire la soustraction, l’addition, la multiplication et la division de n’importe quelle macro variable contenant des nombres.

2. Deux data sets pour l’exemples : PATH_AE et PATH_PID

Pour illustrer cette macro fonction très simple du langage de programmation SAS, je vous propose ce petit exemple. A la base, il y a deux data sets :

  • PATH_AE (AE: Adverse Events ou effets secondaires) et
  • PATH_PID (PID: Patient Identifier ou identifiant du patient).

Chacun des deux data sets a une variable les chemins d’accès à des répertoires contenant respectivement les fichiers AE et PID. C’est le genre de data set qu’on peut obtenir à partir d’une commande Unix et une étape data.

Combien d’observations dans chaque data set ? : Le data set PATH_AE contient deux observations et le data set PATH_PID en a trois. Vous pouver activer les conditions WHERE pour que chacun des data sets soient vides et ainsi voir le changement qu’il implique dans la suite du programme.

data path_ae ;*(where=(substr(path_ae,1,1) ne 'c'));
   length path_ae $200;
   input path_ae;
   datalines;
c:/project_d15/study145
c:/project_d66/study234
;
run;

data path_pid ;*(where=(substr(path_ae,1,1) ne 'c'));
   length path_pid $200;
   input path_pid;
   datalines;
c:/project_a99/study133
c:/project_a99/study532
c:/project_b01/study012
;
run;

3. Créer des macros variables

Le code qui suit extrait le nombre d’observations de chacun de nos data sets dans des macro variables. C’est une approche alternative à l’utilisation des dictionnaires qui a le mérite de pouvoir indifféremment extraire des données au niveau du data set qu’au niveau des variables.

La macro variable CNT_AE

  1. Ouvrir le data set PATH_AE de la bibliothèque WORK.
  2. Y extraire le nombre total d’observations et le sauvegarder dans la macro variable CNT_AE.
  3. Fermer le data set PATH_AE.
%let dsid_ae = %sysfunc(open(work.path_ae,in));
%let cnt_ae = %sysfunc(attrn(&dsid_ae.,nobs));
%let rc_ae   = %sysfunc(close(&dsid_ae.));

La macro variable CNT_PID : de manière similaire, le nombre d’observations contenues dans le data set PATH_PID est sauvegardé dans la macro variable CNT_PID.

%let dsid_pid = %sysfunc(open(work.path_ae,in));
%let cnt_pid = %sysfunc(attrn(&dsid_ae.,nobs));
%let rc_pid   = %sysfunc(close(&dsid_ae.));

D’autres %SYSFUNC pourraient au besoin être ajoutées entre l’ouverture et la fermeture du data set.

4. Une petite vérification

A présent, voyons dans la log la valeur prise par la somme des deux macros variables.

%let check= %eval(&cnt_ae.+&cnt_pid.);
%put SASREF Macro Variable Check: &check.;

Si les options WHERE restent en commentaires, CHECK=5 puisque qu’on fait la somme de 2 (observations dans le data set PATH_AE) et 3 (observations dans le data set PATH_PID.

Par contre, si les options WHERE sont inclues, les deux data sets sont vide et CHECK=0.

5. Utiliser la macro fonction %EVAL() dans une macro

Dans le programme suivant, si aucun des deux data sets ne contiennent de données, un message est ajouté dans la log et SAS va directement au point d’encrage donné par PGM_END et donc ici en fin du programme. Tout programme intermédiaire est alors ignoré par SAS.

%macro test;
  *Here additional Program code can be included;
   %if %eval(&cnt_ae.+&cnt_pid.)=0 %then
      %do;
         %put NOTE_TEST_EVAL=--------------------------------;
         %put NOTE_TEST_EVAL= 1. Check data;
         %put NOTE_TEST_EVAL= 1.1 Check AE and PID data sets;
         %put NOTE_TEST_EVAL=--------------------------------;
         %put NOTE_TEST_EVAL= No AE or PID data set has been selected;
         %goto pgm_end;
      %end;
   *Here additional Program code can be included;
%pgm_end;
%mend test;
%test;

Pour un autre exemple de GOTO, vous pouvez vous reporte à la troisième partie de l’article intitulé « Mon paramètre de macro est-il rempli ? « .

h1

Sauvegarder une macro au delà d’une session SAS

janvier 8, 2009

Par défaut, une macro est créée le temps d’une session. En effet, elle est sauvegardée dans le catalogue réservé aux macros (macro catalog) de la bibliothèque WORK. Comment changer la bibliothèque en vue d’une utilisation ultérieure de la macro ?

1. Par défaut, créer une macro temporaire

Dans un premier temps, une macro appelée TMP_MACRO est créée. Cette macro est sauvegardée dans un fichier appelé un macro catalog de la bibliothèque WORK.

%macro tmp_macro;
proc print data=sashelp.class;
run;
%mend tmp_macro;

2. Sauvegarder de manière permanente la macro

A présent, il s’agit de sauvegarder la macro PERM_MACRO dans la biblioht`que SASREF. Comme précédemment, elle sera sauvegardée dans un catalogue ne pouvant contenir que des macro. Ce catalog s’appelle toujours SASMACR.

Grâce aux options SASMSTORED= et MSTORE, on précise à SAS que les macros à conserver (to store) seront à diriger dans la bibliothèque SASREF.

Ensuite, lors de la définition de la macro PERM_MACRO, on indique à SAS que cette macro fait partie des macros à conserver au delà de la session SAS. Elle sera donc sauvegardée dans la bibliothèque SASREF.

libname sasref 'C:/sasref';
options sasmstore=sasref mstored;

%macro perm_macro /store;
proc print data=sashelp.class;
run;
%mend perm_macro;

L’option STORE maintient la bibliothèque SASREF en activité. Il est alors impossible de désassigner la bibliothèque SASREF. Si vous avez une solution à ce problème, n’hésitez pas à nous la faire partager.

*libname sasref;
h1

Combien de contrats ai-je au total ? (1/5) PROC SQL

octobre 27, 2008

Sur le forum http://www.commentcamarche.net, j’ai rencontré une question pour laquelle une série d’articles seront rédigés et ainsi pour présenter différentes solutions. Je commence aujourd’hui avec une procédure SQL précédée d’une introduction sur les données. Les quatre prochains articles utiliseront les compteurs, les procédures PROC MEANS, PROC FREQ et PROC TABULATE.

1. Les données

On part d’un fichier contenant une liste de clients et deux types de contrats : téléphone (tel) et habitation (habitat).

  • Une variable TEL indique si oui ou non le client a un contrat de téléphone peu importe qu’il s’agisse d’une ligne fixe, d’un téléphone portable personnel. Une variable NB_CNTR précise le nombre de contrats de ce type le client a signé.
  • Une variable HABITAT indique si oui ou non le client a un contrat en relation avec son habitat qu’il s’agisse de sa maison principale, sa maison secondaire ou d’un contrat de location pour ses enfants partis étudiés, etc. La variable NB_CNTR précise comme précédemment le nombre de contrats de ce type souscrit par le client.
data contrats;
   input client $ nb_cntr tel habitat;
   datalines;
a 5 1 0
b 1 1 0
c 2 0 1
d 1 1 0
e 3 0 1
f 2 1 0
;
run;

Objectif : Le but du jeu est de retrouver le nombre total de contrats téléphoniques et de contrats d’habitation, soit 9 dans le premier cas (5+1+1+2) et 5 dans le second cas (2+3).

2. La procédure SQL

Dans cet exemple, un data set, appelé SOLUTION1, est créé à partir du fichier CONTRATS.

Créer une nouvelle variable TEL : SAS créé une nouvelle variable TEL.

  • Nombre de contrats par client : Pour chaque ligne d’observation, SAS multiplie le nombre de contrat par la variable binaire TEL pour retrouver le nombre de contrats téléphonique par client.
a 5 1 0 => 5*1 = 5
b 1 1 0 => 1*1 = 1
c 2 0 1 => 2*0 = 0
d 1 1 0 => 1*1 = 1
e 3 0 1 => 3*0 = 0
f 2 1 0 => 2*1 = 2
  • Puis, il fait la somme de tous les nombres (5+1+0+1+0+2) pour connaître le nombre total de contrats téléphoniques. Ce nombre est répété pour chaque observation.
a 5 1 0 => 9
b 1 1 0 => 9
c 2 0 1 => 9
d 1 1 0 => 9
e 3 1 0 => 9
f 2 0 1 => 9

Créer une nouvelle variable HABITAT : De la même manière, une nouvelle variable HABITAT est créée.

  • Nombre de contrat par client : Pour chaque ligne d’observation, SAS multiplie le nombre de contrats par la variable binaire HABITAT pour retrouver le nombre de contrats liés à l’habitation par client.
a 5 1 0 => 5*0 = 0
b 1 1 0 => 1*0 = 0
c 2 0 1 => 2*1 = 2
d 1 1 0 => 1*0 = 0
e 3 0 1 => 3*1 = 3
f 2 1 0 => 2*0 = 0
  • Nombre total de contrats : Puis, il fait la somme de tous les nombres (0+0+2+0+3+0) pour connaître le nombre total de contrats d’habitation. Ce nombre est répété pour chaque observation.
a 5 1 0 => 5
b 1 1 0 => 5
c 2 0 1 => 5
d 1 1 0 => 5
e 3 0 1 => 5
f 2 1 0 => 5

Ne souhaitant pas afficher le nom des clients (variable CLIENT), il est possible d’extraire une seule ligne pour les nouvelles variables TEL et HABITAT en ajoutant le mot-clé DISTINCT. Comme toutes les lignes ont les valeurs 9 et 5, une seule sera conservée.

proc sql;
   create table solution1 as
      select distinct sum(nb_cntr*tel) as tel,
                      sum(nb_cntr*habitat) as habitat
      from contrats;
quit;

Je vous donne rendez-vous tous les lundi pour présenter une nouvelle solution à commencer par lundi prochain dans une étape data, basée sur la notion de variable compteur générée à partir d’un RETAIN.

h1

Copier la structure d’un data set et se séparer des données

octobre 16, 2008

Sous SAS, comment récupérer les caractéristiques d’un data set dans un autre data set sans les données et ainsi s’épargner un travail occasionnel mais qui peut vite devenir fastidieux ? Le nom des variables, leur position dans le data set et leurs autres attributs (type, longueur, format, informat) forme la structure d’un data set. Pour les récupérer, deux notations sont offertes : l’option OBS= dans une étape data et le mot LIKE dans une procédure SQL.

1. Créer le data set servant d’exemple

Pour illustrer les deux notations, nous partirons d’un data set nommé CLASS contenant une ligne d’observations et trois variables :

  • le nom de l’élève (NAME),
  • la date de début du cursus (SDT pour starting date) et
  • la date de fin du cursus (EDT pour ending date).

data class;
attrib name length=$15 label=‘Nom’
sdt informat=date9. format=date9. label=‘Starting Date’
edt informat=date9. format=date9. label=‘Ending Date’;
input name $ sdt edt;
datalines;
Charline 06OCT2006 15JUN2007
;
run;

Un PROC CONTENTS résumera les attributs des variables de la manière suivante :

proc contents data=class;
run;

# Variable Type Len Pos Format Informat Label

3 edt Num 8 8 DATE9. DATE9. Ending Date
1 name Char 15 16 Nom
2 sdt Num 8 0 DATE9. DATE9. Starting Date

1. Créer un data set vide

Dans cette première partie, un data set SQL_SOLUTION et ETAPE_DATA sont créés. Les deux ont la même structure

La procédure SQL : Au lieu de désigner toutes les variables à garder après un AS SELECT, on passe directement au data set de référence en l’introduisant avec le mot LIKE.

proc sql;
create table sql_solution like class;
quit;

L’étape data : L’option data set OBS= sur le fichier d’entrée précise qu’aucune observation ne sera lue. Seul le ‘header’ du data set contenant les caractéristiques sont lues par SAS et sauvegardées dans le data set de sortie ETAPE_DATA.

data etape_data;
set class (obs=0);
run;

SAS ira un peu plus vite avec une instruction STOP.

data etape_data;
set class;
stop;
run;

3. Ajouter des observations au data set vide

Une fois le data set copié sans les observations deux lignes sont ajoutées. La première désigne Jean-Pierre qui a début en janvier 2006. Christophe est nommé en second. Il a début le 7 octobre 2005 et terminé le 18 juin 2007.

La procédure SQL : Dans la PROC SQL, je vous propose d’ajouter les observations manuellement grâce à l’instruction INSERT INTO.

proc sql;
create table sql_solution like class;
insert into sql_solution
set name=‘Jean-Pierre’, sdt=’10JAN2006′d
set name=‘Christophe’, sdt=’07OCT2005′d, edt=’18JUN2007′d;
quit;

L’étape data : Dans un data step, les nouvelles observations sont sauvegardées dans un autre data set et sont ajoutées au moyen de l’instruction SET.

data add;
name=‘Jean-Pierre’;
sdt=’10JAN2006′d;
output;
name=‘Christophe’;
sdt=’07OCT2005′d;
edt=’18JUN2007′d;
output;
run;

data etape_data;
set class (obs=0)
add;
run;

Note : Dans ce cas, il faut que le data set contenant la structure apparaissent en premier. SAS sauvegarde toujours la première variable qu’il rencontre avec ses attributs. Proposer une autre variable du même nom avec des attributs différents ensuite n’alternera pas celles sauvegardées en premier.

h1

Supprimer un data set SAS en 6 points (PROC DATASETS)

octobre 6, 2008

Supprimer un data set SAS est une des fonctionnalités de la procédure PROC DATASETS. Voici donc quelques détails sur la syntaxe.

Les options de l’instruction PROC DATASETS donnent la possibilité de supprimer, dans une bibliothèque donnée, tous les fichiers sans distinction de nom (KILL). Certains options réduisent la sélection à certains types de fichiers (MEMTYPE). L’affichage par défaut dans les fenêtres OUTPUT et LOG est contrôlable avec d’autres options (NOLIST et NOWARN). Pour ajouter un peu de flexibilité, il est possible de nommer les fichiers à supprimer ou à garder dans des instructions complémentaires (DELETE et SAVE).

1. Un option pour supprimer tous les fichiers quelque soit leur nom, KILL : Pour supprimer tous les fichiers SAS contenu dans une bibliothèque temporaire, il suffit d’ajouter l’option KILL à l’instruction PROC DATASETS.

2. Par défaut, supprimer tous les types de fichiers MEMTYPE=ALL : En effet, l’option MEMTYPE est par défaut égale à tout (MEMTYE=ALL). Cela comprend 3 types de fichiers :

  • data sets (MEMTYPE=DATA),
  • vues (MEMTYPE=VIEW) ou
  • catalogues (MEMTYPE=CATALOG),

Cela veut dire que les formats, qui sont toujours sauvegardés dans un CATALOG, sont également supprimés.

3. Par défaut, supprimer les fichiers de la bibliothèque temporaire, LIB=WORK : De plus, par défaut, la bibliothèque est temporaire (LIB=WORK) est concernée.

Un premier exemples : Les deux procédures suivantes donnent le même résultat.

proc datasets kill;
quit;

proc datasets lib=work
memtype=all
kill;
quit;

4. Supprimer l’affichage dans la fenêtre OUTPUT avec l’option NOLIST : Pour éviter un affichage dans la fenêtre OUTPUT, vous pouvez ajouter l’option NOLIST ou encadrer la procédure entre deux instructions ODS :

  • ODS LISTING CLOSE : stopper la redirection par défaut vers la fenêtre OUTPUT
  • ODS LISTING : réactiver la redirection vers la fenêtre OUTPUT

5. Désigner les fichiers à garder ou supprimer par leur nom

Deux instructions, soit DELETE, soit SAVE permettent de se concentrer sur quelques fichiers en particulier à supprimer ou non quand l’option KILL n’est pas présente.

Si le type d’un fichier est différent de la majorité des fichiers listés dans l’instruction DELETE (ou SAVE), le type est à définir entre parenthèse avec le mot-clé MEMTYPE= après son nom.

Un second exemple en deux parties

Dans l’exemple qui suit, deux formats  (GENDER et GRP) créés dans la bibliothèque SASREF et tous les data sets de la bibliothèque SASHELP incluant le data set CLASS y sont également copiés.

libname sasref ‘C:/sasref/blog’;

proc format lib=sasref;
value gender 1=‘Male’
2=‘Female’;
value grp    1=‘Per Protocol (PP)’
2=‘Intent to Treat (ITT)’
3=‘Safety’;
run;

proc copy in=sashelp out=sasref memtype=data;
run;

Par défaut, tous les data sets listés dans l’instruction DELETE sont supprimés. A cela s’ajoute le catalogue contenant le format GRP. Il restera donc le format GENDER et tous les data sets sauf CLASS dans la bibliothèque SASREF.

proc datasets lib=sasref
memtype=DATA;
delete class grp (memtype=catalog);
run;

6. Supprimer un fichier qui n’existe pas

Dans certains cas, le nom des fichiers créés dans un programme varie. A la phase de suppression, le fichier manquant sera assortie d’une note dans la LOG:

NOTE: The file SASREF.GENDRE (MEMTYPE=CATALOG) was not found but appear on a DELETE statement.

Deux options s’offrent à vous pour l’éviter :

  • Ajouter l’option NOWARN : dans l’instruction PROC DATASETS, l’option empêchera l’affichage de la note sur les fichiers manquants.
  • Exécuter l’instruction conditionnellement : identifier les fichiers à supprimer au préalable via les dictionnaires et les stocker dans une macro variable.

NOTE : Sachez que PROC COPY a son équivalent dans la procédure PROC DATASETS. Cela dépasse cependant l’objet de cet article.

h1

4 étapes de base pour créer un data set avec PROC SQL

septembre 18, 2008

La procédure SQL disponible sous SAS est une alternative à l’étape data (data step en anglais) dans de nombreuses situations. La syntaxe est dérivée du langage SQL abbréviation de Structured Query Language. Il s’agit donc de faire une requête (query) auprès de SAS pour extraire une information à partir d’un ou plusieurs jeux de données.

Voici donc ici l’occasion de voir la syntaxe de base pour créer un data set à partir d’un autre data set.

1. Début et fin : les instructions PROC SQL et QUIT.

Pour débuter une procédure SQL, il faut taper une instruction commençant par PROC SQL et finir avec une instruction QUIT (et non RUN). Entre ces deux instructions, une nouvelle instruction créera le nouveau data set.

Il est possible d’avoir autant d’instructions entre PROC SQL et QUIT que voulu. Dans la suite, seul un data set sera créé. Il n’y aura q’une seule instruction.

proc sql;
*instruction 1: créer un premier data set par exemple;
*instruction 2 : créer un second data set par exemple;

quit;

2. Lister les variables après SELECT

Un mot introductif, SELECT : l’instruction centrale débute avec le mot-clé SELECT. A la suite figurent toutes les variables à garder.

La virgule comme délimiteur : A la différence d’un data step, la procédure SQL utilise la virgule et uniquement la virgule comme délimiteur entre les noms de variables.

proc sql;
select age, height, weight
from sashelp.class;
quit;

Renommer une variable avec AS : Au stade de la sélection des variables, il est possible d’assigner un nom différent de celui d’origine en se servant du mot AS.

Dans l’exemple ci-dessous, la variable d’origine s’appelle HEIGHT. Après cette variable s’appelle TAILLE.

proc sql;
select height as taille
from sashelp.class;
quit;

Ajouter des attributs : Dans un data step, les instructions ATTRIB, LABEL, FORMAT, INFORMAT et LENGTH sont disponibles pour définir les attributs d’une variables. Avec PROC SQL, les attributs sont à donner après le nom de chaque variable.

Exemple : Dans cet exemple, toutes les variables reçoivent un label. De plus, la longueur des variables NAME (caractère) et AGE (numérique) sont redéfinies.

proc sql;
select name length=15 label=‘Nom’,
age length=4,
height label=‘Taille’,
weight label=‘Poids’
from sashelp.class;
quit;

Note : Dans un data step, un symbole dollar ($) est obligatoire pour définir la longueur des variables caractères, alors qu’avec PROC SQL, ce symbole n’est pas demandé.

Lister toutes les variables : pour lister toutes les variables du data set source rapidement, le symbole étoile (asterik) fera le travail. Rien n’empêche d’ajouter d’autres variables à la suite.

Exemple : Dans l’exemple ci-dessous, toutes les variables du data set CLASS situé dans la bibliothèque SASHELP sont gardées. De plus, pour chaque observation, une variable EXTRA prend la valeur ‘TEST’.

proc sql;
select *, ‘TEST’ as extra
from sashelp.class;
quit;

3. Définir le data set source avec le mot-clé FROM

Dans chacun des exemples ci-dessus, un data set source a été introduit pas le mot-clé FROM.

4. Assigner un nom de data set avec CREATE

Par défaut aucun data set n’est créé : Avec un data step, il faut dans un premier temps créer le data set pour pouvoir ensuite l’imprimer. Avec PROC SQL, les informations sont automatiquement envoyées dans la fenêtre de destination (OUTPUT par exemple) si aucun nom de data set n’est donné avant la sélection des variables.

La structure de début de l’instruction centrale : Pour donner un nom de data set, il faut commencer l’instruction centrale par :

CREATE TABLE mon_nom_de_table AS…

Pourquoi un mot-clé TABLE ? : La présence du mot-clé TABLE se justifie par le fait que SAS est capable de créer plusieurs types de fichiers : les SAS data sets appelés aussi TABLE, et les VIEW. Pour débuter seules les TABLES nous intéressent, l’usage des VIEW étant beaucoup plus occasionnel.

Par ailleurs, sachez que les options du data set vues dans un data step (DROP, KEEP, RENAME, WHERE…)  s’appliquent également dans la PROC SQL mais seulement une fois le nouveau data set créé. Pour les curieux, il y a l’article « Je garde ou je jette ? les variables« .

proc sql;
create table class (drop=age) as
select *, ‘TEST’ as extra
from sashelp.class;
quit;

Depuis la version SAS 9, SAS demande explicitement d’éviter de créer un data set portant le même nom que le data set source. Si vous le faites, un message apparaîtra dans la log.

WARNING: This CREATE TABLE statement recursively references the target table. A consequence of this is a possible data integrity problem.

h1

Insérer quelques nouvelles observations

juin 9, 2008

Dans l’article ‘Ajouter des lignes en combinant des data sets’, nous avons vu comment ajouter des observations en joignant plusieurs data sets. Ici, il s’agit de voir comment ajouter manuellement un nombre limité d’observations en fin de data set. Deux méthodes sont proposées : un data step avec l’option END= et l’instruction OUTPUT d’une part et l’instruction INSERT INTO de PROC SQL d’autre part.

1. Passer par un data step pour ajouter une ou plusieurs observations

L’instruction SET dispose de l’option END=. Celle-ci permet de définir une nouvelle variable. On peut s’imaginer cette variable comme une variable binaire prenant une valeur zéro pour toutes les observations sauf la dernière. Il est courant de nommer cette variable EOF, acronyme pour END OF FILE (fin de fichier).

Dans un premier temps, toutes les observations sont lues et envoyées dans le data set de sortie avec OUTPUT.

Dans un second temps, on précise à SAS que si notre variable binaire a une valeur de 1, l’observation va être de nouveau envoyée dans le data set final après avoir changé les valeurs de son choix.

Lorsque la valeur prise par la variable binaire n’est pas précisée (if eof then…), SAS assume ‘if eof=1 then…’ ou en d’autres termes ‘si la condition est vraie alors…’. Pour information, l’inverse est ‘if not eof then…’ ou ‘if eof=0 then…’.

data class;
   set sashelp.class end=eof;
   output;
   if eof then
      do;
         name=‘SASREF’;
         sex=‘F’;
         age=18;
         height=.;
         weight=100;
         output;
         name=‘SASREF’;
         sex=‘M’;
         age=.;
         height=.;
         weight=.;
         output;
      end;
run;

Cette méthode reste très contraignante. Car il faut redéfinir tous les champs au risque sinon d’avoir une valeur de l’ancienne observation. La procédure SQL est véritablement conçue pour répondre à notre besoin.

2. L’instruction INSERT de la procédure PROC SQL

Deux syntaxes sont disponibles avec l’instruction INSERT selon qu’on liste seulement les valeurs, mais pour toutes les variables ou qu’on liste à la fois les variables et leur valeurs mais seulement celles qui nous intéresse.

Ma préférence va à la seconde solution, car elle évite des erreurs dans l’ordre d’affichage des valeurs. De plus, lorsqu’on relit un programme, il est facile de faire le lien entre une valeur et la variable à laquelle elle réfère.

 2.1 Lister toutes les valeurs pour une ligne d’observation sans le nom des variables : chaque nouvelle ligne d’observation est introduite par le mot-clé VALUES. Il n’y a donc pas besoin de délimiteur entre chaque ligne d’observation. Toutes les valeurs pour une observation donnée sont listées entre parenthèses et séparées par une virgule.

proc sql;
   insert into class
   values (‘SASREF2’,‘F’,18,.,100)
   values (‘REFSAS2’,‘M’,.,.,.);
quit;

 2.2 Lister les variables qui nous intéressent seulement : chaque nouvelle ligne d’observation est introduite par le mot-clé SET. Comme précédemment, il n’y a pas de délimiteur entre chaque ligne d’observation nouvellement définie. Les variables sont listées dans un ordre quelconque. Les variables non listées prennent une valeur manquante.

proc sql;
   insert into class
   set sex=‘F’, name=‘SASREF3’,age=18,weight=100
   set name=‘REFSAS3’, sex=‘M’;
quit;

Pour plus de précisions sur l’instruction INSERT, vous pouvez vous reporter à  la SAS Online Doc. : Insert Statement.

h1

Mon paramètre de macro est-il rempli ?

mai 18, 2008

Une macro sous SAS peut dans certains cas être comparée à un questionnaire. A chaque question (parameter) correspond plusieurs réponses possibles (parameter value). Certains réponses peuvent êtes obligatoires, d’autres facultatives. Dans le cas où la réponse est impérative mais n’est pas fournie par l’utilisateur, il faut pouvoir l’avertir : arrêter l’exécution du programme de manière propre et l’informer des éléments à fournir. Trois notions de programmation aideront à construire cette vérification (check).

1. Passer un message

Une condition en langage macro : ici, une macro est définie. Des instructions globales sont exécutées, si le paramètre de la macro est vide. Cette condition est donc définie avec une instruction du langage macro %IF … %THEN … %DO; …; %END;

Un message dans la log : l’objectif est d’informer l’utilisateur sur la nécessité d’une valeur pour le paramètre INPUT_VAL. Pour faire apparaître ce texte d’ERREUR dans la log, l’instruction du langage macro %PUT fera le travail.

Pas besoin de guillemets avec %IF ou %PUT : le paramètre d’une macro est une forme de macro variable. Pour retrouver sa valeur, son nom est donc entouré d’un symbole & et d’un point. Si cette valeur doit apparaître dans une chaîne de caractères entre guillemets, il faut impérativement utiliser des guillemets doubles. Dans le cas contraire, comme ici dans une instruction %IF ou %PUT, on se passe de guillemets pour résoudre la macro variable.

%macro test_param (input_val=,output_val=);
%if &input_val. = %then
   %do;
      %put ERREUR: Le macro paramètre INPUT_VAL= est obligatoire;
   %end;
*suite du programme;
%mend test_param;
%test_param (input_val=,output_val=);

Personnaliser son message : quand SAS rencontre une erreur, il utilise le mot ERROR dans la log. Pour distinguer ce message des votre, vous pouvez ajouter un mot-clé comme le nom de la macro. Par exemple : « ERROR – TEST_PARAM: the INPUT_VAL= macro parameter is mandatory. ».

2. Gérer les caractères spéciaux : il est fréquent d’avoir des valeurs autres que les chiffres et les lettres de l’alphabet comme valeur pour un paramètre de macro. Vous aurez souvent besoin de définir l’emplacement des données sources et celui où les outputs seront sauvegardées. Pour cela, les paramètres auront des valeurs du type c:/mon_projet/mesdonnees ou encore c:/mon_projet/mes_resultats. Il existe des macros fonctions : %BQUOTE et %NBRQUOTE pour tenir compte de la barre inclinée (slash) et d’autres caractères spéciaux.

  • %BQUOTE : les symboles suivants sont gérés avec la fonction %BQUOTE() : ‘  » ( ) + – * / < > = ¬ ^ ~ ; , blanc AND OR NOT EQ NE LE LT GE GT
  • %NBRQUOTE : si, en plus, vous avez les symboles & (et) et % (pourcentage), il faudra faire appel à la macro fonction %NBRQUOTE().

SAS online DOC :

  • %BQUOTE et %NBRQUOTE Functions
  • Using the %BQUOTE and %NBRQUOTE Functions

3. Enjamber un programme

Si la condition n’est pas remplie, on peut demander à SAS d’ignorer une partie du code grâce à la syntaxe de %GOTO. Il était également possible de demander à SAS d’arrêter son exécution en plein milieu. Certes, enjamber le code permet d’avoir une log plus propre, puisque seuls nos messages apparaissent. Mais surtout, cela permet de poursuivre l’exécution du programme. Ainsi, si un appel de macro ne fonctionne pas, rien n’empêche de continuer la soumission d’autres appels de cette macro.

Dans un premier temps, il s’agit de définir une balise. A partir de cette position, SAS pourra continuer son exécution. Ici, la balise s’appelle FIN_PGM. Elle est ajoutée juste avant la fin du la macro.

Dans un second temps, si le paramètre est vide, SAS est prié d’ignorer le code qui suit jusqu’à la balise. Pour cela, dans la condition, l’instruction %GOTO est ajoutée.

%macro test_param (input_val=,output_val=);
%if &input_val. = %then
   %do;
      %put ERREUR: Le macro paramètre INPUT_VAL= est obligatoire;
      %goto fin_pgm;
   %end;
*suite du programme;
%fin_pgm:
%mend test_param;
%test_param (input_val=,output_val=);

h1

Produit cartésien : un notion pas si barbare !

mars 13, 2008

jeu_fr.jpg

Enfant, vous avez peut-être joué à ce jeu où les mots d’une colonne sont à relier avec les mots d’une autre colonne. Pour s’amuser, on peut tracer toutes les combinaisons possibles. Avec 4 valeurs à gauche et 3 valeurs à droite, 12 traits sont tracés. 

Le produit cartésien c’est la même chose : créer toutes les combinaisons possibles. Ce mot fait parti du vocabulaire pour combiner deux bases de données.

Proc SQL ou data step ? : Seule la procédure SQL permet de faire cette manipulation occasionnelle. Le MERGE du data step ne peut pas.

1. Un exemple : dans l’exemple ci-dessous, le premier jeu de données a trois lignes d’observations et le second en a deux.

–ONE–
x     y
1    11
2    22
3    33

—–TWO—–
 a    b    c
 9    8    3
99    5    2

Pour chaque ligne du premier jeu, on veut les deux observations du second jeu. Cela donne un nouveau data set avec 3*2 lignes d’observations.

x  y  a b c
1 11  9 8 3
1 11 99 5 2
2 22  9 8 3
2 22 99 5 2
3 33  9 8 3
3 33 99 5 2

2. Une procédure SAS : la procédure SQL liste les variables des deux jeux de données. Le nom des deux data sets  sont séparés pas une virgule.


proc sql;;
   select x, y, a, b, c
   from one, two;
quit;

h1

Le luxe des macros, B.A.BA de la syntaxe

février 18, 2008

voiture_bleue.jpg 

Pour répéter un même programme SAS avec quelques nuances, trois possibilités s’offrent à vous :

  1. la macro,
  2. le data _null_,
  3. le call execute.

Aujourd’hui, je vous propose de voir la notation de base pour la création d’une macro. Pour pouvoir ensuite développer vos propres macros, vous devrez savoir comment résoudre une macro variable.

1. Définition et appel : le minimum

1.1 Encadrer votre programme entre les instructions %MACRO et %MEND : une des caractéristiques du langage macro est l’utilisation du signe pourcentage (%) devant des mots-clés. Ceux qui créent une macro n’échappent pas à la règle. On trouve le %MACRO pour annoncer le début de la définition et le %MEND pour arrêter la définition. Pourquoi le mot %MEND ? M est la référence au mot MACRO et END est le mot FIN en anglais.

%macro;
*mon programme SAS;
%mend;

Important : on s’assurera que la définition de la macro est terminée avant d’en commencer une nouvelle.

1.2 Un nom pour ma macro : il faudra aussi donner un nom à la macro pour pouvoir l’identifier par la suite.

%macro monlisting;
*mon programme SAS;
%mend monlisting;

L’utilisation du nom de la macro en clôture n’est pas obligatoire mais c’est un bon repère dans votre programme.

1.3 Appel de macro : pour appeler votre macro, il vous suffit ensuite de faire précéder le nom de la macro du signe pourcentage.

%monlisting;

2. Imaginez un questionnaire en ligne avec des champs à remplir : parfois une valeur est inscrite par défaut, parfois le texte à remplir est libre ou réduit à un éventail de proposition. Dans notre cas, le champ est un paramètre de la macro. Derrière chacun de ces champs se cache un nom. Il faudra donc donner un nom à ce paramètre. Et enfin, la valeur d’origine est optionnelle. Ces paramètres, qui permettent de nuancer le programme, sont définis dans l’instruction %macro :

%macro monlisting(annee=ALL,imprimer=NO,patient=);

2.1 Utiliser les valeurs par défaut : pour appeler la macro en utilisant les paramètres par défaut, on écrira soit la macro sans paramètres, ou on pourra rappeler les valeurs d’origine pour améliorer la lisibilité, si besoin est.

%monlisting;
%monlisting(annee=ALL,imprimer=NO,patient=);

2.2 Changer les valeurs des paramètres : pour appeler la macro avec une option d’impression différente, le paramètre imprimer sera ajouté :

%monlisting (imprimer=YES);

Important : ici j’ai fait le choix de vous présenter la notation la plus pratique, mais ce n’est pas la seule. Le signe égal est indiqué même si tous les paramètres n’ont pas de valeur par défaut. Ainsi lors de l’appel de macro, on pourra agir sur les paramètres :

  • plus besoin de lister tous les paramètres
  • plus besoin de respecter l’ordre d’origine des paramètres

3. Utiliser les valeurs des paramètres dans le programme : les paramètres d’une macro sont considérés comme des macros variables et rappelés dans le programme comme tels.

h1

3 méthodes pour construire des macros variables sans macro

février 7, 2008

Les macro-variables peuvent être créées soit à l’intérieur d’une macro, soit à l’extérieur. Ici je vous propose de voir comment les créer indépendamment d’une macro. Pour une valeur brute indépendante du reste de votre programme, je vous propose le statement %let. Pour des macros variables définies à partir d’autres informations disponibles dans un jeu de données, vous aurez le choix entre le statement ‘CALL SYMPUT’ dans un data step et le mot clé ‘INTO :’ dans une procédure SQL.

1. Assigner une valeur manuellement : L’instruction %LET sert à définir une macro variable quand vous connaissez la valeur à donner à votre macro variable à l’avance et qu’elle n’est pas fonction de vos données. Tapez la valeur de votre macro-variable. Pour chaque %LET statement une macro variable est créée. Faites suivre %LET du nom de la variable et saisissez sa valeur après le signe égal.

%let projet=53269 ;

2. Créer une macro variable dans un data step : pourquoi vouloir passez par un data step ? Voici deux exemples : assigner la valeur d’une variable automatique comme _N_ ; créer une boucle pour créer autant de macros variables qu’il y a de valeurs distinctes dans une variable.

2.1 La distinction entre CALL SYMPUT et CALL SYMPUTX : les arguments de CALL SYMPUT sont le nom de la macro variable dans un premier temps, et sa valeur dans un second temps. Jusqu’à SAS 8.2, on devait convertir les valeurs numériques en valeur caractères, via la fonction PUT, pour créer la macro variable. Depuis SAS 9, on peut directement utiliser la valeur numérique avec CALL SYMPUTX.

data _null_ ;
   set demo;
   call symputx(‘Nb_boucle’,_N_);
run;

Pourquoi cette nouveauté si tardive ? Parce que la valeur d’une macro variable est toujours caractère. Dans un macro statement tel %if…, vous aurez besoin d’une macro fonction pour faire la somme de deux macro variables. En dehors, vous devrez écrire la macro variable entre double guillemets.

2.2 Un seul CALL SYMPUT(X) et plusieurs macros variables : si vous avez un jeu de données avec deux variables : une contenant le nom de vos futures macro-variables et l’autre leur valeur, vous pouvez avec un seul CALL SYMPUT/SYMPUTX créer toutes les macro-variables. Pour cela, il vous suffit de mettre le nom des deux variables dans les paramètres. Cette fois-ci il n’y a plus de guillemets.

Niveau Dose
Dose1 50
Dose2 100
Dose3 150
call symputx (niveau,dose);

3. Créer une macro variable dans une procédure SQL : Vous pouvez répondre à trois besoins avec PROC SQL : 1) sauvegarder une valeur unique dans une macro variable, comme le nombre total d’observations dans un jeu de données ; 2) sauvegarder toutes les valeurs prises par une variable dans une seule macro variable, en jouant avec SEPARATED BY. 3) créer autant de macro variable qu’il y a de valeurs sélectionnées.

3.1 Une macro variable ayant une seule valeur : pour sauvegarder le nombre d’observations d’un data set dans une variable CNT, vous écririez select count(*) as cnt from demo ; Pour sauvegarder cette information dans une macro variable CNT vous remplacerez ‘AS’ par ‘INTO :’

proc sql;
   select count(*) into : cnt
      from sashelp.class ;
quit;

3.3 Plusieurs macros variables à partir de plusieurs valeurs: la syntaxe suivante permet de créer plusieurs macros variables à partir de plusieurs calculs extraits d’un même data set.

proc sql;
   select distinct count(age), count(*)
              into : cnt_age,
                   : cnt_rec
       from sashelp.class;  
quit;

Si les noms de variables ont un nom schématique (base + nombre incrémenté par 1), la syntaxe suivante peut être appliquée.

proc sql;
   select distinct age into : pop1-:pop6
      from sashelp.class;
quit;

3.4 Plusieurs valeurs dans une seule macro variable: vous pouvez aussi décider de sauvegarder ces cinq valeurs dans une seule macro variable. Ne listez alors qu’un nom. Au moment d’appeler votre macro vous observerez que seule la première valeur apparaît si vous n’avez pas précisez un délimiteur comme un espace ou une virgule entre les observations via SEPARATED BY. Par défaut, le délimiteur est en effet un passage à la ligne. Voici deux exemples :

proc sql;
   select distinct age into : age_space
                            separated by ‘ ‘
      from sashelp.class;
   select distinct age into : age_comma
                           separated by ‘,’
      from sashelp.class;
quit;

 
3.5 La macro variable automatique SQLOBS : Enfin sachez qu’il existe une macro variable automatique SQLOBS qui sauvegarde le nombre d’observation de la dernière procédure SQL. Cette fonction peut s’avérer pratique à condition de bien garder à l’esprit qu’il ne faudra pas par la suite intercaler d’autres SQL statement qui changeraient la valeur de cette macro variable automatique.

3.6 Extra

L’option NOPRINT : Par défaut, les valeurs d’un select statement sont affichées dans la log, si aucun jeu de données n’est crée. Si vous ne souhaitez pas voir la valeur des macros variables s’afficher dans votre log arrêter via l’option NOPRINT :

   proc sql noprint;
      *ma sélection;
   quit;

Important: si aucun record n’est sélectionné avec la PROC SQL, la macro variable n’est pas créée. Dans l’exemple ci-dessous, la macro variable MAX_AGE n’apparaît pas dans la liste des variables de l’utilisateur disponible dans la log.

proc sql noprint;
   select max(age) into : max_age
   from sashelp.class
   where age > 18;
quit;

%put _user_;

4. Supprimer une macro variable globale

Les macros variables globales sont disponibles tout le long de la session. On peut choisir d’écraser la valeur en créant une nouvelle macro variable portant le même nom ou choisir de la supprimer. Dans la version 9.1.3, l’instruction globale %SYMDEL fait supprime les macros variables globales pour vous. Pour ce qui est des variables locales, il n’y a pas d’instructions pour la simple raison que la valeur de la macro variable ne peut pas être rappelée en dehors de la macro.

%symdel cnt cnt_age cnt_rec pop1 pop2 pop3 pop4 pop5 pop6 age_space age_comma;

NOTE : Pour définir une condition basée sur une macro variable, il faut qu’elle existe. Si une macro variable n’est pas créée, faute de valeur à assigner, il est conseillé de définir au préalable une valeur par défaut avec un %LET par exemple. Elle pourra ensuite être actualisée par une des trois méthodes mentionnées ci-dessus. Une autre solution est de s’assurer de l’existence de la macro variable avec la fonction %SYMEXIST.

h1

Un besoin ponctuel de variables macros

janvier 24, 2008

Horloge

Cet article requiert une connaissance préalable de la syntaxe pour créer des macros et des variables macros.

1. Deux types de variables macros utilisateur : lorsque vous définissez un paramètre dans votre macro, vous créez une variable macro. Vous pouvez récupérer la valeur de cette variable macro n’importe où à l’intérieur de votre macro. Vous ne pourrez pas l’appeler en dehors de votre macro par défaut. C’est d’ailleurs ce que vous voulez la plupart du temps. Ainsi vous pourrez redéfinir une variable macro du même nom, plus tard, sans risquer d’utiliser une valeur antérieure. On parle de variable macro locale (local macro variable). Par contre, si vous voulez l’utiliser en dehors de la macro, vous devez clairement le préciser avant de lui assigner une valeur. On parle alors de variable macro globale (global macro variable).

2. Trois mots-clés pour afficher les statuts des variables macros dans la log : %put pour savoir quel statut porte votre variable macro, vous pouvez utiliser le statement propre au langage macro afin de les afficher dans la log. On fera suivre %put des mots-clés suivants :

  • _global_ ou _local_ pour limiter la sélection à un statut donné parmi les macros variables utilisateur,
  • _user_ pour voir toutes macro-variables de l’utilisateur
  • _all_ pour lister toutes les variables macros, y compris celles définies par le système SAS.

3. Changer de statut : pour qu’une variable macro a priori locale soit globale, faites usage du statement propre au langage macro %global suivi du nom des variables séparées par des espaces.

4. Un exemple de variable macro locale : Dans ce premier exemple, la variable macro est créée dans une macro. On appelle la macro et affiche la valeur de la macro variable dans la log via le %put statement inclus dans la macro. Une fois l’appel de macro terminé, on affiche toutes les variables macros pour constater que la macro variable locale n’existe plus.

%macro ex_local(x=);
   %put _all_;
%mend ex_local;
%ex_local;
%put _all_;

5. Un exemple de variable macro globale : dans ce second exemple, la macro variable définie dans la macro est préalablement enregistrée comme globale. On appelle la macro et montre sa valeur grâce au %put statement inséré dans la macro. Après l’appel de macro, on liste toutes les variables macros dans la log pour remarquer que la variable macro qui est globale est toujours présente.

%global y;
%macro ex_global(y=);
   %put _local_;
%mend ex_global;
%ex_global;
%put _all_;