Archives pour juillet 2008

h1

Un tableau à une dimension avec PROC FREQ et ODS OUTPUT

juillet 31, 2008

Pour personnaliser une sortie statistique générée par une procédure SAS, il faut parfois convertir ses résultats en tableau (SAS data set). Dans un précédent article, la procédure PROC MEANS a été mise à l’honneur (Diriger la sortie d’un PROC MEANS dans un dataset SAS). Maintenant nous abordons la procédure PROC FREQ dans le cadre d’un tableau à une dimension en combinaison avec l’instruction ODS OUTPUT.

1. Identifier le nom des sorties : un exemple avec une variable

ods trace on/listing;

*Exemple 1 : Proc Freq, une variable;
proc freq data=sashelp.class;
   table age;
run;

ods trace off;

On obtient deux types de tables selon qu’il s’agisse d’un tableau à une dimension ou à plusieurs dimensions.

  • OneWayFreqs: Dans le cas d’un PROC FREQ avec une seule variable, on parle de OneWayFreqs.
  • CrossTabFreqs: Dans le cas d’un tableau croisé, la sortie se nomme CrossTabFreqs.

Output Added:
————-
Name: OneWayFreqs
Label: One-Way Frequencies
Template: Base.Freq.OneWayFreqs
Path: Freq.Table1.OneWayFreqs
————-

1. Identifier le nom des sorties : un exemple avec 2 variables

Dans ce second exemple, deux variables (AGE et SEX)  sont listées. Les statistiques de l’une seront indépendantes des statistiques de l’autre.

ods trace on/listing;

*Exemple 2 : Proc Freq, deux variables;
proc freq data=sashelp.class;
   table age sex;
run;

ods trace off;

Pour distinguer les statistiques de la table SEX de celles de la table AGE, deux outputs sont créés dans la fenêtre OUTPUT. Leur nom (NAME) est identique mais leur chemin d’accès (PATH) varie. On parle de TABLE1 et TABLE2.

Output Added:
————-
Name: OneWayFreqs
Label: One-Way Frequencies
Template: Base.Freq.OneWayFreqs
Path: Freq.Table1.OneWayFreqs
————-

Output Added:
————-
Name: OneWayFreqs
Label: One-Way Frequencies
Template: Base.Freq.OneWayFreqs
Path: Freq.Table2.OneWayFreqs
————-

3. Identifier le nom des sorties : un exemple avec une instruction BY

Avant de se servir d’une instruction BY, les données doivent être triées. La procédure PROC SORT le fait. 

Le data set source est un data set non modifiable. C’est un data set de la bibliothèque SASHELP fournit avec le logiciel SAS.

La version triée est sauvegardée de manière temporaire dans la bibliothèque WORK (bibliothèque par défaut quand son nom n’est pas cité). Ce nouveau dataset s’appelle CLASS.

proc sort data=sashelp.class out=class;
   by sex;
run;

ods trace on/listing;

*Exemple 3 : Proc Freq, une variable et une instruction BY;
proc freq data=class;
   by sex;
   table age;
run;

ods trace off;

Avec une instruction BY, il y a plusieurs outputs pour une seule procédure dans la fenêtre OUTPUT. Les deux sorties ont le même nom (NAME) mais le chemin d’accès (PATH) est différent. On parle de TABLE1 dans les deux cas et de BYGROUP1 et BYGROUP2 pour les distinguer.

Output Added:
————-
Name: OneWayFreqs
Label: One-Way Frequencies
Template: Base.Freq.OneWayFreqs
Path: Freq.ByGroup1.Table1.OneWayFreqs
————-

Output Added:
————-
Name: OneWayFreqs
Label: One-Way Frequencies
Template: Base.Freq.OneWayFreqs
Path: Freq.ByGroup2.Table1.OneWayFreqs
————-

4. ODS OUTPUT et PROC FREQ

L’instruction ODS OUTPUT convertit les sorties dans un data set SAS. Voici donc le résultat de trois PROC PRINT sur les data sets créés avec l’instruction ODS OUTPUT.

4.1 Exemple 1, tableau avec une variable

Dans ce premier exemple, on note, d’une part, la présence de la variable caractère TABLE ; d’autre part, deux variables listent les différentes valeurs prises par la variable AGE : l’une est caractère, l’autre est numérique.

*Exemple 1 : Proc Freq, une variable;
proc freq data=sashelp.class;
   table age;
   ods output onewayfreqs=exemple1;
run;

                                         Cum      Cum
Table     F_Age Age Frequency Percent Frequency Percent

Table Age   11   11     2      10.53       2      10.53
Table Age   12   12     5      26.32       7      36.84
Table Age   13   13     3      15.79      10      52.63
Table Age   14   14     4      21.05      14      73.68
Table Age   15   15     4      21.05      18      94.74
Table Age   16   16     1       5.26      19     100.00

4.2 Exemple 2, tableau avec deux variables

En ajoutant une deuxième variable SEX, des variables supplémentaires sont ajoutées dans la table de sortie. Elles listent les valeurs prises par la variable supplémentaire. Comme précédemment avec la variable AGE, il y a deux variables pour accéder à la fois à l’information sous forme caractère et sous forme numérique a priori. Mais comme ici la variable d’origine est caractère, les deux sont de type caractère.

*Exemple 2 : Proc Freq, deux variables;
proc freq data=sashelp.class;
   table age sex;
   ods output onewayfreqs=exemple2;
run;

                                        Cum      Cum
Table    F_Age Age Frequency Percent Frequency Percent F_Sex Sex

Table Age  11   11     2      10.53        2     10.53
Table Age  12   12     5      26.32        7     36.84
Table Age  13   13     3      15.79       10     52.63
Table Age  14   14     4      21.05       14     73.68
Table Age  15   15     4      21.05       18     94.74
Table Age  16   16     1       5.26       19    100.00
Table Sex        .     9      47.37        9     47.37    F   F
Table Sex        .    10      52.63       19    100.00    M   M

