h1

Jongler avec les records grâce aux compteurs

juin 12, 2008

Sous SAS, une variable compteur permet de numéroter les lignes d’observations. Le plus souvent, cette variable sert ensuite à sélectionner certaines lignes d’un jeu de données et d’agir en fonction. Par exemple, pour chaque patient, un fois le compteur créé, il est simple de sélectionner les 5 premiers records.

Pour développer une variable compteur, il faut maîtriser la notion de FIRST. Vous pouvez vous reporter à l’article « Repérer les 1ers/derniers records (FIRST/LAST) ».

En outre, il faut comprendre la notion de RETAIN. Celle-ci sera abordée dans cet article.

Quatre exemples serviront à illustrer le sujet. Ils sont basés sur un data set nommé LAB ayant 9 lignes observations. Il est donné en fin d’article dans le paragraphe « Annexe ». On y trouve trois patients (PAT_ID), deux types de tests médicaux (TEST) et une date pour chaque test (variable TEST_DT). La variable compteur s’appelle à chaque fois CNT.

 1. La notion de RETAIN

Un RETAIN permet d’assigner une valeur à toutes les observations d’une variable. On préfèrera donc un RETAIN à « variable=valeur; » pour assigner une valeur unique pour toutes les records d’une variable données. 

Si entre temps, la valeur d’une observation est modifiée, tous les valeurs suivantes prennent cette nouvelle valeur. Cette seconde fonctionnalité sert pour créer une variable compteur.

Un RETAIN se définit le plus souvent dans une instruction RETAIN. Dans le cas des compteurs, on peut créer un RETAIN implicite prenant une valeur d’origine de zéro.

2. Pour chaque nouvelle observation incrémenter le compteur : dans ce premier exemple, à chaque nouvelle observation identifiée de manière unique par PAT_ID, TEST_DT et TEST, le compteur est incrémenté par 1. Le compteur va alors de 1 à 9 (le total d’observations). Les données sont préalablement triées par ces trois variables.

  test_dt    pat_id    test    cnt

28MAR2006      101     DBP      1
28MAR2006      101     SBP      2
29APR2006      101     DBP      3
27MAY2006      101     SBP      4
23JUN2006      101     SBP      5
13JAN2006      301     DBP      6
14FEB2006      301     SBP      7
15MAR2006      301     DBP      8
05MAR2006      401     DBP      9

Il faut donc dans un premier temps trier les données et rappeler cet ordre dans l’instruction BY du data step.

proc sort data=lab;
   by pat_id test_dt test;
run;

Puis la variable CNT prend une valeur de 0 pour chaque record.

Enfin les records sont lus les uns après les autres. A chaque nouvelle TEST pour un PAT_ID et TEST_DT donné, le compteur est incrémenté de 1.

data lab;
   retain cnt 0;
   set lab;
   by pat_id test_dt test;
   if first.test then cnt=cnt+1;
run;

Un RETAIN implicite : l’instruction RETAIN peut-être omise si un RETAIN implicite est utilisé. C’est le cas ici quand « cnt=cnt+1 » est remplacé par « cnt+1 ».

data lab;
   set lab;
   by pat_id test_dt test;
   if first.test then cnt+1;
run;

3. Pour chaque nouvelle date, incrémenter le compteur : dans le second exemple, pour chaque nouvelle date indépendamment du patient ou de type de test, le compteur est incrémenté par 1. Le compteur va de 1 à 8 (les 8 différentes dates). Les données sont triées par date au préalable.

  test_dt    pat_id    test    cnt

13JAN2006      301     DBP      1
14FEB2006      301     SBP      2
05MAR2006      401     DBP      3
15MAR2006      301     DBP      4
28MAR2006      101     SBP      5
28MAR2006      101     DBP      5
29APR2006      101     DBP      6
27MAY2006      101     SBP      7
23JUN2006      101     SBP      8

proc sort data=lab;
   by test_dt;
run;

data lab;
   set lab;
   by test_dt;
   if first.test_dt then cnt+1;
run;

4. Pour chaque nouveau patient, incrémenter le compteur : dans ce troisième exemple, chaque patient reçoit un numéro unique allant de 1 à 3 ; trois étant le nombre total de patients. Les données sont donc triées par PAT_ID.

   test_dt    pat_id    test    cnt

28MAR2006      101     SBP      1
28MAR2006      101     DBP      1
27MAY2006      101     SBP      1
23JUN2006      101     SBP      1
29APR2006      101     DBP      1
14FEB2006      301     SBP      2
13JAN2006      301     DBP      2
15MAR2006      301     DBP      2
05MAR2006      401     DBP      3

proc sort data=lab;
   by pat_id;
run;

data lab;
   set lab;
   by pat_id;
   if first.pat_id then cnt+1;
run;

5. Pour chaque nouveau date d’un patient donné, incrémenter le compteur : dans ce dernier exemple, à chaque nouvelle date, le compteur est incrémenté par un. Le premier patient ayant 4 dates différentes et 5 observations, le compteur va de 1 à 4 pour lui. Une des valeurs est doublée pour la date identique. Le second patient ayant trois dates uniques, le compteur va de 1 à 3 pour lui. Le compteur est donc réinitialisé à 1 pour chaque nouveau patient.

  test_dt    pat_id    test    cnt

28MAR2006      101     SBP      1
28MAR2006      101     DBP      1
29APR2006      101     DBP      2
27MAY2006      101     SBP      3
23JUN2006      101     SBP      4
13JAN2006      301     DBP      1
14FEB2006      301     SBP      2
15MAR2006      301     DBP      3
05MAR2006      401     DBP      1

proc sort data=lab;
   by pat_id test_dt;
run;

data one;
   set orig;
   by pat_id test_dt;
   if first.pat_id then cnt=1;
   else if first.test_dt then cnt+1;
run;

Annexe :

data orig;
   format test_dt date9.;
   input pat_id test_dt date9. test_type $;
   datalines;
101 28MAR2006 SBP
101 28MAR2006 DBP
101 27MAY2006 SBP
101 23JUN2006 SBP
301 14FEB2006 SBP
101 29APR2006 DBP
301 13JAN2006 DBP
301 15MAR2006 DBP
401 05MAR2006 DBP
;
run;

3 commentaires

  1. Comment faire pour faire la même chose mais avec des conditionnements? Dans votre exemple, incrémenter seulement si test=SBP par exemple?


  2. Bonjour,
    Tout d’abord merci pour votre blog qui est très intéressant.
    Je l’ai regardé car j’ai besoin de créer un compteur avec 2 contraintes.
    dans mon fichier j’ai une colonne avec une variable code_invidu et une autre colonne avec une date de visite (format en mois ex : NOV11). Je souhaite compter le nombre de visites par mois pour chaque individu. Dès qu’il y a un changement de mois le compteur doit se remettre à 0. Et pour un même individu s’il y a plusieurs mois identiques le nombre de visite doit être de +1 pour ce mois là.
    Connaissez vous une procédure qui pourrait m’aider? car j’avoue que je suis bloquée.
    Merci d’avance.


  3. […] Jouer avec les records grâce aux compteurs […]



Laisser un commentaire