Archive for the ‘Par Etapes’ Category

Passer par un format pour changer les couleurs d’une cellule dans un tableau (PROC REPORT et ODS)
septembre 17, 2009Dans de précédents articles, je vous ai parlé de la possibilité de changer le style des cellules d’un tableau. Je vous invite ici à découvrir comment un format peut vous éviter de passer par un COMPUTE/ENDCOMP de PROC REPORT pour changer le style selon les valeurs prises par une variable donnée.
1. Créer les formats pour l’exemple
Pour mettre en gras (bold) ou non, il faut passer par le style FONT_WEIGHT. Dans notre exemple, ce style prendra la valeur BOLD quand la variable AGE aura des valeurs entre 14 et 16 ans et un LIGHT pour un style non gras. Vous avez aussi à disposition la valeur MEDIUM pour un ton légèrement plus prononcé.
Pour changer la couleur du texte, c’est le style FOREGROUND qu’il faut utiliser. Dans notre cas, le texte aura la couleur bleu si la variable AGE est comprise entre 14 et 16 ans inclus.
proc format;
value age_font 11–13=‘light’
14–16=‘bold’;
value age_color 14–16=‘blue’;
run;
2. Utiliser le format dans PROC REPORT
Pour changer le style d’une colonne en particulier, il suffit d’ajouter style(column)=[…] dans l’instruction DEFINE.
Ici au lieu de donner une couleur à toutes les valeurs avec FOREGROUND= suivi du nom de la couleur, on donne le format AGE_COLOR. qui prendra la valeur BLUE pour les AGE des 14-16 ans.
De manière similaire, l’épaisseur du trait est changée avec FONT_WEIGHT et le format AGE_FONT. défini auparavant.
ods listing close;
ods pdf file=‘C:/sasref/zebre.pdf’;
proc report data=sashelp.class nowd;
columns name age;
define name / display ;
define age / display style(column)=[font_weight=age_font. foreground=age_color.];
run;
ods pdf close;
ods listing;
3. Voir le résultat
Lectures complémentaires
- Alterner les couleurs de fond dans un tableau : une ligne sur deux (PROC REPORT et ODS)
- Changer la couleur d’une ligne ou d’une colonne grâce à PROC REPORT et ODS
- Un moyen simple de changer les couleurs en fonction des valeurs prises par des variables dans un fichier .xls
- Choisir ses couleurs sous SAS
Des questions ? Envoyez votre message sur le forum du blog.

Choisir la police de caractères pour des graphiques SAS
juin 24, 2009La liste des polices de caractères pour construire des graphiques sous SAS a longtemps été très limitée. Depuis SAS a racheté de nouvelles polices se rapprochant des classiques comme Arial. Mais pour l’instant, voici les styles disponibles depuis de nombreuses années. La mise en image de ces polices devrait vous aider à faire un choix plus rapide.
1. Trois fonts avec ses variantes
Ajoutez aux mots CENT, SWISS, ZAPF les lettres
- l pour une version comprimée,
- x pour une version étendue/allongée,
- b (bold) pour mettre en gras,
- i (italic) pour mettre en italic,
- e (empty) pour avoir un un font blanc.
2. Quelques autres styles
A ces trois premières polices s’ajoutent:
- BRUSH,
- SIMPLEX/DUPLEX/COMPLEX/TRIPLEX,
- SCRIPT/CSCRIPT
- GERMAN/GITALIC/OLDENG
- ITALIC/TITALIC

Plusieurs mots d’un paramètre de macro à mettre entre guillemets (%QSYSFUNC, %STR(), TRANWRD)
mai 28, 2009Mettre 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

Les pièges d’Excel : Une colonne sans nom (GETNAME=YES)
mai 24, 2009Lors 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.