4.3 Exemple 3, tableau avec une instruction BY

Avec l’instruction BY, une seule variable est créée pour distinguer les âges des hommes de ceux des femmes.

*Exemple 3 : Proc Freq, une variable et une instruction BY;
proc freq data=class;
  
by sex;
  
table age;
run;

                                             Cum      Cum
Sex   Table   F_Age Age Frequency Percent Frequency Percent

  Table Age   11   11     1      11.11      1      11.11
 F  Table Age   12   12     2      22.22      3      33.33
 F  Table Age   13   13     2      22.22      5      55.56
 F  Table Age   14   14     2      22.22      7      77.78
 F  Table Age   15   15     2      22.22      9     100.00
 M  Table Age   11   11     1      10.00      1      10.00
 M  Table Age   12   12     3      30.00      4      40.00
 M  Table Age   13   13     1      10.00      5      50.00
 M  Table Age   14   14     2      20.00      7      70.00
 M  Table Age   15   15     2      20.00      9      90.00
 M  Table Age   16   16     1      10.00     10     100.00

NOTE : Dans le cas de l’utilisation de plusieurs PROC FREQ se servant du même OUTPUT (onewayfreqs par exemple), il est conseillé de nettoyer l’ODS OUTPUT avec l’option CLEAR.

ods output clear;

h1

9 points autour de la notion d’octet

juillet 28, 2008

L’octet (byte en anglais) est une unité de mesure informatique utilisée en SAS pour définir la longueur des variables. Il permet de stocker 1 caractère parmi une liste de 256. Une des listes de caractères les plus répandue est la table des ASCII (American Standard Code for Information Interchange). SAS dispose de deux fonctions RANK et BYTE pour passer d’un nombre à un de ces caractères et inversement. Ces notions sont à découvrir ou redécouvrir sous la forme de 9 points.

1. Des notions mathématiques mises à la sauce informatique

Deux valeurs possibles avec les booléens : Les booléens (boolean) sont des valeurs égales à 0 ou à 1. C’est une notation mathématique. On parle souvent de la logique des booléens. L’interprétation de ces valeurs est :

  • 0 pour faux (false)
  • 1 pour vrai (true)

En SAS, les syntaxes FIRST/LAST et END= du data step se servent de la logique des booléens.

Le bit est l’unité informatique de base : L’unité de mesure élémentaire en informatique, le bit (bit en anglais également) est basé sur le même principe. Le bit prend soit la valeur 0, soit la valeur 1.

L’octet est un groupement de 8 bits : Un octet (byte en anglais) est égal à la combinaison de 8 unités élémentaires, de 8 bits.

2. Le but du jeu

En informatique, le but du jeu est de n’utiliser que des valeurs 0/1 pour faire référence à des nombres entiers. Pour avoir un éventail de nombre entier assez large, il faut donc plusieurs bits.

Ensuite, pour chaque nombre entier une valeur peut être assignée. Par exemples, les nombres allant de 0 à 255 servent dans une table de référence pour les caractères, la table des ASCII.

3. Combien de valeurs différentes sont extraites avec x bits ? 

Tout d’abord, les bits sont mis les uns à la suite des autres.

  • Avec 1 bit : le bit prend soit la valeur 0 soit la valeur 1.
  • Avec 2 bits : les valeurs de 2 bits s’arrangent de 4 manières différentes à savoir 00, 01, 10 ou 11.
  • Avec 3 bits : les valeurs de 3 bits peuvent se présenter de 8 manières possibles 000, 001, 010, 011, 100, 101, 110, 111.

Généralisation : Pour savoir combien d’arrangements de 0 et 1 sont possibles, le nombre 2 (nombre de valeurs possibles dans un bit) est multiplié autant de fois qu’il y a de bits, soit 2x. En termes mathématiques, on parle du nombre d’arrangements avec répétition. Il s’agit bien du calcul avec répétition car les valeurs 0 et/ou 1 peuvent apparaître plusieurs fois.

Ecrire un exposant sous SAS : Pour mettre une valeur en exposant sous SAS, on fait suivre la base de 2 étoiles et de l’exposant. Voici un exemple pour une variable nommée EXPOSANT.

  • En langage mathématique : exposant=28
  • Sous SAS : exposant=2**8;

4. Quelle position pour mon bit ?

On commence par regarder celui qui est le plus à droite et on lui assigne la position 0. Celui qui suit aura une position 1, etc.

  • Avec 1 bit : le bit est en position 0.
  • Avec 2 bits : le premier bit est en position 1, le second en position 0.
  • Avec 3 bits : le premier bit est en position 2, le second en position 1 et le dernier en position 0.
  • Etc.

5. Création d’une liste de valeurs

Maintenant que la position (x) de chaque bit est connue, on va additionner des valeurs 2x à chaque fois que le bit est égal à 1. Voici donc quelques exemples avec 1, 2 et 3 bits. D’un côté, on a l’arrangement des bites, de l’autre la valeur que l’on peut en extraire.

Avec 1 bit, les valeurs finales sont entre 0 et 1.

  • “0″ : 0
  • “1″ : 20 = 1

Avec 2 bits, les valeurs finales sont entre 0 et 3.

  • “00″ : 0 + 0 = 0
  • “01″ : 0 + 20 = 0 + 1 = 1
  • “10″ : 21 + 0 = 2 + 0 = 2
  • 11″ : 21 + 20 = 2 + 1 = 3

Avec 3 bits, les valeurs finales sont entre 0 et 7.

  • “000″ : 0 + 0 + 0 = 0
  • “001″ : 0 + 0 + 20 = 0 + 0  + 1 = 1
  • “010″ : 0 + 21+ 0 = 0 + 2 + 0 = 2
  • “011″ : 0 + 21+ 20 = 0 + 1+ 2 = 3
  • “100″ : 22 + 0 + 0 = 4 + 0 + 0 = 4
  • “101″ : 22 + 0 + 20 = 4 + 0 + 1 =5
  • “110″ : 22 + 21 + 0 = 4 + 2 + 0 = 6
  • 111″ : 22 + 21+ 20 = 4 + 2 + 1 = 7

