Par défaut, les résultats des procédures SAS sont affichés dans la fenêtre OUTPUT. Pour convertir ces résultats en tableau SAS (SAS dataset), la syntaxe de l’ODS (Output Delivery System) dispose d’outils appropriés comme les instructions
- ODS TRACE pour identifier une sortie,
- ODS OUTPUT pour rediriger une sortie vers un data set,
- ODS SELECT and ODS EXCLUDE pour choisir les sorties apparaissant dans la fenêtre OUTPUT.
Pour illustrer ce sujet, la procédure PROC MEANS sera utilisée.
Remise dans le contexte :
- Changer l’éditeur pour une présentation plus fine : rediriger vers un document RTF avec ODS RTF s’applique une fois que la formulation nous convient.
- Changer la formulation des informations : le TEMPLATE peut préalablement être modifié pour n’afficher qu’un sous ensemble du résultat par exemple.
- Faire de gros travaux : pivoter un tableau, combiner des résultats entre eux ou encore calculer une valeur à partir des résultats existant fait partie des gros travaux qui nécessitent de passer par un dataset SAS.
1. Identifier le nom des résultats
Pour voir le nom des différentes outputs, entourez votre procédure des instructions ODS TRACE ON/LISTING et ODS TRACE OFF.
- La première instruction demande l’affichage de chacune des noms des sorties.
- L’option LISTING permet d’afficher cette information dans la fenêtre OUTPUT. La destination par défaut est la LOG.
- Enfin, la seconde instruction désactive le traçage.
Premier exemple
ods trace on/listing;
*Exemple 1 : Proc Means;
proc means data=sashelp.class;
var height weight;
run;
ods trace off;
On obtient la sortie de PROC MEANS appelée SUMMARY.
Output Added:
————-
Name: Summary
Label: Summary statistics
Template: base.summary
Path: Means.Summary
————-
Second exemple avec une instruction BY : il est toujours possible d’ajouter une instruction BY dans PROC MEANS.
proc sort data=sashelp.class out=class;
by sex;
run;
ods trace on/listing;
*Exemple 2 : Proc MEANS et l’instruction BY;
proc means data=class;
by sex;
var height weight;
run;
ods trace off;
Il y a plusieurs outputs pour une seule procédure. Les deux sorties ont le même nom (NAME) mais le chemin d’accès (PATH) est différent. On parle de BYGROUP1 et BYGROUP2 pour les distinguer.
Output Added:
————-
Name: Summary
Label: Summary statistics
Template: base.summary
Path: Means.ByGroup1.Summary
————-
Output Added:
————-
Name: Summary
Label: Summary statistics
Template: base.summary
Path: Means.ByGroup2.Summary
————-
2. ODS OUTPUT et PROC MEANS
Dans le premier exemple, un data set EXEMPLE1 est créé à partir de la sortie ONEWAYFREQ de la PROC MEANS appliquée au fichier SASHELP.CLASS.
J’ai choisi d’écrire l’instruction ODS OUTPUT à l’intérieur de la procédure puisqu’elle s’applique uniquement à la procédure mais elle peut être aussi affichée avant la procédure.
Une seule instruction pour plusieurs data sets à créer : Ecrire l’instruction ODS OUTPUT avant la procédure est intéressant si vous générez plusieurs sorties de procédures différentes et voulez lister tous les data sets SAS à créer en une seul instruction ODS OUTPUT.
*Exemple 1 : Proc Means;
proc means data=sashelp.class;
var height weight;
ods output summary=exemple1;
run;
Un fichier brut peu lisible : Après un PROC PRINT sur le data set EXEMPLE1, on découvre un fichier peu lisible dès qu’il y a plus d’une variable.
VName_
Height Height_N Height_Mean
Height 19 62.336842105
Height_
StdDev Height_Min Height_Max
5.1270752466 51.3 72
VName_
Weight Weight_N Weight_Mean
Weight 19 100.02631579
Weight_
StdDev Height_Min Height_Max
22.773933494 50.5 150
Solution, étape 1 : Une solution est de faire un PROC TRANSPOSE pour un résultat sous la forme ci-dessous.
_NAME_ _LABEL_ COL1
Height_N N 19.000
Height_Mean Mean 62.337
Height_StdDev Std Dev 5.127
Height_Min Minimum 51.300
Height_Max Maximum 72.000
Weight_N N 19.000
Weight_Mean Mean 100.026
Weight_StdDev Std Dev 22.774
Weight_Min Minimum 50.500
Weight_Max Maximum 150.000
Dans la sortie brute de l’ODS OUTPUT, les variables commencent soit par HEIGHT, soit par WEIGHT (soit par VNAME ne m’intéresse pas ici). Il s’agit de transposer toutes ces variables. Il faut donc toutes les lister. Par soucis de clarté et de simplicité, on peut faire appel à une version abrégée : la racine commune des variables suivie de deux points.
proc transpose data=exemple1 out=exemple1;
var height: weight:;
run;
Solution, étape 2 : Pour retrouver une présentation semblable à celle d’un PROC MEANS envoyé dans la fenêtre OUTPUT, il faut transposer de nouveau. Auparavant, il faut créer une variable distinguant la variable HEIGHT de la variable WEIGHT.
var_name N Mean Std_Dev Minimum Maximum
Height 19 62.337 5.1271 51.3 72
Weight 19 100.026 22.7739 50.5 150
Créer une variable nommée VAR_NAME prenant soit la valeur HEIGHT soit la valeur WEIGHT.
- La fonction SCAN récupérera, dans une variable nommée VAR_NAME, le premier mot de la variable _NAME_ après avoir précisé que chaque mot est séparé par un trait bas (underscore).
- La longueur de la variable est définie explicitement au cas où certains noms de variables seraient supérieurs à 8 et donc tronqués.
- Cette longueur est définie avant l’instruction SET pour que la variable VAR_NAME apparaisse en premier.
data exemple1 (drop=_name_);
length var_name $12;
set exemple1;
var_name=scan(_name_,1,‘_’);
run;
Il est alors possible de faire pivoter le data set. Une ligne est créée pour HEIGHT et une autre pour WEIGHT, c’est-à-dire pour chaque nouvelle valeur de VAR_NAME. Chaque colonne prend le nom contenu dans la variable _LABEL_.
proc transpose data=exemple1 out=exemple1 (drop=_name_);
by var_name;
id _label_;
run;
L’instruction BY : Dans le cas du PROC MEANS, on ne rencontre pas de difficulté particulière liée à l’instruction BY. Au lieu d’avoir une ligne dans le fichier de sortie, on a autant de lignes que de valeurs dans la variable de l’instruction BY. Dans notre exemple, on a donc deux lignes avec une instruction BY SEX. Vous pouvez retrouver le code pour la transposition en fin d’article pour obtenir la sortie suivante :
Sex=F
var_name N Mean Std_Dev Minimum Maximum
Height 9 60.5889 5.0183 51.3 66.5
Weight 9 90.1111 19.3839 50.5 112.5
Sex=M
var_name N Mean Std_Dev Minimum Maximum
Height 10 63.91 4.9379 57.3 72
Weight 10 108.95 22.7272 83.0 150
3. Sélectionner ou exclure certaines sorties ou toute les sorties (ODS EXCLUDE, SELECT, LISTING)
L’instruction ODS LISTING CLOSE suspend l’envoie de toutes les sorties dans la fenêtre OUTPUT. L’ODS EXCLUDE interrompt un sous-ensemble ou toutes les sorties générées par la procédure. A l’inverse, l’ODS SELECT retient les sorties. A vous de voir si vous avez plus vite fait de lister les sorties à garder ou celles à exclure.
Quelques sorties : Pour sélectionner ou exclure quelques sorties en particulier, il suffit d’ajouter leur nom, trouvés au préalable avec ODS TRACE ON, séparé par un espace dans l’instruction. Cela est pratique pour des procédures générant beaucoup de sorties comme PROC UNIVARIATE.
Toutes les sorties : Pour faire la même chose sur toutes les sorties, on utilise ALL et NONE avec ODS EXCLUDE et ODS SELECT.
*Exemple 1 : Proc Means;
ods exclude all; *ods select none; *ods listing close;
proc means data=sashelp.class;
var height weight;
ods output summary=exemple1;
run;
ods exclude none; *ods select all; *ods listing;
Note : Toutes les explications couvertes dans cet article s’appliquent aussi à la procédure PROC SUMMARY.
Annexe : Détails du programme s’appliquant au second exemple
*Exemple 2 : Proc MEANS et l’instruction BY;
proc sort data=sashelp.class out=class;
by sex;
run;
proc means data=class;
by sex;
var height weight;
ods output summary=exemple2;
run;
proc transpose data=exemple2 out=exemple2;
by sex;
var height: weight:;
run;
data exemple2 (drop=_name_);
length var_name $12;
set exemple2;
var_name=scan(_name_,1,‘_’);
run;
proc transpose data=exemple2 out=exemple2 (drop=_name_);
by sex var_name;
id _label_;
run;
proc print data=exemple2 noobs;
by sex;
run;