Enlever les balises HTML d’un texte (do while et do until)
mai 18, 2009Les balises HTML sont des mots entourés de < et > servant à la mise en forme de pages Internet. Dans l’exemple qui suit le but est d’enlever avec SAS des balises HTML contenues dans une variable appelée DESCRIP au moyen d’une boucle. Cet exemple, basé sur un cas réel, permettra d’illustrer la syntaxe de DO UNTIL et de DO WHILE.
1. La fonction SUBSTR pour enlever un symbole <…>
Pour enlever une balise, je choisis ici de remplacer la chaîne commencant par < et se terminannat par > au moyen de la fonction SUBSTR. Pour ce faire,
- paramètre 1 : donner le nom de la variable en premier
- paramètre 2 : préciser la position du symbole < en second
- paramètre 3 : donner la longueur du texte en calculant le nombre de caractères entre ce symbole de début de balise et celui de fin (position de su symbole de fin > – position du symbole de début < + 1).
data no_tag (drop=tag:);
descrip=‘<p>my text</p>’;
tag_start = index(descrip,‘<‘);
tag_end = index(descrip,‘>’);
substr(descrip,tag_start,tag_end-tag_start+1)=‘ ‘;
run;
Ici le texte à mettre à jour est <p>my text</p>. Cette première étape data remplace la première balise et seulement la première. Pour des raisons de lisibilité, j’ai choisi de créer deux variables intermédiaires qui retourne la position de < (variable TAG_START) et de > (TAG_END) au moyen de la fonction INDEX.
En fin d’étape data, toutes les variables dont le nom commence par TAG sont supprimée grâce à l’option DROP.
2. Répéter l’opération au moyen d’une boucle DO UNTIL
A chaque exécution de la boucle la variable DESCRIP est mise à jour : une balise <…> est enlevée.
La boucle sera exécutée jusqu’à ce qu’aucun symbole < ne soit identifié. En d’autres termes, la boucle sera exécutée jusqu’à ce que la fonction INDEX retourne la valeur zéro.
data no_tag (drop=tag:);
descrip=‘<p>my text</p>’;
do until(index(descrip,‘<‘)=0);
tag_start = index(descrip,‘<‘);
tag_end = index(descrip,‘>’);
substr(descrip,tag_start,tag_end-tag_start+1)=’ ‘;
end;
run;
3. Répéter l’opération au moyen d’une boucle DO WHILE
A chaque exécution de la boucle la variable DESCRIP est mise à jour : une balise <…> est enlevée.
La boucle sera exécutée tant qu’un symbole < sera identifié. En d’autres termes, la boucle sera exécutée tant que la fonction INDEX ne retournera pas la valeur zéro.
data no_tag (drop=tag:);
descrip=‘<p>my text</p>’;
do while(index(descrip,‘<‘) ne 0);
tag_start = index(descrip,‘<‘);
tag_end = index(descrip,‘>’);
substr(descrip,tag_start,tag_end-tag_start+1)=‘ ‘;
end;
run;
Avec DO UNTIL et DO WHILE, il faut faire attention aux boucles infinies. Si la condition pour sortir de la boucle n’est jamais obtenue. L’exécution continue sans fin.
Lectures complémentaires
Sur le blog www.sasreference.fr
- Les deux visages de la fonction SUBSTR
- Mon petit doigt me dit que le mot commence en position 2 (Fonction INDEX)
Online Doc
- DO WHILE Statement
- DO UNTIL Statement