Avec 8 bits (1 octet) les valeurs vont de 0 à 255. Comme indiqué précédemment ces nombres servent pour la table des ASCII.

6. La table des ASCII et les fonctions RANK/BYTE

La table des ASCII regroupe les caractères en trois groupes :

  • 0-31 : les codes de contrôle (control code) comme “passage à la ligne”
  • 32-127 : les caractères imprimables (printable characters)
  • 128-255 : les caractères spéciaux (special characters) comme é, à, û…

Note pour les claviers étrangers : La liste des caractères spéciaux est pratique à l’étranger lorsqu’un clavier d’ordinateur ne dispose pas des accents. Ainsi pour obtenir la lettre “é”, maintenez la touche “Alt” enfoncé et tapez le nombre 0233. Voici ceux que j’utilise le plus souvent :

  • 0224 à
  • 0226 â
  • 0231 ç
  • 0233 é
  • 0234 ê
  • 0235 è
  • 0238 î
  • 0244 ô
  • 0249 ù
  • 0251 û

Exemples d’applications : Dans le cadre des fonctions SAS, je vais me concentrer sur les valeurs 32 à 255 car ce sont les valeurs que j’ai rencontré dans des data sets SAS. J’ai aussi eu besoin de vérifier qu’une macro pouvait toujours fonctionner quand elle rencontrait ces caractères dans un data set. Pour se faire, j’ai eu besoin de créer un data set les contenant.

7. Convertir un nombre en caractère (la fonction BYTE)

Dans cet exemple, la fonction BYTE génère toutes les valeurs ASCII imprimables et les sauvegarde dans une variable ASCII. Pour ce faire, une boucle est construite avec les instructions DO et END. C’est l’occasion d’introduire rapidement sous forme d’exemple la notion de boucle.

data one (drop=i);
   do i=32 to 127;
   *do i=128 to 255;
      ascii=byte(i);
      output;
   end;
run;

La boucle est définie par variable i allant de 32 à 128 (et non 127) mais l’action est conduite seulement pour les valeurs 32 à 127. Les valeurs intermédiaires sont distantes d’une valeur 1 car l’incrémentation par défaut est 1. Pour changer cette valeur par défaut et disons prendre une valeur sur deux, on ajoute BY 2 dans l’instruction DO.

A chaque fin de boucle i est incrémenté par 1. Quand i=127, la valeur est calculée une dernière fois. Puis i est incrémenté  par 1. Avec i=128, la condition n’est plus remplie. Le contenu de la boucle est ignoré. SAS s’intéresse à l’étape suivante dans le data step. Ici l’étape suivante est la suppression de la variable i définissant la boucle.

A chaque nouvelle valeur de la variable i, la variable ASCII est recalculée. Puis le record est ajouté dans le data set ONE grâce à l’instruction OUTPUT.

8. Convertir un caractère ASCII en nombre (la fonction RANK)

Dans cet exemple, la fonction RANK retourne la valeur numérique de la table ASCII pour la lettre “é”. Cette valeur est sauvegardée dans la variable VAL_NUM.

data two;
   val_num=rank(‘é’);
run

9. Les multiples des octets dans le commerce

Dans le monde des disques durs…, et taille de fichiers…., vous entendez couramment parler de :

  • Kilooctet ou Ko (Kilo Byte KB en anglais),
  • Megaoctet ou Mo (Mega Byte MB),
  • Gigaoctet ou Go (Giga Byte GB),
  • Teraoctet ou To (Tera Byte TB).

A l’avenir, on entendre peut-être même parle de :

  • Petaoctet ou Po (Peta Byte PB),
  • Exaoctet ou Eo (Exa Byte EB),
  • Zebioctet ou Zo (Zebi Byte ZB),
  • Yobioctet ou Yo (Yobi Byte YB).

La Commission Electrotechnique International (International Electrotechnique Commission IEC) a développé un standard se basant sur des multiples de 10 de l’octet. Cependant, l’ancien standard peut encore être rencontré.

  • Nouveau standard : un Kilooctet est 1 000 octets (103). Un Megaoctet est 1 000 000 (106).
  • Ancien standard : un Kilooctet représente 1 024 octets (210). Pour le Megaoctet, on passe à 1 048 576 (220).

En résumé, en achetant un disque dur de 500 Go, le produit est plus intéressant s’il réfère à l’ancien standard car il aura une plus grande capacité. Par contre, si on a un fichier de 5 Mo à envoyer, il représente moins de volume si on parle avec le nouveau standard.

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

2 suggestions pour grouper les valeurs d’une variable

juillet 21, 2008

Sous SAS, lorsqu’une variable contient plusieurs valeurs à regrouper pour n’en former qu’une seule, il existe plusieurs options. Voici deux suggestions : une basée sur la notion de RETAIN et FIRST/LAST, l’autre sur PROC TRANSPOSE et ARRAY.

Pour illustrer le propos un data set liste plusieurs actions pour un patient à une visite donnée. Il s’agit de regrouper ces actions par patient et visite dans un seul record.

Le data set avant

pat_id  visit_dt rec_id action

   1   02APR2007    1   RAYON X
   1   02APR2007    2   ULTRASON
   1   02APR2007    3   SCANNER
   2   15NOV2007    2   RAYON X
   2   15NOV2007    1   ULTRASON

Le data set après : une nouvelle variable caractère est créée ACTION_LST. On lui donnera une longueur de 200. Chaque action y est séparée par une barre. Les variables REC_ID (identifiant du record) et ACTION sont supprimées.

