SAS Macro  •  Module EM  •  Corrigé
Exercices de synthèse — SAS Macro
M2 TIDE — Stage de programmation SAS — Enseignement 100 % distanciel
Objectifs du module
  • Mobiliser, sur des cas complets, l'ensemble des notions vues dans les modules VIII à X
  • Écrire des macro-programmes paramétrés qui produisent un résultat, une table ou un graphique
  • Réutiliser sans les recopier des tables produites lors des exercices de synthèse SAS Base

Avant de commencer

Cette page contient le corrigé complet des exercices donnés en devoir à l'issue du bloc SAS Macro (devoirs 7 à 9), réalisés en direct le lundi 14 septembre entre 17h00 et 19h30. Elle reste masquée pendant que vous travaillez et n'est publiée qu'à la clôture du dépôt, à 19h30. Plusieurs exercices réutilisent des tables produites dans la page Exercices de synthèse — SAS Base (temperatures, electric, cars) : veillez à les avoir sauvegardées dans votre bibliothèque MALIB plutôt que dans WORK.

Chaque question dispose de son propre corrigé, replié par défaut. La méthode en quatre étapes du module IX (programme fixe, puis %LET, puis %MACRO, puis macro-instructions) reste la bonne grille de lecture pour comprendre chaque solution, même quand l'énoncé ne le demandait pas explicitement.

Exercice 1 — %PRINT

Écrire un macro-programme %PRINT, avec les paramètres tab, varlist et n, qui affiche les n premières observations pour une liste de variables choisies dans une table donnée. Application sur SASHELP.IRIS avec une seule variable, puis avec une liste de variables.
Voir le corrigé
%macro print(tab, varlist, n) ;
    proc print data=&tab (obs=&n) noobs ;
        var &varlist ;
    run ;
%mend print ;

%print(sashelp.iris, sepallength, 5)

/* Avec une liste de variables, y compris via l'operateur -- qui selectionne */
/* toutes les variables de la table dans l'ordre entre les deux bornes      */
%print(sashelp.iris, sepallength--petalwidth, 20)

L'opérateur -- (double tiret) sélectionne toutes les variables de la table comprises, dans l'ordre de position, entre les deux bornes indiquées — pratique pour éviter de lister des dizaines de noms de variables consécutives.

Exercice 2 — Deux derniers caractères

En utilisant LENGTH, %EVAL et %SUBSTR, écrire un macro-programme qui renvoie les deux derniers caractères d'un mot donné par l'utilisateur. Essayez de rédiger l'instruction en une seule ligne.
Voir le corrigé
%macro ext_char(mot) ;
    %put %substr(&mot, %eval(%length(&mot)-1), 2) ;
%mend ext_char ;

%ext_char(IMIE)

/* Verification manuelle du mecanisme, sans macro-programme */
%put %substr(MARION, 5, 2) ;
%put %substr(MARION, %eval(%length(MARION)-1), 2) ;

Exercice 3 — %STATS

Écrire un macro-programme %STATS qui crée deux macro-variables : la moyenne et l'écart-type d'une variable. La bibliothèque, la table et la variable sont passées en paramètres. Exécuter sur SASHELP.IRIS.
Voir le corrigé
%macro stats(lib, tab, var) ;
    %let nom = %sysfunc(compress(&lib..&tab)) ;
    proc means data=&nom mean std ;
        var &var ;
        output out=resultat mean=moyenne std=ecart ;
    run ;
    data _null_ ;
        set resultat ;
        call symput("MA_MOYENNE", moyenne) ;
        call symput("MON_ECARTTYPE", ecart) ;
    run ;
    %put &MA_MOYENNE. ;
    %put &MON_ECARTTYPE. ;
%mend stats ;

%stats(sashelp, iris, sepallength)

Alternative sans macro-langage, avec la clause SELECT ... INTO : de la PROC SQL — une autre façon d'obtenir le même résultat, vue en détail dans le cours SAS SQL :
proc sql noprint ;
    select mean(sepallength) into :moyenne_sql
    from sashelp.iris ;
quit ;

%put &moyenne_sql. ;

Exercice 4 — %MOYENNE

Écrire un macro-programme %MOYENNE qui prend une table, une variable quantitative et une variable de groupe. Il doit calculer les moyennes par groupe, les sauvegarder et les représenter graphiquement. Utiliser ce programme pour automatiser les moyennes annuelles et mensuelles des précipitations et des températures de la table temperatures (exercice 2 des exercices de synthèse SAS Base).
Voir le corrigé
%macro moyenne(table, quanti, group) ;
    proc means data=&table mean ;
        var &quanti ;
        class &group ;
        output out=sortie mean=m ;
    run ;
    proc gplot data=sortie ;
        plot m*&group ;
    run ;
%mend moyenne ;

%moyenne(table=malib.temperatures, quanti=temp,  group=year)
%moyenne(table=malib.temperatures, quanti=temp,  group=month)
%moyenne(table=malib.temperatures, quanti=precp, group=year)
%moyenne(table=malib.temperatures, quanti=precp, group=month)