Un premier exemple d’array : changer toutes les variables 1/2 en variable 0/1
mai 11, 2009Imaginez que vous avez dans une table des variables oui/non où 1 représente non et 2 représente oui. Changement de standard oblige, vous devez symboliser les non par un 0 et les oui par un 1.
Si mavariable=1 alors mavariable=0.
Sinon mavariable=1.
Bien sûr, vous pouvez traiter séparément chaque variable. Ce chantier laborieux est remplaçable par une boucle où seul le nom de la variable change à chaque fois. Vous voulez donc effectuer une même opération sur un grand nombre de variables. La syntaxe de l’array est faite pour vous.
1. Un data set pour l’exemple
Voici la table (SAS data set) utilisée pour l’exemple. Elle s’appelle FINAL. Elle est composée d’une variable caractère et de trois variables numériques, toutes des variables binaires de type oui (2)/ non (1).
data final;
input subject $ pregny validny aeny;
datalines;
A 1 2 1
B 1 1 2
C 2 1 2
D 1 2 2
;
run;
Le but sera d’obtenir un data set avec des variables binaires de type oui (1)/ non (0).
subject pregny validny aeny;
A 0 1 0
B 0 0 1
C 1 0 1
D 0 1 1
2. C’est quoi un array ?
Un array est un nom qui désigne une liste de variables. Il est propre à l’étape data.
- Définir un nouvel array : Dans un premier temps, l’array est à créer: Sous un nom de son choix, sont sauvegardés sauvegarde des noms de variables (les éléments de l’array) dont l’ordre est indexé pour pouvoir les désigner de manière individuelle par la suite.
- Appler les variables contenues dans l’array : Dans un second temps, chaque élément de l’array (chaque variable) est appelé/désigné, non pas par son nom, mais par sa position dans l’array.
3. Définir un array
Pour définir un array, il existe l’instruction ARRAY. Elle est composée de trois parties principales et d’un quatrième optionnel.
- le nom de l’array
- le nombre de variables listées (le nombre d’éléments dans l’array)
- le nom des variables
- la valeur des variables (optionel)
Dans l’exemple, j’ai un array nommé NY composé de trois éléments : les variables PREGNY (prenant no/yes), VALIDNY (valid no/yes) et AENY (adverse event no/yes).
data final;
set final;
*array ny {1998:2000} pregny validny aeny;
*array ny {1:3} pregny validny aeny;
array ny {*} pregny validny aeny;
run;
Je vous propose trois alternatives pour la notation. Ma préférence, pour des raisons de simplicité dans ce cas, va au cas numéro trois.
- {1998:2000} Dans le premier cas, la variable PREGNY a pour référence la position 1998, VALIDNY a pour référence la position 1999 et la variable AENY est en position 2000.
- {1:3} Dans le second cas, la numérotation commence à 1 avec la variable PREGNY et se termine à 3 avec la variable AENY.
- {*} Dans le troisième et dernier cas, la numérotation est implicite. Comme précédemment. Elle ira de 1 à 3. SAS se charge de compter le nombre de variables pour savoir la dimension de l’array. Si SAS fait le travail pour nous, pourquoi se priver de ce luxe !
Note : La première syntaxe peut apporter dans certains cas un plus en terme de compréhension. C’est le cas quand le numéro a un lien avec le sens de la variable. Par exemple, les variables RESULT98, RESULT99 et RESULT00 peuvent avoir les positions 1998, 1999 et 2000 et donc avoir un caractère informatif.
4. Appeler un array
Pour appeler un élément d’un array (une variable), il faut donner le nom de l’array suivi de la position de la variable dans l’array. Ainsi :
- ny{1} désigne la variable PREGNY
- ny{2} fait référence à la variable VALIDNY
- ny{3} concerne la variable AENY
data final;
set final;
array ny {*} pregny validny aeny;
*variable PREGNY;
if ny{1}=1 then ny{1}=0;
else ny{1}=1;
*variable VALIDNY;
if ny{2}=1 then ny{2}=0;
else ny{2}=1;
*variable AENY;
if ny{3}=1 then ny{3}=0;
else ny{3}=1;
run;
L’intérêt de cette notation vient dans l’usage d’une boucle où la position de la variable sera automatiquement changé.
data final;
set final;
array ny {*} pregny validny aeny;
do i=1 to dim(ny);*do i=1 to 3;
if ny{i}=1 then ny{i}=0;
else ny{i}=1;
end;
run;
Pour les plus paresseux comme moi, on demandera à SAS de calculer le nombre d’éléments contenus dans l’array (la dimension) au moyen de la fonction SAS propre à l’array DIM().
Je vous proposerai dans les semaines à venir un autre article sur les subtilités de l’array.