pat_id  visit_dt action_lst

   1   02APR2007 RAYON X | ULTRASON | SCANNER
   2   15NOV2007 ULTRASON | RAYON X

1. La force du RETAIN

Pour débuter une variable ACTION_LST de longueur 200 est créée. Elle ne contient à la base aucune valeur.

data final; *(drop = rec_id action);
   set orig;
   by pat_id visit_dt;
   length action_lst $200;
   retain action_lst ‘ ‘;
   if first.visit_dt then action_lst=action;
   else action_lst=catx(‘ | ‘,action_lst,action);
   *if last.visit_dt then output;
run;

Pour chaque nouvelle visite de chaque patient, ACTION_LST est initialisée. Elle prend la valeur de la variable ACTION.

Du fait de la présence de l’instruction RETAIN, cette première valeur est maintenue pour tous les records d’une même visite. A chaque nouvelle lecture d’un record, une nouvelle action est ajoutée.

La fonction CATX permet de concaténer les valeurs d’ACTION_LST et ACTION, et d’ajouter la barre comme délimiteur.

Voici donc le résultat intermédiaire, avant l’activation du code mis en commentaires.

pat_id  visit_dt action_lst

   1   02APR2007 RAYON X
   1   02APR2007 RAYON X | ULTRASON
   1   02APR2007 RAYON X | ULTRASON | SCANNER
   2   15NOV2007 ULTRASON
   2   15NOV2007 ULTRASON | RAYON X

A présent, il s’agit de garder seulement le dernier record de chaque visite par patient avec LAST.VISIT_DT et à supprimer les variables REC_ID et ACTION.

2. Rotation de données (PROC TRANSPOSE) et lecture en boucle (ARRAY)

Avec cette seconde approche, le travail est découpé en deux étapes à commencer.

Dans un premier temps, un PROC TRANSPOSE pour faire pivoter les données. Le data set n’a alors plus qu’une ligne par visite de patient. Chaque action apparaît dans une colonne donnée.

proc transpose data=orig out=final2 (drop=_name_);
   by pat_id visit_dt;
   var action;
run;

pat_id  visit_dt  COL1      COL2      COL3

   1   02APR2007  RAYON X   ULTRASON  SCANNER
   2   15NOV2007  ULTRASON  RAYON X

Dans un second temps un ARRAY nommé _ACTION est défini. Il contient toutes les variables commençant par COL. A chaque nouvelle lecture d’une variable COL, sa valeur est ajoutée à celle de la variable ACTION_LST.

data final2 (drop=i col:);
   set final2;
   length action_lst $200;
   array _action {*} col:;
   do i=1 to dim(_action);
      action_lst = catx(‘ | ‘,action_lst,_action{i});
   end;
run;

Annexe : Création du data set utilisé pour l’exemple.

data orig;
   input pat_id visit_dt date9. rec_id action $15.;
   format visit_dt date9.;
   datalines;
1 02APR2007 1 RAYON X
1 02APR2007 2 ULTRASON
1 02APR2007 3 SCANNER
2 15NOV2007 2 RAYON X
2 15NOV2007 1 ULTRASON
;
run;

proc sort data=orig;
   by pat_id visit_dt;
run;

h1

20h de formation SAS au CNAM de Paris

juillet 17, 2008

Le Conservatoire National des Arts et Métiers (CNAM www.cnam.fr) et plus particulièrement son centre régional d’Ile-de-France propose deux unités de formations incluant SAS sur son site de la rue Saint Martin. Voici quelques précisions sur ces formations et les modalités pour les suivre.

1. Présentation du CNAM

Le CNAM ou Conservatoire National des Arts et Métiers est composé, en Métropole et DOM-TOM, de 130 centres de formations, regroupés en 28 centres régionaux. Le centre régional d’Ile-de-France est a priori le seul à proposer la formation SAS. Il est situé 292 rue Saint Martin à Paris.

2. L’intitulé des formations incluant SAS

Les formations sont divisées en unités d’enseignements (UE). Elles peuvent être suivies à la carte ou dans le cadre d’un cursus diplômant.

Quelle unité d’enseignement ? La formation au logiciel SAS est incluse dans deux UEs.

Quel cursus ?

3. Horaires

Sur site : La formation SAS dans les locaux de Paris a lieu au 1er semestre. Elle dure 20 h réparties à raison de 2H30 h par semaines en alternance (une semaine sur deux) sous forme de cours et de travaux dirigés et pratiques le soir.

  • Avec l’UE STA111, il faut ajouter 20 h pour la formation à R du premier semestre. 
  • L’UE EGS109 compte quant à elle 40 heures supplémentaires.

A distance : L’UE STAT111 est aussi proposée en formation à distance au 2ème semestre. Elle est accessible via la plateforme de formation nommée Pleiad du CNAM. Cette formation est complètement indépendante de la formation en cours du soir au centre.

Evaluation : L’évaluation se déroule sous la forme d’un projet consistant à analyser un jeu de données ou programmer une ou plusieurs méthodes statistiques.

4. Le contenu de la formation

Les modules SAS couverts lors de cette formation sont SAS/BASE®, SAS SQL, SAS/IML®, SAS MACRO, SAS/INSIGTH® et SAS/GRAPH®. Vous trouverez plus de précisions sur la page du département Mathématiques du CNAM.

5. Inscription

Pré-requis :

  • Pour la formation “Outils informatiques de la statistique” au moins une bonne connaissance en statistique descriptive est demandée.
  • Pour la formation “Représentation graphique et cartographique”, un bac + 2 minimum est requis (DESE, DEUG, L2, DUT, DPCT, DE Infirmière).

Dossier d’inscription : les deux UE requièrent un dossier d’inscription. De plus, pour la formation “Outils informatiques de la statistique” une lettre de motivation et un CV sont à envoyer à

