Archive for the ‘proc print’ Category

Je garde ou je jette? les variables
août 25, 2008Pour garder ou supprimer sous SAS des variables, il y a les mots-clés KEEP (garder) et DROP (enlever). Sélectionner les variables nécessaires par la suite et seulement celles-ci est très important. Cela fait partie des outils pour améliorer la performance d’un programme tant en terme de temps d’exécution que le volume demandé pour stocker les data sets. Voici plus en détails, et avec des exemples, l’utilisation de ce vocabulaire qui s’applique au data step, aux procédures et à la syntaxe de l’ODS OUTPUT.
1. L’option dans un data step
Les mots KEEP et DROP servent principalement en tant qu’option appliquée à un data set donné. Elles sont alors listées juste après le nom du data set entre parenthèses et sont suivies du signe égal :
- Keep= Data Set Option : nom_du_dataset (keep=nom_var1 nom_var2 etc)
- Drop= Data Set Option : nom_du_dataset (drop=nom_var1 nom_var2 etc)
Exemple 1 : une instruction SET
data class (drop=weight: height:);
set sashelp.class (keep=name weight height);
weight_kg = weight*0.45359237;
height_m = height*0.0254;
bmi = weight_kg/height_m**2;
run;
Dans le cas présent, les variables NAME (nom), WEIGHT (poids) et HEIGHT (taille) sont lues dans le fichier d’origine SASHELP.CLASS et gardées. De nouvelles variables sont calculées pour avoir un poids en kilogramme (WIEGHT_KG) et une taille en mètres (HEIGHT_M). A partir du poids et de la taille, l’indicateur de masse corporelle (BMI) est calculé. Les variables, dont le nom commence par WEIGHT et HEIGHT, ne sont plus nécessaires par la suite. Elles sont donc supprimée dans le data set final appelé CLASS.
Soit le mot KEEP, soit le mot DROP est donné en option mais pas les deux afin d’éviter les confusions. Le choix entre KEEP et DROP dépend souvent du nombre de variables à lister par la suite. C’est donc un choix purement pratique.
Note, Indice de masse corporelle : L’indice de masse corporel (Body Mass Index, BMI) est égal au poids divisé par la taille au carré (poids/taille2). Le site de l’Organisation Mondiale de la Santé (World Health Organisation, WHO) donne des précisions sur le sujet.
Note, Conversion des unités de mesures (source Wikipedia) : je suppose que la taille donnée dans le fichier SASHELP.CLASS est exprimée en pouces (inches) et que le poids est exprimé en livres (pounds). Sachant qu’un pouce est égal à 2,54 cm et qu’une livre est égale à 0,45359237 kg, les tailles et poids du premier exemple ont pu être convertis en mètres et kilos.
Exemple 2 : une instruction MERGE
data age_ae;
merge ae (in=ref keep=name ae_id ae_sev)
patient (keep=name age);
by name;
if ref;
run;
Dans ce second exemple, les patients ayant eu un effet secondaire (adverse event, AE) sont enregistrés dans le data set AE. Chaque effet secondaire est identifié de manière unique par les variables NAME et AE_ID. La sévérité de l’effet secondaire nous intéresse dans le data set AE.
A cette information, est ajouté l’âge du patient disponible dans la variable AGE du data set PATIENT.
La variable commune aux deux data sets est NAME. Il faut donc qu’elle reste dans les deux data sets. Seuls les patients ayant eu un effet secondaire sont sélectionnés grâce à l’option IN.
Pour tester l’exemple, vous trouverez en fin d’article un code créant les fichiers PATIENT et AE.
NOTE : Une variable utilisée par une autre option du data set comme RENAME ou WHERE ne pourra pas être supprimée au même moment.
2. Quelques exemples de procédures
Dans une procédure, elles suivent le nom du data set d’entrée et/ou du data set de sortie. Aucun autre mot ne doit être inséré entre le nom du data set et les options entre parenthèses.
- proc sort data=… () out=…();
- proc print data=… () width=min;
- proc transpose data=…() out=…() prefix=visit;
- proc freq data=…();
- proc report data=…() split=’#’;
- proc tabulate data=…()
- proc gplot data=…()
- proc boxplot data=…()
- proc univariate data=…()
- proc ttest data=…()
- etc.
La procédure SQL liste les variables à garder après le mot SELECT. Il n’y a pas à ce stade d’option pour supprimer les variables. Par contre, on peut affiner la sélection après que le data set final soit créé. Bien sûr, le temps de lecture est augmenté puisque toutes les variables sont lues pour créer le data set et non un sous-ensemble.
proc sql;
create table test (drop=ae_sdt ae_edt) as
select a.*, age
from ae a
left join
patient b
on a.name=b.name;
quit;
NOTE : L’option WHERE est très pratique lorsqu’on en peut faire une sélection que sur le résultat de la fusion.
proc sql;
create table test (where=(ae_sev=1 or age=12)) as
select a.*, age
from (select name, ae_id, ae_sev
from ae) a
left join
(select name, age
from patient) b
on a.name=b.name;
quit;
3. L’option dans l’ODS OUTPUT
Les sorties générées par une procédure sont redirigeables vers un data set via l’instruction ODS OUTPUT. Le nom de la sortie est alors suivi du signe égal et du nom du data set de destination. Après ce nom les options sont ajoutables.
ods exclude all;
ods output onewayfreqs=exemple_ods (keep=age frequency percent);
proc freq data=sashelp.class;
table age;
run;
ods output clear;
ods exclude none;
Deux articles sur l’ODS OUTPUT sont déjà à votre disposition
- Un tableau à une dimension avec PROC FREQ et l’ODS OUTPUT
- Diriger les sorties d’un PROC MEANS dans un data set SAS
4. Les instructions KEEP et DROP dans un data step
En plus des options KEEP et DROP, il existe les instructions KEEP (KEEP Statement) et DROP (Drop Statement) pouvant être exécutées dans un data step. L’important ici est de se souvenir que l’instruction s’applique à la fin du data step, une fois que le data set final est créé. Ainsi il n’est pas possible de supprimer une variable en milieu de programme pour ensuite créer une autre variable du même nom.
data class (drop=i);
do i=0 to 3;
output;
end;
do i=10 to 12;
output;
end;
run;
data class;
do i=0 to 3;
output;
end;
drop i;
do i=10 to 12;
output;
end;
run;
Les deux exemples ci-dessus font le même travail. La variable I n’apparaîtra pas dans le data set final car elle est supprimée en fin de programme.
Lectures complémentaires : Outre les options KEEP et DROP, le programmeur utilisera souvent les options RENAME et WHERE et de temps en temps les options FIRSTOBS et OBS. Pour une liste complète des options, consultez la documentation en ligne : SAS Data Set Option.
Après savoir comment supprimer les variables et donc les colonnes d’un data set SAS, vous serez peut-être intéressé de savoir comment supprimer ou garder certaines lignes d’un data set avec les mots-clés DELETE (DELETE Statement) et OUTPUT (OUTPUT Statement).
Annexe : Créer les data sets PATIENT et AE pour tester l’exemple avec MERGE.
data patient;
set sashelp.class;
run;
data ae;
set sashelp.class (keep=name);
if name=‘Thomas’ then
do;
ae_id = 1;
ae_sdt = ’21MAR2007’d;
ae_edt = ’28APR2007’d;
ae_sev = 3;
output;
ae_id = 2;
ae_sdt = ’03JUN2007’d;
ae_edt = ’19JUN2007’d;
ae_sev = 1;
output;
end;
run;

Diriger les sorties d’un PROC MEANS dans un dataset SAS
juillet 24, 2008Par 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;