Les pièges d’Excel : cellules formatées
mai 6, 2009Voici un des nombreux pièges avec des données Excel (version anglaise) à importer en SAS.
1. Repérer le problème
J’ai récupéré hier des données sous Excel version anglaise.
- Normalement on aurait dû avoir un nombre avec trois décimales.
- Mais, dans les faits, Excel interprétait le point comme un séparateur pour les milliers et non comme le séparateur entre la partie entière et la partie décimale.
Du coup, à l’importation sous SAS, tous les nombres sont des entiers.
2. La raison du problème
Le formatage de la cellule utilisait le point comme séparateur des milliers.
3. Une solution laborieuse et risquée
J’ai converti toutes les cellules en texte et ai manuellement rajouté le séparateur entre partie entière et partie décimale.

Récupérer la valeur d’une option système dans une macro variable, %SYSFUNC(GETOPTION())
avril 30, 2009Les options SAS modifiables au moyen de l’instruction globale OPTIONS peuvent être retrouvées dans une étape data ou autre au moyen de %SYSFUNC(GETOPTION()).
Par exemple, cette semaine, j’ai eu besoin de savoir combien de caractères par ligne je pouvais entrer dans ma sortie (fenêtre OUTPUT). En d’autres termes, je voulais connaître la LINESIZE et en fonction d’elle ajuster les colonnes de mon listing généré au moyen d’un simple PROC REPORT.
1. Lire dans la LOG l’information
L’instruction PROC OPTIONS permet de lister toutes les options dans la fenêtre LOG de SAS. En ajoutant OPTION=, l’affichage est réduit à la seule option LINESIZE.
proc options option=linesize;
run;
Dans notre exemple, l’option LINESIZE est de 91. Jusqu’à 91 caractères pourront être affichés sur une même ligne avec un PROC PRINT ou autre.
LINESIZE=91 Line size for SAS log and SAS procedure output
NOTE: PROCEDURE OPTIONS used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
2. Sauvegarder l’information dans une macro variable
Pour illustrer la syntaxe %SYSFUNC(GETOPTION()), je choisi de sauvegarder l’information dans une macro variable appelée CURRENT_LS. Cette valeur est ensuite affichée dans la LOG au moyen de l’instruction %PUT.
%let current_ls=%sysfunc(getoption(linesize));
%put ¤t_ls.;
Vous pouvez directement inclure %SYSFUNC(GETOPTION()), dans une instruction globale comme TITLE si vous le souhaitez.
La liste des options du système SAS est grande. A vous d’explorer les possibilités que vous offre cette notation.

Parler français : représenter un nombre 100 987,24
avril 18, 2009Selon le pays les nombres sont présentés de manière différente. COMMA et COMMAX sont deux formats utilisés par SAS pour représentés les nombres mais ne s’applique pas au cas français. Vous verrez donc comment créer le format qui vous convient avec l’instruction PICTURE de PROC FORMAT.
1. La différence français/anglais
Les francophones présentent les nombres différemment des anglophones sur deux points.
- Les milliers : Les chiffres des milliers sont séparés par un espace alors que les américains utilisent la virgule
- Les décimales : Les décimales sont séparées par une virgule en français contre un point en anglais
2. La représentation par défaut de SAS
Par défaut, les nombres sous SAS sont simplifiés comme sur une calculatrice.
- Les milliers : le seul séparateur est celui des décimales
- Les décimales : le point fait office de séparateur pour les décimales
Pour une présentation à l’anglais, il faudra appliquer le format COMMA. Il n’existe à ma connaissance qu’une semi version française : le format COMMAX. En effet celui-ci utilise bien la virgule pour séparer les entiers des décimales mais il utilise aussi le point et non le blanc pour séparer les milliers. On préférera donc créer un format avec l’instruction PICTURE.
2. Un exemple
Créer un format : dans le cas présent, les nombres seont affichés jusqu’à 999999,99, en ajoutant un espace entre les milliers et un virgule pour les décimales.
- L’usage du 0 : il n’y aura pas de zéro affiché à l’avant du nombre si celui-ci est plus petit que 100000.
- L’usage du 9 : Les décimales s’afficheront toujours avec deux chiffres après la virgules même si le second chiffre est un zéro.
proc format;
picture commafr other=’000 000,99′;
run;
Appliquer les formats COMMA, COMMAX et format personnel
Dans cette étape data trois variables sont créées chacune avec une observation.
Dans les trois cas, un format avec une extension 9.2 est ajouté de manière permanente. On indique à SAS que le nombre ne dépassera normalement pas 9 caractères dont 2 pour les décimales.
data fr_en;
format eg_english comma9.2
eg_semifrench commax9.2
eg_french commafr9.2;
eg_english=100987.24;
eg_semi_french=100987.24;
eg_french=100987.24;
run;
Voir le résultat
eg_english eg_semifrench eg_french
100,987.24 100.987,24 100 987,24
La variable EG_ENGLISH (exemple, anglais) reçoit, quant à elle, un format COMMA9.2 pour un affichage à l’américaine/l’anglais.
La variable EG_SEMIFRENCH (exemple,respectant partiellement la syntaxe française) reçoit u nformat COMMAX9.2.
La variable EG_FRENCH (exemple, français) reçoit le format créé manuellement COMMAFR9.2 pour un affichage avec un blanc entre chaque groupe de trois chiffres parmi dans la partie entière et deux chiffres pour la partie décimale.
Lectures complémentaires
- Parler français : les heures sous la forme 9h30
- Arrondir ses chiffres avant d’appliquer un format
- Ajouter une date dans un nom de fichier Word, Excel,…
- Afficher 7h30 du matin sous la forme 07:30
SAS Online Doc
- COMMAw.d Format
- COMMAXw.d Format
- PICTURE Statement