Financement :

  • Pour un particulier, le coût de formation est composé du droit d’inscription annuel et du droit d’inscription à un UE. A titre informatif, pour 2008-2009, le droit d’inscription annuel s’élève à 140 euros. A cela s’ajoute 40 euros pour l’UE STA111 et 60 euros pour l’UE EGS109 (10 euros par crédit).
  • Les entreprises ont une somme forfaitaire de 1400 euros pouvant inclure jusqu’à 5 salariés.

Nombre de place : une vingtaine de personnes peuvent rejoindre la formation basée dans les locaux du CNAM.

6. Le suivi des anciens élèves

Association des anciens élèves : Il existe plusieurs types d’association d’élèves du CNAM dont AE2 CNAM. Vous pouvez vous reporter à la page du CNAM sur les associations auditeurs.

Offres d’emploi : Le centre d’information et d’orientation (CIO) du CNAM diffuse les offres d’emploi gratuitement. Les entreprises doivent contacter (CIO) moy.taillepied@cnam.fr, ou plus spécifiquement pour la statistique sabine.glodkowski@cnam.fr.

Pour plus de précisions, je vous renvoie sur la FAQ du site du CNAM Maths.

Merci à Madame Niang, Maître de conférences à la Chaire de Statistique Appliquée enseignant notamment SAS, pour avoir répondu si précisément et rapidement à mes questions.

h1

Identifier et supprimer les doublons

juillet 14, 2008

Identifier et supprimer les doublons dans un data set fait partie des compétences de base du programmeur SAS. Trois approches sont envisageables : PROC SQL, PROC SORT et un compteur dans un data step.

Qu’appelle-t-on doublon ? des lignes complètement identiques ou seulement des lignes ayant quelques variables communes ? Il est important de savoir si deux records ayant des observations communes sont considérés comme doublons ou s’il faut que toutes les observations soient identiques. Si seules quelques variables sont considérées, il faut savoir quelle ligne est conservée et lesquelles sont supprimées.

Le data set utilisé pour l’exemple est composé de trois variables CNTRY (country), PAT_ID (patient ID) et VAL (value). Le patient 2 de Chine a trois lignes d’observations dont deux strictement identiques.

cntry    pat_id    val

 CN        1        A
 CN        2        B
 CN        2        C
 CN        2        C
 HK        3        E 

1. PROC SQL

Avec la procédure SQL, il est possible de faire des calculs et de baser sa sélection d’observations sur ce calcul. En d’autres termes, il est possible de compter le nombre de fois qu’une valeur apparaît. Pour identifier les records avec doublons, on prend ceux comptés plus d’une fois.

Première présentation : Voici, tout d’abord, une présentation de PROC SQL décomposable en deux étapes.

proc sql;
   create table two (where=(cnt_pat > 1)) as
      select cntry, pat_id, val, count(*) as cnt_pat
      from one
      group by cntry, pat_id;
quit;

Dans un premier temps, une variable donne le nombre de records par patient dans un pays donné (CNT_PAT) grâce à la syntaxe GROUP BY et la fonction COUNT. A ce stade, on obtient le data set suivant :

cntry pat_id val cnt_pat

  CN     1    A     1
  CN     2    C     3
  CN     2    B     3
  CN     2    C     3
  HK     3    E     1

Dans un second temps, seules les observations ayant des doublons sont gardées, une fois le nouveau data set créé, grâce à l’option WHERE=.

Deuxième présentation : Au lieu de créer la variable CNT_PAT et de faire une sélection ultérieure, la fonction COUNT peut être  ajoutée dans une condition introduite par le mot HAVING et faisant toujours appel à la fonction COUNT.

Pour ne voir qu’une des lignes multiples, il suffit d’ajouter DISTINCT.

proc sql;
   create table two_bis as
   select /*distinct*/ cntry, pat_id, val
   from one
   group by cntry, pat_id
   having count(*) > 1;
quit;

A l’inverse, pour ne sélectionner que les observations n’apparaissant qu’une fois, “>1″ sera remplacé par “=1″. Seules les observations ayant exactement une occurrence sont sélectionnées.

Le DISTINCT s’applique à l’intégralité des observations. Cela permet de ne garder que des lignes uniques.

Il n’est pas possible de garder la première ligne parmi les doublons définis par des variables précises (CNTRY et PAT_ID dans l’exemple) avec cette méthode.

2. Les options de la procédure PROC SORT (NODUP/NODUPRECS, NODUPKEY)

Il existe deux options dans la procédure PROC SORT pour supprimer les doublons selon qu’ils s’appliquent

  • à toute une ligne d’observation (NODUPRECS dont l’alias est NODUP) ou
  • à une liste de variables précises données dans l’instruction BY (NODUPKEY).

Au choix, le nouveau data set sans doublons remplace l’ancien ou est sauvegardé dans un dataset différent introduit par OUT=.

Les observations ayant été exclues peuvent être sauvegardées dans un nouveau data set dont le nom est défini par DUPOUT=.

proc sort data=one out=three nodupkey dupout=three_bis;
   by cntry pat_id;
run;

proc sort data=one out=four noduprecs /*nodup*/ dupout=four_bis;
   by cntry pat_id;
run;

3. Appliquer une variable compteur

Enfin, après PROC SQL et PROC SORT, une troisième possibilité pour identifier et supprimer les doublons, est d’ajouter une variable compteur.

Dans l’exemple ci-dessous, la variable compteur est nommée CNT. Pour la première observation d’un patient d’un pays donné, le compteur est initialisé à 1. Pour chaque nouveau record du patient, le compteur est incrémenté de 1. Quand la variable CNT est égale à 1, le record est ajouté dans le data set FIVE. Sinon il est ajouté dans le data set FIVE_BIS. A la fin, la variable compteur est supprimée.

Ainsi le data set FIVE contient les records sans doublons. Dans le cas du patient doublonné (patient 2), c’est la première observation qui est conservée.

Dans le data set FIVE_BIS, les records exclus de la première sélection sont conservés.

