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;