Tout sur l’instruction BY
avril 14, 2009Me rendant compte que l’instruction BY pouvait poser des difficultés lorsqu’on débute avec SAS, j’ai décidé de faire le point sur cette instruction.
1. Une instruction locale
L’instruction BY peut servir dans toutes les étapes data et procédures à l’exception de PROC SQL.
2. Un ordre défini par le nom des variables :
L’instruction BY est suivie du nom des variables servant pour le tri.
Dans un premier temps, les observations sont triées selon les valeurs de la première variable citée, ici SEX. Puis, pour chacune des valeurs prises par SEX (M et F), les données sont triées par NAME.
proc sort data=sashelp.class out=class;
by sex name;
run;
3. PROC SORT : le premier usage de l’instruction BY : L’instruction BY est logiquement obligatoire dans un PROC SORT. Sinon SAS ne saurait pas dans quel ordre trier les données. Le mot DESCENDING peut-être ajouté pour préciser un ordre décroissant. Ici les données sont d’abord triées par SEX puis par nom en ordre descendant.
proc sort data=sashelp.class out=class;
by sex descending name;
run;
L’autre manière de trier les données est d’utiliser la procédure PROC SQL.
Idée : Vous aurez souvent un PROC SORT avant d’utiliser l’instruction BY dans une autre procédure ou étape data. Simplifiez-vous la vie en copiant l’insstruction au niveau du PROC SORT et en la collant au niveau de la procédure ou étape data suivante.
4. SAS vous informe si les données ne sont pas triées comme indiqué
L’instruction BY précise à SAS dans quel ordre les données doivent être lues. Si les données ne respectent pas cet ordre, SAS s’arrête et fourni un message d’erreur.
5. L’instruction BY : obligatoire ou optionnelle ?
L’instruction BY est optionelle dans une instruction SET. Utilisée pour empiler les données de deux data sets, elle permettra d’intercaler les observations des deux sources selon leur valeurs au lieu de mettre d’abord toutes les observations du premier data set cité et ensuite toutes les observations du second data set.
L’instruction BY reste pratiquement indispensable avec MERGE puisqu’elle sert à relier les observations de deux data sets par les variables du même nom. Sans elle, les observations du second data set pour les variables du même nom réécrirait sur celle du premier.
L’instruction BY est indispensable avec FIRST et LAST.
6. D’autres usages de l’instruction BY
L’instruction BY peut s’ajouter dans un PROC REPORT. Une option NOBYLINE permettra de changer le titre à chaque nouvelle combinaison de valeurs désignée par l’instruction. Néanmoins la mise à jour du titre par cette approche avec ODS RTF par exemple ne fonctionne pas.
L’instruction BY peut servir dans toutes less procédures (sauf PROC SQL) et notamment dans les procédures statistiques. Voir dans les lectures complémentaire l’usage de l’instruction BY avec PROC FREQ.
Lectures Complémentaires
- Trier les données par ordre croissant et décroissant : PROC SORT et l’instruction BY
- Empiler des data sets : L’instruction BY utilisée avec SET
- La base de la jointure entre deux data sets avec MERGE : l’instruction BY utilisée avec MERGE
- Retrouver la valeur suivante avec LAG et MERGE : un rare cas de MERGE sans instruction BY
- Mettre à jour un data set à partir d’un autre : l’instruction BY avec UPDATE
- Repérer les premiers et derniers records (FIRST/LAST) : l’instruction BY avec FIRST et/ou LAST
- Jongler avec les records grâce aux compteurs : l’instruction BY avec FIRST
- 9 points pour personnaliser ses titres : l’instruction BY utilisée en combinaison avec TITLE
- Faire pivoter un data set : un premier exemple avec PROC TRANSPOSE : l’instruction BY avec PROC TRANSPOSE
- Un tableau à une dimension : PROC FREQ et ODS OUTPUT : l’instruction BY avec PROC FREQ
SAS Online Doc
- BY-Group Processing in SAS Programs