data five (drop=cnt) five_bis (drop=cnt);
   set one;
   by cntry pat_id val;
   if first.pat_id then cnt=1;
   else cnt+1;
   if cnt = 1 then output five;
   else output five_bis;
run;

Annexe :

data one;
   input cntry $ pat_id $ val $;
   datalines;
CN 1 A
CN 2 B
CN 2 C
CN 2 C
HK 3 E
;
run;

h1

Faire pivoter un data set (un 1er exemple de PROC TRANSPOSE)

juillet 10, 2008

La transposition de jeux de données sous SAS est une étape fréquente dans le processus de programmation. Voici pour débuter un premier exemple pour se familiariser avec la syntaxe de base.

1. Les données d’origine

Le data set illustrant le sujet est composé de trois variables :

  • le numéro du patient (PAT_ID)
  • le numéro de la visite (VISIT) prenant les valeurs 18 pour début de visite, 50 pour fin de visite et 70 pour suivi
  • la date de cette visite (VISIT_DT).

En fin d’article, vous trouverez le code pour créer ce data set.

pat_id visit visit_dt

   1     18  25MAR2007
   1     70  15OCT2007
   1     50  01JUL2007
   2     18  14APR2007
   2     50  08AUG2007
   3     50  16OCT2007

2. Le minimum

Pour afficher une ligne par patient, il faut faire appel à la procédure PROC TRANSPOSE.

Dans le cas présent, on a choisi d’afficher la date de la visite (VAR VISIT_DT) pour chaque patient (BY PAT_ID). Le numéro de la visite est perdu dans cette transposition.

Le minimum de la syntaxe requiert la création d’un nouveau data set introduit par le mot-clé OUT=. Ce data set peut avoir le même nom que le data set d’origine. Il faut au moins lister une variable.

proc transpose data=one out=two;
   by pat_id;
   var visit_dt;
run;

pat_id  _NAME_    COL1      COL2      COL3

   1   visit_dt 25MAR2007 15OCT2007 01JUL2007
   2   visit_dt 14APR2007 08AUG2007         .
   3   visit_dt 16OCT2007         .         .

3. Les options et instructions supplémentaires

3.1 Des variables automatiques supprimées avec l’option DROP= : Le nom de la variable utilisée pour créer les colonnes COL1-COL3 est donné de manière automatique par SAS. Cette information est sauvegardée dans la variable _NAME_. Elle peut dont être supprimée avec l’option DROP attachée au data set de sortie nommé TWO.

proc transpose data=one out=two (drop=_name_);
   by pat_id;
   var visit_dt;
run;

pat_id         COL1         COL2         COL3

   1      25MAR2007    15OCT2007    01JUL2007
   2      14APR2007    08AUG2007            .
   3      16OCT2007            .            .

3.2 Une colonne propre à une visite donnée grâce à l’instruction ID : On remarque que pour le premier patient, la visite du 15 octobre est citée avant celle du 1er juillet. En d’autres termes, une colonne donnée ne correspond pas à une visite donnée mais à l’ordre des données dans le fichier source. De la même manière, la deuxième visite du troisième patient apparaît dans la première colonne.

Pour que chaque colonne corresponde à un numéro de visite donné, on fait appel à l’instruction ID suivie du nom de la variable définissant la colonne. Dans notre cas, il s’agit de la variable VISIT.

proc transpose data=one out=two (drop=_name_);
   by pat_id;
   var visit_dt;
   id visit;
run;

pat_id          _18          _70          _50

   1      25MAR2007    15OCT2007    01JUL2007
   2      14APR2007            .    08AUG2007
   3              .            .    16OCT2007

3.3 Des noms de colonnes personnalisés grâce à PREFIX = : Maintenant chaque colonne correspond à une visite en particulier. Comme les numéros de visites sont des nombres et que les variables de SAS ne peuvent commencer par un chiffre, SAS ajoute automatiquement un tiret bas devant. Pour donner un nom un peu plus parlant, on peut ajouter un préfixe à ces noms de colonne.

proc transpose data=one out=two (drop=_name_) prefix=VISIT;
   by pat_id;
   var visit_dt;
   id visit;
run;

pat_id      VISIT18      VISIT70      VISIT50

   1      25MAR2007    15OCT2007    01JUL2007
   2      14APR2007            .    08AUG2007
   3              .            .    16OCT2007 

3.4 Lister toutes les variables commençant par un nom donné

Avoir une série de variables commençant par le même préfixe présente des avantages car SAS permet d’y référer très simplement.

La syntaxe SAS : Pour lister toutes ces variables, il suffit de faire suivre le préfixe de deux points. Dans notre exemple, toutes les variables commençant par le mot VISIT sont listées avec VISIT:.

Voici quelques exemples d’applications de cette syntaxe :

  • un PROC TRANSPOSE : lister les variables à transposer
  • une option KEEP/DROP : lister les variables à garder ou à supprimer
  • un ARRAY : lister les variables définissant l’array.

Annexe :

data one;
   input pat_id visit visit_dt date9.;
   format visit_dt date9.;
   datalines;
1 18 25MAR2007
1 70 15OCT2007
1 50 01JUL2007
2 18 14APR2007
2 50 08AUG2007
3 18 16OCT2007
;
run;

h1

6 conseils pour vos emails

juillet 7, 2008

Le programmeur SAS ne fait pas exception dans le monde du travail lorsqu’il s’agit de communiquer par email avec ses partenaires et collaborateurs.

Dans l’industrie pharmaceutique, le programmeur travaillera souvent à distance avec un statisticien qu’il n’aura parfois jamais vu. Ensemble, ils clarifieront les caractéristiques d’un tableau à fournir et compareront leurs résultats. Le programmeur aura aussi fréquemment un manager très occupé qu’il consultera en allant à l’essentiel, optimisant le temps de chacun.

Voici quelques conseils pratiques qui font appel au bon sens.

1. Faites des emails courts, un par question

