Pour créer un tableau et le publier, la procédure REPORT est disponible. Je vous propose de voir sa structure de base.
1. Lister vos variables avec l’instruction COLUMN : la procédure REPORT doit contenir au minimum une instruction COLUMN listant les variables à publier dans l’ordre d’apparition souhaité.
Pour les utilisateurs de SAS pour Windows, on ajoutera l’option NOWD dans l’instruction PROC REPORT, pour éviter l’ouverture d’une fenêtre indépendante.
2 Personnalisez les colonnes : par défaut, les colonnes auront pour nom celui de la variable. Pour les personnalisez, on ajoute une instruction DEFINE par colonne.
proc report data=result_pat nowd;
column pays pays_txt patient_id cnt pct;
define pays / display ‘ ‘;
define pays_txt / display ‘Pays’;
define patient_id / display ‘ID’;
define cnt / display ‘N’;
define pct / display ‘%’;
run;
3. Privilégiez l’affiche en mode DISPLAY : par défaut les variables textes seront en mode DISPLAY tandis que les variables numériques seront en mode ANALYSIS. En d’autres termes, SAS peut potentiellement regrouper et additionner des valeurs numériques. Je pense notamment lorsqu’on utilise l’option GROUP sur d’autres variables. De plus, les valeurs textes seront alignées à gauche et les valeurs numériques seront alignées à droite.
Mon choix est donc de convertir toutes mes variables à afficher en texte avant et de n’utiliser PROC REPORT que comme un outil de publication. Vous pouvez, de plus, explicitement indiquer le mode DISPLAY dans les instructions DEFINE.
4. Trier les données et ne pas afficher certaines colonnes : en plus des affichages par défaut DISPLAY et ANALYSIS, vous avez l’affichage ORDER. Il est vivement conseillé de noter explicitement l’option ORDER= (formated, data, freq ou internal) car la valeur par défaut risque d’évoluer dans les prochaines versions de SAS. On peut également utiliser le mot-clé DESCENDING pour un tri par ordre décroissant.
Il est souvent plus facile de trier les données si elles sont numériques. Par exemple, imaginez que vous vouliez trier vos données par pays avec en premier des pays d’Europe par ordre alphabétique (Allemagne, France, Royaume-Uni) puis des pays d’Asie par ordre alphabétique (Indonésie, Malaisie, Singapour, Thaïlande). Vous pouvez créer un format numérique avec des valeurs allant de 1 à 7 (1 pour Allemagne, 7 pour Thaïlande).
Pour être cohérent avec mon propos précédent, je vous conseille d’avoir deux variables :
-
d’un côté la variable numérique qui sert pour le tri mais que ne sera pas affichées. Pour cela, il y a l’option NOPRINT de l’instruction DEFINE ;
-
et de l’autre, la variable texte créée préalablement à partir de la variable numérique et du format avec une fonction PUT.
5. Grouper les données et créer des breaks : imaginez que vous ayez plusieurs patients du même pays. Vous aurez autant de fois le nom de pays qu’il y a de patients. Pour alléger le tableau, vous pouvez n’afficher le pays que la première fois. Au lieu de DISPLAY, ANALYSIS, ORDER, etc. vous utilisez alors l’option GROUP dans l’instruction DEFINE.
Notez que toutes les colonnes à gauche devront donc être également groupées.
Il est possible d’utiliser ORDER=… avec GROUP comme pour l’option ORDER.
Un des avantages de GROUP est de définir entre les groupes des séparations. Pour cela, il y l’instruction BREAK AFTER appelle la variable groupée en question. Le type de séparation est défini par l’option. SKIP par exemple permet de sauter une ligne entre les groupes. Mais cette instruction ne fonctionne pas avec ODS RTF. Il faut alors utiliser la syntaxe COMPUTE/ENDCOMP.
proc report data=result_pat nowd;
column pays pays_txt patient_id cnt pct;
define pays / group order=data noprint;
define pays_txt / group ‘Pays’;
define patient_id / display ‘ID’;
define cnt / display ‘N’;
define pct / display ‘%’;
*break after pays / skip;
compute before;
line ‘ ‘;
endcomp;
compute after pays_num;
line ‘ ‘;
endcomp;
run;
6. Les faiblesses de l’instruction ACROSS : imaginez que vous ayez les fréquences et pourcentages pour deux drogues. Cela vous donne 4 colonnes dans votre tableau finale. Mais, dans votre tableau d’origine, vous avez 3 colonnes : le type de drogue, les fréquences et les pourcentages. L’instruction ACROSS permet de « transposer » l’information. Mais si, en plus, vous voulez rajouter une colonne à droite, vous rencontrerez de réelles difficultés.
Comme précédemment, je choisi d’agencer mes données comme il me convient avant la procédure. Je n’utilise PROC REPORT que pour l’affichage. Cela implique souvent l’usage d’un PROC TRANSPOSE et d’un MERGE (where=() rename=()).
proc sort data=result_drug;
by pays;
run;
proc transpose data = result_drug
out = result_drug_across
prefix = drug_;
by pays;
var cnt pct;
id drug;
run;
data result_drug_across (drop=_NAME_);
merge result_drug_across
(where=(lowcase(_name_)=‘cnt’)
rename=(drug_1=cnt_1 drug_2=cnt2))
result_drug_across
(where=(lowcase(_name_)=‘pct’)
rename=(drug_1=pct_1 drug_2=pct2));
by pays;
run;
Pour une information plus détaillées sur DISPLAY, ANALYSIS, GROUP, ORDER, ACROSS vous trouverez la page « Concept: REPORT procedure ». Notez que je n’ai pas parlé de COMPUTED, dans la même veine que GROUP, DISPLAY, ACROSS, ANALYSIS, mais que celle-ci permet de faire des calculs simples (sommation, etc).
Conclusion
En conclusion, la procédure REPORT est un outil qui, certes très puissant, peut vite devenir très compliqué. De mon expérience, il apparaît plus judicieux de restreindre l’usage de PROC REPORT à la diffusion de résultats préalablement agencés en triant les données avec des variables numériques non affichées et ne montrant que les variables textes.
Pour plus de détails sur la procédure REPORT, vous pouvez consulter le prochain article intitulé « 6 subtilités de PROC REPORT » et le chapitre PROC REPORT de la documentation en ligne.
Annexe:
data result_pat;
length pays_txt $10;
input pays pays_txt $ patient_id cnt pct;
datalines;
1 Maroc 1 10 20
1 Maroc 2 25 50
1 Maroc 3 15 30
2 Luxembourg 1 18 36
2 Luxembourg 2 32 64
3 Canada 1 5 100
;
run;
data result_drug;
input pays drug cnt pct;
datalines;
1 1 10 20
2 1 18 36
1 2 40 80
2 2 32 64
3 1 5 100
;
run;