Evaluer le critère performance TEMPS d’un programme (%SYSFUNC, %SYSEVALF)
avril 10, 2009Un 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
- Ajouter une date dans le nom de fichier Word, Excel,…
- Combien d’observations dans mon data set
- Additionner deux macros variables : la fonction %EVAL
- Créer une date SAS de 3 manières
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

Les anniversaires, cela se fête avec SAS
avril 2, 2009Aujourd’hui étant mon anniversaire, je fais la paresseuse et vous communique un petit fichier SAS, reçu ce jour (merci Alex), à faire tourner sous Windows, écouteurs en place, pour la prochaine fois qu’un collègue ou pote qui connaît SAS soufflera ses bougies. Amusez-vous bien !
%let pc=1;
%macro sasreference_fr(note,octave,length);
select(¬e.);
when (‘A’) call sound (55*(2**&octave.),&length.*160*&pc.);
when (‘A#’) call sound (58*(2**&octave.),&length.*160*&pc.);
when (‘Bb’) call sound (58*(2**&octave.),&length.*160*&pc.);
when (‘B’) call sound (62*(2**&octave.),&length.*160*&pc.);
when (‘C’) call sound (65*(2**&octave.),&length.*160*&pc.);
when (‘C#’) call sound (69*(2**&octave.),&length.*160*&pc.);
when (‘Db’) call sound (69*(2**&octave.),&length.*160*&pc.);
when (‘D’) call sound (73.5*(2**&octave.),&length.*160*&pc.);
when (‘D#’) call sound (73.5*(2**&octave.),&length.*160*&pc.);
when (‘Eb’) call sound (78*(2**&octave.),&length.*160*&pc.);
when (‘E’) call sound (82*(2**&octave.),&length.*160*&pc.);
when (‘F’) call sound (87*(2**&octave.),&length.*160*&pc.);
when (‘F#’) call sound (92.5*(2**&octave.),&length.*160*&pc.);
when (‘Gb’) call sound (92.5*(2**&octave.),&length.*160*&pc.);
when (‘G’) call sound (98*(2**&octave.),&length.*160*&pc.);
when (‘G#’) call sound (104*(2**&octave.),&length.*160*&pc.);
when (‘Ab’) call sound (104*(2**&octave.),&length.*160*&pc.);
when (‘R’) call sleep((&length./3)*&pc.,1);
otherwise;
end;
%mend sasreference_fr;
data _null_;
%sasreference_fr(‘C’,3,1);
%sasreference_fr(‘C’,3,1);
%sasreference_fr(‘D’,3,2);
%sasreference_fr(‘C’,3,2);
%sasreference_fr(‘F’,3,2);
%sasreference_fr(‘E’,3,4);
%sasreference_fr(‘R’,3,2);
%sasreference_fr(‘C’,3,1);
%sasreference_fr(‘C’,3,1);
%sasreference_fr(‘D’,3,2);
%sasreference_fr(‘C’,3,2);
%sasreference_fr(‘G’,3,2);
%sasreference_fr(‘F’,3,4);
%sasreference_fr(‘R’,3,2);
%sasreference_fr(‘C’,3,1);
%sasreference_fr(‘C’,3,1);
%sasreference_fr(‘C’,4,2);
%sasreference_fr(‘A’,4,2);
%sasreference_fr(‘F’,3,1);
%sasreference_fr(‘F’,3,1);
%sasreference_fr(‘E’,3,2);
%sasreference_fr(‘D’,3,4);
%sasreference_fr(‘R’,3,2);
%sasreference_fr(‘Bb’,4,1);
%sasreference_fr(‘Bb’,4,1);
%sasreference_fr(‘A’,4,2);
%sasreference_fr(‘F’,3,2);
%sasreference_fr(‘G’,3,2);
%sasreference_fr(‘F’,3,4);
run;
Pour les curieux, je vous invite à consulter les programmes des chansons suivantes suggérées sur le forum de developpez.com :
Les plus téméraires s’intéresserons à la publication « Making Music in SAS« . Vos créations pourront être publiées sur le blog.
A lire aussi www.sasreference.fr :

Copier une table dans une autre bibliothèque (PROC COPY)
mars 28, 2009Lors de ses débuts avec SAS, l’étape data est souvent la méthode utilisée pour créer une table (data set) dans une bibliothèque différente de celle d’origine. Cette approche est tout à fait logique lorsque des modifications sont intervenues sur la table. Par contre, dans le cas d’un copier 1/1, la performance est meilleure avec un PROC COPY car les observations ne sont pas lues.
1. Créer une table SAS, une vue SAS et fichier catalogue pour les formats pour l’exemple
Afin de monter les variantes de la procédure PROC COPY, trois types de fichiers (member type) sont créés dans la bibliothèque WORK:
- une table SAS (data set) nommée DSN
- une vue (view) nommée VIEW NAME
- un format catalog nommé FORMATS par défaut et contenant un seul format ici : NY
data dsn;
x=1;
run;
proc sql;
create view viewname as
select *
from sashelp.class;
quit;
proc format;
value ny 0=’No’
1=’Yes’;
run;
2. Copier tous les trois fichiers SAS dans la bibliothèque SASREF
Par défaut, tous les types de fichiers de la bibliothèque WORK sont copiés dans SASREF
libname sasref ‘C:/sasref’;
proc copy in=work out=sasref;
run;
libname sasref;
3. Ajouter de la flexibilité
Pour ajouter de la flexibilité, vous pouvez limiter le choix
- à un type de fichier : memtype=data, memtype=view ou memtype=catalog
- à des noms de fichiers à sélecionner (instruction SELECT) ou à exclure (instruction EXCLUDE)
proc copy in=work out=sasref; *memtype=data;
*select dsn formats;
*exclude dsn formats;
run;
Rien ne vous empêche d’utiliser plusieurs instructions SELECT (ou EXCLUDE) : une par type de fichiers
proc copy in=work out=sasref;
select dsn / memtype=data;
select formats / memtype=catalog;
run;
4. PROC DATASETS alternative à PROC COPY
Développée plus récemment, la procédure PROC COPY englobe les fonctionnalités de plusieurs procédures et est enrichie de commandes qui lui sont propres.
PROC COPY fait partie des fonctionalités de PROC DATASETS. Par défaut, la bibliothèque de la procédure DATASETS est WORK. Pour la modifier au seul niveau de COPY, ajouter IN= dans l’instruction COPY. Cela aura la priorité sur l’option LIBRARY= de l’instruction PROC DATASETS.
proc datasets; * library=work; *memtype=data;
copy /*in=work*/ out=sasref;
select dsn / memtype=data;
select formats / memtype=catalog;
run;
Lectures complémentaires :
- Modifier un data set sans le lire (formater, renommer, libeller)
- Supprimer un data set en 6 points (PROC DATASETS)
- Supprimer des formats
- Empiler des données
En savoir plus avec la SAS Online Doc :
- The COPY Procedure
- The DATASETS Procedure (l’intruction COPY)
- The DATASETS Procedure for Unix
- The DATASETS Procedure for Windows
- The DATASETS Procedure for z/OS

Parler français : les heures sous la forme 9h30
mars 16, 2009Je vous propose une série d’articles sur la thématique « Parler français avec SAS ». Je reprend les notions du précédent article sur les heures pour nous intéresser à la manière d’ajouter la lettre h séparant habituellement les heures des minutes ? Voici un exemple structuré en 4 parties.
1. L’instruction PICTURE de PROC FORMAT
Ici est créé un format HR_FR au moyant de l’instruction PICTURE dans une procédure PROC FORMAT. Il s’applique à des données exprimant les heures SAS.
proc format;
picture hr_fr other=‘%Hh%0M’ (datatype=time);
run;
2. Créer un data set pour illustrer le sujet
L’étape data crée un data set HEURE_FR contenant une variable DEBUT avec deux observations. Ces records sont des heures exprimées en SAS Time.
data heure_fr;
debut=‘9:05’t;
output;
debut=’14:05′t;
output;
run;
3. Appliquer le format HR_FR à la variable DEBUT
Le temps de la procédure PROC PRINT est ajouté le format HR_FR à la variable DEBUT .
proc print data=heure_fr;
format debut hr_fr.;
run;
4. Voir Le résultat de la procédure PROC PRINT
debut
9h05
14h05
Lectures complémentaires :

Ajouter une date dans un nom de fichier Excel, Word…
mars 12, 2009Sous 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
- Mes premiers pas avec ODS TAGSETS.EXCELXP (Partie 1/3)
- Mes premiers pas avec ODS TAGSETS.EXCELXP (Partie 2/3)
- Mes premiers pas avec ODS TAGSETS.EXCELXP (Parite 3/3)
Les fonctions
Les formats :
Les macros fonctions
- Additionner deux macros variables : la fonction %EVAL (usage de %SYSFUNC)
- Combien d’observations dans mon data set (usage de %SYSFUNC)

Visualiser le contenu d’un catalogue contenant des formats
mars 9, 2009Les formats sont sauvegardés dans SAS dans des fichiers appelés catalogues (format catalog). Par défaut, tous les formats envoyés dans une même bibliothèque sont sauvegardés dans le même catalogue. Deux questions se posent après :
- Comment voir la liste des formats présents dans un catalogue ?
- Comment retrouver le contenu d’un format en particulier ?
1. Créer deux formats dans la bibliothèque SASREF
Pour illuster les deux points qui suivent, sont créés deux formats dans la fichier FORMATS de la bibliothèque SASREF.
- Le premier format est nommé CNTRY et s’applique à des pays. Il s’agit d’un format alphanumérique (s’applique à du texte).
- Le second format NY (No/Yes) est un format numérique.
libname sasref 'C:/sasref'; proc format lib=sasref; value $ cntry 'FR' = 'France' 'DE' = 'Germany' 'UK' = 'United-Kingdom'; value ny 0 = 'Non' 1 = 'Yes'; run;
2. Lister les formats présents dans un catalogue avec PROC CATALOG
La procédure PROC CATALOG a la capacité de lister le nom des formats d’un format catalog.
proc catalog c=sasref.formats; contents stat; run;
3. L’option FMTLIB de PROC FORMAT pour voir le contenu des formats
Pour voir les différentes valeurs prises de tous les formats de SASREF (catalogue FORMATS), l’option FMTLIB est joutée dans une procédure PROC FORMAT.
- Pour ne sélectionner que certains formats en particulier, l’instruction SELECT est à disposition.
- Inversement, l’instruction EXCLUDE permet d’ôter certains formats de l’affichage.
Dans les deux cas, il faudra préciser si les formats concernées sont numérique ou alphanumérique en ajoutant le symbole dollar ($) devant le nom de chaque format alphanumérique.
proc format library=sasref.formats fmtlib; *select $cntry ny; *exclude $cntry ny; run;
Lectures complémentaires :