Avez-vous remarqué que, lorsque vous recevez un long pavé par email, vous n’y répondez souvent pas aussitôt. Privilégiez donc des emails courts quitte à faire plusieurs emails, un par question à poser. Les points les plus faciles à répondre trouveront ainsi une réponse très rapide et ne seront pas noyés au milieu d’un bloc compact.

2. Interrogez vous sur la pertinence de votre email

Il est tentant d’envoyer un email pour des détails mineurs. Les managers et statisticiens reçoivent quantités d’emails. Réfléchissez à deux fois avant d’envoyer un email. Si vous ne faites pas partie de ceux qui envoient des emails “à gogo”, votre interlocuteur prendra une attention à lire vos emails car il saura que ce sont des emails importants.

3. Optez pour un vocabulaire universel

Optez pour un vocabulaire non technique que vous parliez à un expert ou non. Au final, le message sera universel et pourra être transféré à d’autres interlocuteurs non prévus initialement. Evitez donc de nommer des noms de variables ou des procédures de manière brute. Rien, par contre, ne vous empêche de rajouter ces informations en complément.

4. Structurez votre email

Numérotez vos paragraphes : par soucis de clarté, ajoutez une numération. Cela sera très pratique lorsque votre email aura pour but de rappeler les points discutés avec votre interlocuteur.

Commencez par introduire le sujet : Votre destinataire travaille probablement sur d’autres sujets et n’a pas forcément en tête le projet qui vous concerne. Il est dont important d’introduire le sujet.

Faites force de proposition : Présentez les problèmes et listez aussi des actions possibles. Cela épargnera du temps à votre collaborateur qui n’aura plus qu’à prendre une décision.

Clarifiez votre attente envers votre destinataire : Finissez par une phrase qui définira clairement si vous attendez une réponse et si oui sur quel point en particulier. N’hésitez pas à mettre en valeur cette phase en changeant de couleur par exemple. 

Des mots-clés dans l’objet : Si votre email a un but purement informatif, précisez-le dans l’objet de votre email par le mot INFO. S’il s’agit d’un problème, vous avez le raccourci PBM pour attirer l’oeil du destinataire. Enfin précisez le nom de l’étude sur laquelle vous travaillez en plus du point particulier abordé dans l’email. 

5. Relisez-vous

Enfant, c’était ma grand-mère qui corrigeait mes cours avec son crayon papier taillé au couteau, lors que je lui les récitais mes leçons. Aujourd’hui, écrivant principalement en allemand et en anglais ce sont mes collègues qui me corrigent quand j’ai des messages ou documents importants à rédiger. Cela reste la meilleure manière de progresser dans la langue et d’éviter les malentendus.

Bien sûr, cette aide est à demander de manière ponctuelle et seulement après avoir fait des efforts :

  • avoir relu son travail auparavant
  • avoir passé son texte au correcteur de Word.

6. Tenez compte des contraintes techniques

Impression : votre email aura de grandes chances d’être imprimé. Evitez les images et tableaux trop larges. En dehors de votre premier contact où vos coordonnées complètes seront détaillées, privilégiez une signature courte. Cela évitera d’avoir le plus souvent une page de plus à l’impression juste pour la signature.

Pièce jointe : même si toute l’information est contenue dans une pièce jointe, sélectionnez l’extrait le plus important et copiez le dans l’email. Cela aidera le lecteur à classer votre mail : à répondre, à sauvegarder, etc. Par ailleurs, précisez dans le mail qu’il y a une pièce jointe pour qu’il la remarque. Si vous l’oubliez votre destinataire le remarquera et pourra vous prévenir.

N’hésitez pas à compléter la liste en envoyant un commentaire.

h1

Penser conditionnel (3/3) : CASE WHEN

juillet 3, 2008

Après avoir présenté les deux alternatives sous SAS dans un data step pour définir des conditions (La base du IF et SELECT), partons voir la syntaxe de PROC SQL pour définir une nouvelle variable.

1. Différences et ressemblances avec les IF et SELECT

Différences : A la différence des deux syntaxes du data step,…

  • … une seule action est possible pour une condition donnée : à savoir définir une et une seule nouvelle variable ou macro variable. Les conditions ne peuvent dont pas servir pour créer de nouveaux data sets ou imbriquer des conditions dans d’autres conditions.
  • … le nom de la nouvelle variable n’est donné qu’une seule fois.

Ressemblances :

  • Comme dans SELECT WHEN et ELSE IF,  seuls les records non déjà valides pour les cas listés précédemment sont relus.
  • Comme IF THEN, une dernière condition ELSE liste tous les cas non sélectionnés auparavant.

Un des avantages de la procédure SQL est de pouvoir définir une nouvelle variable à partir d’une ancienne variable portant le même nom. Alors que dans un data step, cela se passe en plusieurs étapes : 

  • Tout d’abord, la variable est renommée pour pouvoir se servir de son nom d’origine pour la nouvelle variable.
  • Ensuite la variable d’origine portant le nom créé uniquement pour l’occasion est supprimée.

Un autre avantage est l’usage des fonctions et du mot-clé DISTINCT.

2. La syntaxe CASE WHEN en exemple

2.1 Définir une variable à partir de plusieurs variables

Dans cet exemple, la variable POP prend au maximum 4 valeurs :

  • 1 si la variable AGE est supérieure à 13 et la variable SEX est égale à F ;
  • 2 si l’AGE est entre 0 et 13 et qu’il s’agit d’une femme ;
  • 3 si il s’agit d’un homme et que l’âge est une valeur positive ;
  • valeur manquante enfin pour les autres cas.

proc sql;
   /*create table class as*/
   select *, case
               when age > 13 and sex=‘F’ then 1
               when age >= 0 and sex=‘F’ then 2
               when age < 0 or sex not in (‘F’,‘M’) then .
               else 3
           end as pop
   from sashelp.class;
quit;

