Archive for the ‘proc freq’ Category

h1

Combien ai-je de contrats au total ? (4/5) PROC FREQ

novembre 17, 2008

Dans les précédents articles sur cette série traitant du calcul de totaux, la procédure PROC SQL, le RETAIN dans une étape DATA et la procédure PROC MEANS nous on montré qu’elles pouvaient retrouver le nombre total de contrats pour chaque type (contrats téléphoniques, contrats d’habitation). La procédure PROC FREQ mérite également votre attention . Comme PROC MEANS, cette procédure utilise la notion de coefficient/poid (weight).

Rappel : Vous pouvez retrouver l’étape data créant le data set pour ce sujet en fin d’article. Les données contiennent l’identifiant du client CLIENT, le nombre de contrats NB_CNTR et deux variables binaires TEL et HABITAT indiquant si oui ou non les fréquences s’appliquent. Au total, on compte 9 contrats téléphoniques et 5 contrats d’habitation.

client nb_cntr tel habitat;
   a      5     1     0
   b      1     1     0
   c      2     0     1
   d      1     1     0
   e      3     0     1
   f      2     1     0

1. Deux approches possibles

Avec la procédure PROC FREQ, deux options s’offrent à vous :

  • D’abord générer un data set par type de contrat avec PROC FREQ et ensuite combiner les données.
  • D’abord changer la structure des données et ensuite obtenir un seul data set avec PROC FREQ.

Par soucis de simplicité, je vous propose d’aborder la seconde méthode qui me semble de loin la plus logique pour nos données.

Etape 1 : Changer la structure des données revient à avoir d’un côté le nom des différents types de contrats et de l’autre si oui ou non une fréquence s’applique pour eux. Il n’y a alors plus qu’une seule variable binaire.

Pour changer cette structure des données, deux solutions sont possibles :

  • une étape data ou
  • la procédure PROC TRANSPOSE.

La première approche servira à comprendre la manipulation. La seconde approche est facilement généralisable à un plus grand nombre de variable et a donc ma préférence.

Etape 2 : Pour extraire le data set avec PROC FREQ, il existe l’ancienne méthode avec l’option OUT= et la nouvelle beaucoup plus standard ODS OUTPUT. Le raisonnement appliqué par cette méthode est applicable à de nombreuses procédure. La syntaxe est donc beaucoup facile de la retenir.

2. Etape 1 – Changer la structure des données en utilisant une étape data

Il s’agit de créer une variable unique indiquant si oui ou non les coefficients (weight) données dans la variable NB_CNTR s’appliquent.

data contrats_update ;
   length contrat $7;
   set contrats (in=a keep=nb_cntr tel     rename=(tel=tmp)     )
       contrats (     keep=nb_cntr habitat rename=(habitat=tmp) );
    if a then contrat='tel';
    else contrat='habitat';
run;

Les 6 premières lignes sont consacrées au contrat de téléphone et les 6 dernières concernent les contrats d’habitation.

Seules les données où la variable binaire est oui (NO_YES=1) seront au final intéressante. Il est possible de supprimer les données où NO_YES=0 en ajoutant dans l’étape data un WHERE (where=(no_yes=1)) et en supprimant ensuite la variable NO_YES avec DROP (data contrats_update (drop=no_yes)). Voulant vous montrer les différentes étapes, je n’ai pas supprimé les lignes ou NO_YES=0.

nb_cntr  no_yes    contrat

   5        1        tel
   1        1        tel
   2        0        tel
   1        1        tel
   3        0        tel
   2        1        tel
   5        0        habitat
   1        0        habitat
   2        1        habitat
   1        0        habitat
   3        1        habitat
   2        0        habitat

3. Etape 1 alternative – chpour regrouper les contrats dans une seule variable : PROC TRANSPOSE

Pourquoi un PROC SORT ? Dans cette section, il est fait usage de la procédure PROC TRANSPOSE pour modifier la structure du data set de départ. Comme une instruction BY est nécessaire, il est obligatoire d’avoir au préalable les données triées dans ce même ordre. Ceci explique la présence actuelle de la procédure PROC SORT.

Pourquoi une option OUT= ? une Ne souhaitant pas ajouter ces changement dans le fichier d’origine, j’ai donné le nom CONTRATS_UPDATE au nouveau data set. C’est un choix personnel pour cet article en particulier. Il n’y a aucune raison pour immiter obligatoirement ce choix.

proc sort data=contrats out=contrats_update;
   by client nb_cntr;
run;

L’objectif est d’avoir à présent autant de lignes que de type de contrats (2 lignes par client dans notre exemple). Pour chaque ligne est donné le nombre de contrats pouvant s’appliquer (variable NB_CONTR) et si oui ou nom ce nombre s’applique (variable NO_YES).

proc transpose data=contrats_transp
               out=contrats_transp (drop=client
                                    rename=(_name_=contrat col1=no_yes));
   by client nb_cntr;
   var tel habitat;
run;

Après avoir renommé les variables _NAME_ et COL1, nous retrouvons le même résultat que précédemment à l’exception de l’ordre dans lequel sont triées les données. Mais cela n’a pas d’effet dans notre PROC FREQ à venir.

    nb_cntr    contrat    no_yes

       5       tel         1
       5       habitat     0
       1       tel         1
       1       habitat     0
       2       tel         0
       2       habitat     1
       1       tel         1
       1       habitat     0
       3       tel         0
       3       habitat     1
       2       tel         1
       2       habitat     0

4. Etape 2 – Exécuter un PROC FREQ

ODS EXCLUDE ? Je souhaite créer un data set et seulement un data set. Hors par défaut le résultat (la sortie) est envoyé dans la fenêtre OUTPUT. L’instruction ODS EXCLUDE de début empêche cet envoi et celle de fin rétablit le statut initial.

ONEWAYFREQS ? Dans le cadre d’un tableau à une dimension, la sortie s’appelle ONEWAYFREQS. Un ODS TRACE ON/LISTING permet de retrouver lors d’une première exécution ce nom si vous avez oublié dans la fenêtre output (ODS TRACE OFF pour arrêter le processus).

ODS OUTPUT ? La sortie est envoyée dans le data set SOLUTION4 en se servant de l’instruction ODS OUTPUT et du nom de la sortie. Seules les variables CONTRAT et FREQUENCY sont conservées.

L’ancienne méthode ? En commentaire, vous trouverez l’option OUT= de l’instruction TAB qui vous fournira les mêmes statistiques. A noter que le nom de la variable pour les fréquences s’appelle cette fois COUNT et non plus FREQUENCY.

ods exclude onewayfreqs;
proc freq data=contrats_update (where=(no_yes=1));
   weight nb_cntr;
   by contrat;
   table no_yes;
   ods output onewayfreqs=solution4 (keep=contrat frequency);
   *table tmp/out=solution4 (keep=contrat count);
run;
ods exclude none;

Au final, on retrouve bien 9 contrats téléphoniques et 5 contrats d’habitation.

contrat Frequency

tel         9
habitat     5

Annexe : entrer les données dans un tableau SAS

data contrats;
   input client $ nb_cntr tel habitat;
   datalines;
a 5 1 0
b 1 1 0
c 2 0 1
d 1 1 0
e 3 0 1
f 2 1 0
;
run;
h1

Je garde ou je jette? les variables

août 25, 2008

Pour 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

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;

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;