Ces quatre appels remplacent quatre blocs PROC MEANS + PROC GPLOT qui auraient dû être écrits à la main : c'est la démonstration la plus parlante de l'intérêt du macro-langage.

Exercice 5 — %FILTRE

À réaliser après avoir vu l'exercice 7 (factures d'électricité) des exercices de synthèse SAS Base.

Écrire un macro-programme %FILTRE qui prend une table, une liste de variables à afficher, deux bornes a et b (a < b) et une variable filtre. Il doit sélectionner les observations où la variable filtre est comprise entre a et b, et les afficher pour les variables demandées. Application : mois, année et montant pour les factures entre 150 et 200 dollars dans la table electric.
Voir le corrigé
%macro filtre(donnees=, var=, a=, b=, liste=) ;
    data resultat ;
        set &donnees ;
        if ((&a > &var) or (&b < &var)) then delete ;
    run ;
    proc print data=resultat ;
        var &liste ;
    run ;
%mend filtre ;

%filtre(donnees=malib.electric, var=bill, a=150, b=200, liste=year month bill)

Exercice 6 — %LISTE

1. Créer un macro-programme %LISTE qui renvoie la liste des produits différents dans SASHELP.PRDSALE, pour obtenir dans la LOG : PRODUIT_1 : BED, PRODUIT_2 : CHAIR, etc.
Voir le corrigé
proc sort data=sashelp.prdsale (keep=product) out=produits nodupkey ;
    by product ;
run ;

%macro liste ;
    data _null_ ;
        set produits ;
        call symput("PRODUIT_"||compress(_n_), product) ;
        call symput("OBS", _n_) ;
    run ;
    %do i=1 %to &OBS ;
        %put PRODUIT_&i. : &&PRODUIT_&i. ;
    %end ;
%mend liste ;

%liste
2. Ajouter un paramètre TYPE à %LISTE pour sélectionner un type de produit en particulier. Exécuter avec deux valeurs différentes.
Voir le corrigé
%macro liste(type=) ;
    proc sort data=sashelp.prdsale (where=(prodtype="&type.") keep=prodtype product)
              out=produits nodupkey ;
        by product ;
    run ;

    data _null_ ;
        set produits ;
        call symput("PRODUIT_"||compress(_n_), product) ;
        call symput("OBS", _n_) ;
    run ;
    %do i=1 %to &OBS ;
        %put &type. - PRODUIT_&i. : &&PRODUIT_&i. ;
    %end ;
%mend liste ;

%liste(type=FURNITURE)
%liste(type=OFFICE)

Exercice 7 — %PRIX_MOYEN

Utilise la table cars produite à l'exercice 1 (question 1) des exercices de synthèse SAS Base.

Écrire un macro-programme %PRIX_MOYEN qui calcule le prix moyen de vente pour une marque et un modèle de voiture donnés.
Voir le corrigé
%macro prix_moyen(marque=, modele=) ;
    proc means data=malib.cars (where=(make="&marque" and model="&modele")) mean ;
        var price ;
    run ;
%mend prix_moyen ;

%prix_moyen(marque=Buick, modele=Lacrosse)

Exercice 8 — %DEVINEZ

Écrire un macro-programme %DEVINEZ qui fait deviner un nombre entre 1 et 10. Initialiser une macro-variable alea contenant le nombre à trouver (ou tirée aléatoirement avec RAND), et une macro-variable de compteur de coups initialisée à 0. Le macro-programme prend en paramètre NB, la proposition testée.
Voir le corrigé
/* Tirage du nombre a deviner */
%let alea = %eval(%sysfunc(int(%sysevalf(%sysfunc(rand(uniform))*10))) + 1) ;
%put &alea ;

%let nb_coups = 0 ;

%macro devinez(nb=) ;
    %if &nb < &alea %then %do ;
        %put Plus grand ;
        %let nb_coups = %eval(&nb_coups + 1) ;
    %end ;
    %else %if &nb > &alea %then %do ;
        %put Plus petit ;
        %let nb_coups = %eval(&nb_coups + 1) ;
    %end ;
    %else %do ;
        %put BRAVO ! Trouve en &nb_coups coups. ;
    %end ;
%mend devinez ;

%devinez(nb=5)
%devinez(nb=3)
%devinez(nb=7)

Comme dans l'exercice du module X sur ce même thème, le compteur NB_COUPS doit être déclaré en dehors du macro-programme (environnement GLOBAL) pour survivre d'un appel à l'autre.
Modifié le: lundi 14 septembre 2026, 11:05
Accessibilité

Couleur de fond Couleur de fond

Police Police

Crénage de la police Crénage de la police

Visibilité de l’image Visibilité de l’image

Hauteur de ligne Hauteur de ligne

1.2

Surbrillance de lien Surbrillance de lien

Alignement du texte Alignement du texte

Taille de police Taille de police

1

Espacement des lettres Espacement des lettres

0

Couleur de texte Couleur de texte

Largeur de paragraphe Largeur de paragraphe

0