Posts Tagged ‘array’

h1

Un premier exemple d’array : changer toutes les variables 1/2 en variable 0/1

mai 11, 2009

Imaginez que vous avez dans une table des variables oui/non où 1 représente non et 2 représente oui. Changement de standard oblige, vous devez symboliser les non par un 0 et les oui par un 1.

Si mavariable=1 alors mavariable=0.
Sinon mavariable=1.

Bien sûr, vous pouvez traiter séparément chaque variable. Ce chantier laborieux est remplaçable par une boucle où seul le nom de la variable change à chaque fois. Vous voulez donc effectuer une même opération sur un grand nombre de variables. La syntaxe de l’array est faite pour vous.

1. Un data set pour l’exemple

Voici la table (SAS data set) utilisée pour l’exemple. Elle s’appelle FINAL. Elle est composée d’une variable caractère et de trois variables numériques, toutes des variables binaires de type oui (2)/ non (1).

data final;
input subject $ pregny validny aeny;
datalines;
A 1 2 1
B 1 1 2
C 2 1 2
D 1 2 2
;
run;

Le but sera d’obtenir un data set avec des variables binaires de type oui (1)/ non (0).

subject pregny validny aeny;
A      0       1      0
B      0       0      1
C      1       0      1
D      0       1      1

2. C’est quoi un array ?

Un array est un nom qui désigne une liste de variables. Il est propre à l’étape data.

  • Définir un nouvel array : Dans un premier temps, l’array est à créer: Sous un nom de son choix, sont sauvegardés sauvegarde des noms de variables (les éléments de l’array) dont l’ordre est indexé pour pouvoir les désigner de manière individuelle par la suite.
  • Appler les variables contenues dans l’array : Dans un second temps, chaque élément de l’array (chaque variable) est appelé/désigné, non pas par son nom, mais par sa position dans l’array.

3. Définir un array

Pour définir un array, il existe l’instruction ARRAY. Elle est composée de trois parties principales et d’un quatrième optionnel.

  • le nom de l’array
  • le nombre de variables  listées (le nombre d’éléments dans l’array)
  • le nom des variables
  • la valeur des variables (optionel)

Dans l’exemple, j’ai un array nommé NY composé de trois éléments : les variables PREGNY (prenant no/yes), VALIDNY (valid no/yes) et AENY (adverse event no/yes).

data final;
set final;
*array ny {1998:2000} pregny validny aeny;
*array ny {1:3} pregny validny aeny;
array ny {*} pregny validny aeny;
run;

Je vous propose trois alternatives pour la notation. Ma préférence, pour des raisons de simplicité dans ce cas, va au cas numéro trois.

  • {1998:2000} Dans le premier cas, la variable PREGNY a pour référence la position 1998, VALIDNY a pour référence la position 1999 et la variable AENY est en position 2000.
  • {1:3} Dans le second cas, la numérotation commence à 1 avec la variable PREGNY et se termine à 3 avec la variable AENY.
  • {*} Dans le troisième et dernier cas, la numérotation est implicite. Comme précédemment. Elle ira de 1 à 3. SAS se charge de compter le nombre de variables pour savoir la dimension de l’array. Si SAS fait le travail pour nous, pourquoi se priver de ce luxe !

Note : La première syntaxe peut apporter dans certains cas un plus en terme de compréhension. C’est le cas quand le numéro a un lien avec le sens de la variable. Par exemple, les variables RESULT98, RESULT99 et RESULT00 peuvent avoir les positions 1998, 1999 et 2000 et donc avoir un caractère informatif.

4. Appeler un array

Pour appeler un élément d’un array (une variable), il faut donner le nom de l’array suivi de la position de la variable dans l’array. Ainsi :

  • ny{1} désigne la variable PREGNY
  • ny{2} fait référence à la variable VALIDNY
  • ny{3} concerne la variable AENY

data final;
set final;
array ny {*} pregny validny aeny;
*variable PREGNY;
if ny{1}=1 then ny{1}=0;
else ny{1}=1;
*variable VALIDNY;
if ny{2}=1 then ny{2}=0;
else ny{2}=1;

*variable AENY;
if ny{3}=1 then ny{3}=0;
else ny{3}=1;

run;

L’intérêt de cette notation vient dans l’usage d’une boucle où la position de la variable sera automatiquement changé.

data final;
set final;
array ny {*} pregny validny aeny;
do i=1 to dim(ny)
;*do i=1 to 3;
if ny{i}=1 then ny{i}=0;
else ny{i}=1;
end;
run;

Pour les plus paresseux comme moi, on demandera à SAS de calculer le nombre d’éléments contenus dans l’array (la dimension) au moyen de la fonction SAS propre à l’array DIM().

Je vous proposerai dans les semaines à venir un autre article sur les subtilités de l’array.

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;