macro SAS9

Déboguer une Macro pour des Tableaux de Fréquence

Simon 20/05/2021 0 views

L'automatisation des tâches répétitives est l'une des grandes forces de SAS©, notamment pour traiter de grandes enquêtes ("large scale surveys"). Cependant, le passage de paramètres — comme des libellés (labels) ou des formats — à l'intérieur d'une macro est une source fréquente d'erreurs syntaxiques.

Note :
Le Besoin : Automatiser PROC FREQ avec des métadonnées
L'utilisateur souhaite créer une macro %f_freq pour générer des tables de fréquences. Ses contraintes sont précises :

La sortie doit être une table de données (OUT=).

La variable doit être formatée (regroupement des valeurs).

Un label spécifique (souvent long) doit être attribué à la variable dans la table de sortie, défini au préalable via un %LET.

Le code problématique :
1%let Q1_label='Texte très long pour la question 1...';
2 
3%macro f_freq(var, var_w, var_label);
4 PROC FREQ DATA=clean_data order=freq;
5 TABLE &var / out=freqout.freq_&var;
6 FORMAT &var &var_w;
7 label &var=&var_label; /* Assigne le label */
8 RUN;
9%mend;
10 
11/* L'appel qui ne fonctionne pas comme prévu */
12%f_freq(Q1, Q1_w., Q1_label);
Note :
L'Erreur : La résolution des variables macro (&)
Comme l'a souligné la réponse sur le forum, l'erreur ne se situe pas dans la définition de la macro, mais dans son appel.

L'utilisateur a écrit : %f_freq(Q1, Q1_w., Q1_label);

Le problème : SAS© interprète le troisième paramètre littéralement comme le texte "Q1_label". Conséquence : Dans la procédure, SAS© essaie d'exécuter label Q1 = Q1_label;, ce qui assigne le texte "Q1_label" comme étiquette, au lieu du texte contenu dans la variable (le "Texte très long...").

La solution : Il faut utiliser le signe & (ampersand) pour dire à SAS© de résoudre la variable avant de l'envoyer à la macro.
1/* Appel corrigé */
2%f_freq(Q1, Q1_w., &Q1_label);
3 

L'impact des Formats et Labels sur PROC FREQ

L'expert qui a répondu soulève un point technique intéressant : "Je pense que le format et le label sont utilisés pour l'affichage... Je ne pense pas qu'ils affectent l'agrégation."

Il est important de clarifier ce comportement dans SAS© :

  1. Les Formats (FORMAT) : Ils affectent l'agrégation. Si vous appliquez un format qui regroupe les valeurs (par exemple, transformer 1, 2, 3 en "Petit"), PROC FREQ calculera la fréquence pour "Petit". C'est essentiel pour le recodage à la volée.

  2. Les Labels (LABEL) : Ils n'affectent pas le calcul, mais ils sont cruciaux pour les métadonnées. L'instruction LABEL à l'intérieur de la procédure permet bien de stocker la description de la variable dans la table de sortie (OUT=).

Note :
Les bonnes pratiques de débogage
Pour éviter ce genre de confusion entre le nom d'une variable et son contenu, voici deux conseils tirés de la discussion :

Utiliser %PUT : Avant de lancer une procédure complexe, affichez les valeurs dans la journal (Log) pour vérifier ce que la macro reçoit vraiment.
1%macro f_freq(var, var_w, var_label);
2 %put NOTE: La variable est &var;
3 %put NOTE: Le label reçu est &var_label;
4 /* ... reste du code ... */
5%mend;
Attention aux Quotes : Si votre label contient déjà des guillemets (comme défini dans %let Q1_label='...'), assurez-vous de ne pas en rajouter dans l'instruction label &var=&var_label;.

L'écriture de macros nécessite une rigueur particulière sur la portée des variables. Rappelez-vous toujours : si vous voulez passer le contenu d'une variable définie par un %LET, vous devez impérativement utiliser le préfixe & lors de l'appel.

References & Docs