2.2 Utiliser les fonctions

Dans l’exemple ci-dessous, le critère est appliqué par groupe de valeurs définies dans la variable SEX. En regardant les données, deux groupes de valeurs apparaissent : ‘F’ pour les femmes et ‘M’ pour les hommes. La variable MAX_AGE1 est égale à ‘13′ si, pour un groupe donné, la valeur maximale observée parmi les valeurs non manquantes de la variable AGE est 13. Sinon, MAX_AGE1 prend la valeur ‘N/A’.

proc sql;
   select sex, case
                 when max(age) = 13 then ‘13′
                 else ‘N/A’
               end as max_age1
   from sashelp.class
   group by sex;
quit;

A présent, vu qu’il n’y a qu’un critère définissant la condition et qu’une seule valeur n’est attendue, ce critère peut être donné en début.

proc sql;
   select sex, case max(age)
                 when (13) then ‘13′
                 else ‘N/A’
               end as max_age2
   from sashelp.class
   group by sex;
quit;

Mais, il est bon de se demander si un format ne serait pas plus adapté dans ce cas.

proc format;
  value max_age
   13    = ‘13′
   other = ‘N/A’;
run;

proc sql;
   select sex, put(max(age),max_age.) as max_age2
   from sashelp.class
   group by sex;
quit

2.3 Créer une macro variable

Voici pour terminer un petit exemple où une macro variable POP est crée. Sa valeur dépend de l’âge maximum observé dans le data set.

proc sql; *noprint;
   select case
            when
max(age) > 13 then ‘>13′
            when max(age) >= 0 then ‘[0-13]‘
            else ‘N/A’
          end into :pop
   from sashelp.class;
quit;

h1

Des souvenirs de lycée, les logarithmes

juillet 2, 2008

Une des notations mathématiques qui est abordée au lycée en algèbre sont les logarithmes. Les propriétés de cette notation la rendent très attrayante pour exprimer et résoudre des équations. Mais vous souvenez vous du raisonnement qui se cache derrière ce nom ? Et savez-vous comment retrouver cette information en SAS ?

Cet article intéressera plus particulièrement ceux qui veulent replonger dans leur cours de statistique. En effet, les distributions statistiques, par exemple, sont formulées avec des équations contenant souvent des logarithmes. D’un point de vue professionnel, je n’ai jamais eu besoin de calculer un logarithme sous SAS pour l’industrie pharmaceutique.

1. Définition

Combien de fois faut-il multiplier 10 pour obtenir 1000 ? ou encore combien de fois faut-il multiplier 2 pour obtenir 32 ? Si vous avez la réponse à ces questions, vous êtes capable de résoudre des logarithmes.

Un logarithme est défini par une base. 10 et 2 sont les plus simples à comprendre dans un premier temps. Une base “e” rend les calculs plus simples. On parle alors de logarithme népérien ou logarithme naturel.

Dans le cas général, log symbolise le logarithme de manière général. Dans le cas particulier du logarithme népérien, log base e, le symbole est ln.

Les mathématiciens emploient plus facilement la base e dans la vie de tous les jours pour les raisons de facilité de calcul. Mais on a l’ordinateur de nos jours, me direz-vous. Alors il faut pensez au temps d’exécution de calculs complexes. Et là, même l’ordinateur sera content d’avoir des options pour résoudre le problème plus rapidement !

2. Exemples

Dans ce premier exemple, le logarithme de 1000 est défini par une base 10. Ainsi le but est de retrouver le nombre de fois 10 doit être multiplié pour obtenir le chiffre 1000. Sachant que 10×10x10=1000 ou de manière plus condensée 103=1000, la réponse est 3 fois.

log10 1000 = 3 car pour résoudre 10x=1000, on note x=3, soit 10×10x10=1000.

Dans ce second exemple, une base 2 est choisie. Il faut trouver le nombre de fois le nombre 2 est multiplié pour obtenir 32. La réponse est 5 fois.

log2 32 = 5 car pour résoudre 2x=32, on note x=5 soit 2×2x2×2x2=32.

Dans ce dernier exemple, une base e est choisie. Il s’agit du logarithme naturel ou logarithme népérien noté en langage courant ln. Pour retrouver la valeur approximative de e, on résout e1 sur son ordinateur ou sa calculatrice et on obtient une valeur de l’ordre de 2,71828.

loge 1 = ln 1 = 0 car pour résoudre ex =  1, on note x=0.

3. Calculer un logarithme en SAS

En SAS, il existe plusieurs types de fonctions LOG. Ainsi, notre log base 10 de 1000 devient LOG10 (1000) et notre log base 2 de 32 devient LOG2(32). Pour ce qui est du logarithme népérien, il suffit de ne pas préciser de chiffre LOG(1).

data _null_;
   log10_1000 = log10(1000);
   log2_32    = log2(32);
   loge_1     = log(1);
   loge_0     = log(0);
   put log10_1000 =;
   put log2_32    =;
   put loge_1     =   loge_0 = ;
run;

Dans l’exemple ci-dessus, j’ai arbitrairement choisi de ne pas créer de data set SAS en utilisant le mot _null_. Vous pouvez choisir de créer un data set et de l’afficher avec PROC PRINT.

Pour afficher les valeurs je me sers des instructions PUT. En choisissant d’ajouter le signe égal après le nom de la variable, non seulement la valeur des variables apparaîtront, mais aussi le nom des variables et le signe égal. Cela rend la lecture de l’information affichée dans la LOG plus facile. Faites le test sans le signe égal et vous verrez la différence dans la LOG.

Pour plus de précisions sur les fonctions logarithmiques, vous pouvez vous reporter à la documentation en ligne (SAS Online Doc. : LOG FunctionLOG10 FunctionLOG2 Function). Sachez par ailleurs qu’il existe d’autres fonctions log sous SAS : LOGBETA, LOGCDC, LOGPDF et LOGSDF.