Posts Tagged ‘select’

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

Diriger les sorties d’un PROC MEANS dans un dataset SAS

juillet 24, 2008

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;

h1

Penser conditionnel (2/3) : SELECT

juin 26, 2008

Pour dire à SAS quelles actions sont à mener si des critères sont remplis, nous avons vu la syntaxe IF/THEN/ELSE (voir article). Dans un data step, l’alternative à cette syntaxe, SELECT WHEN, fait l’objet du présent article.

1. La syntaxe de base

Toutes les conditions sont englobées entre l’instruction SELECT et l’instruction END.  Chaque condition est introduite par l’instruction WHEN. Les observations non sélectionnées avant la fin sont traités par l’instruction OTHERWISE.

A la différence de la syntaxe IF/THEN :

  • Les conditions sont listées entre parenthèses et aucun mot-clé n’introduit l’action.
  • Si toutes les conditions se basent sur une seule variable, celle-ci peut-être citée une seule fois et ce en tout début dans l’instruction SELECT. Mais il faut aussi que les valeurs prises par la variable soient toutes listées. Ainsi <5 ne marche pas mais 0,1,2,3,4 marche.

De la même manière que IF/THEN :

  • Seuls les records non sélectionnés pas un précédent WHEN sont considérées par les conditions suivantes. C’est le même principe que le ELSE IF.
  • Si plusieurs actions sont planifiées, celles-ci sont listées entre un DO et un END.

select  <nom_variable, optionnel> ;
when (<condition>)
do;
<action 1>;
<action 2>;
*etc;
end;
when (<condition>)  <action>;
otherwise <action>;
end;

2. Le caractère unique du SELECT WHEN

Pas d’action s’il vous plaît : Lorsqu’il n’y a aucune action pour une condition donnée, il est possible d’écrire une instruction WHEN sans donner de détails après la parenthèse. On parle d’instruction nulle.

OTHERWISE est parfois obligatoire : Si aucune condition n’est rempli pour un data set donné, il est important d’avoir une instruction OTHERWISE. Celle-ci peut rester vide d’action.

3. Illustration par un exemple

Premier exemple : les trois caractéristiques de ce premier exemple sont les suivantes.

  • La condition est basée sur une seule variable. On choisit dont de nommer une seule fois cette variable dans l’instruction SELECT.
  • Il y a plusieurs actions (DO/END) pour certaines conditions.
  • Dans le cas où aucune des conditions précédentes ne serait remplie, l’instruction OTHERWISE est ajoutée.

Les records incluant un âge manquant sont sauvegardées dans le data set nommé MISS_AGE et la  date de création d’une requête (query) pour clarifier le record est ajoutée dans une variable QUERY_SDT (Query Starting Date). Les autres records, traitant des moins de 5 ans, sont sauvegardés dans le data set YOUNG.

data miss_age young ;
set sashelp.class;
select (age);
when (.)
do;
query_sdt=mdy(3,26,2008);
output miss_age;
end;
when (0,1,2,3,4) output young;
otherwise;
end;
run;

Second exemple : cet exemple se distingue sur trois aspects.

  • La condition est basée sur plusieurs variables. Il faut dont les lister à chaque nouvelle instruction WHEN.
  • Une seule action n’est donnée à chaque fois voir moins. L’action porte sur la valeur de la variable POP. Il n’y a pas d’action quand l’âge n’est pas une valeur connue ou que le sexe n’est pas défini par les lettres majuscules F (female) ou M (male).
  • Les valeurs restantes se rapportent aux hommes ayant une valeur pour leur âge. C’est notre troisième population.

data pop;
set sashelp.class;
select;
when (age > 13 and sex=‘F’) pop = 1;
when (age >= 0 and sex=‘F’) pop = 2;
when (age < 0 or sex not in (‘F’,‘M’));
otherwise pop = 3;
end;
run;

A dans huit jours pour une présentation du CASE WHEN de la procédure SQL.