Annonce

Bienvenue sur le site support de mes ouvrages d'introduction à SAS

La 4ème édition de mon ouvrage est disponible depuis le 11 avril 2019 !

Où trouver cet ouvrage ?


#1 09-05-2019 08:55:50

SAS-SR
Administrateur
Lieu: Université d'Orléans
Date d'inscription: 01-09-2008
Site web

sujet examen macro sous SAS 2019

et si nous corrigions, ensemble, le sujet de l'examen de langage macro sous SAS que j'ai proposé aux étudiants du M1 ESA le 29 avril dernier ?

voici le sujet :

Ah… la comptabilité nationale…. Ma passion…. Surtout le tableau T_2201… vous ne le connaissez pas ? vous avez tort ! Ce tableau a pour objet de présenter la Consommation finale effective des ménages par fonction à prix courants, sur la période 1959-2017.

Il est présenté dans le fichier Excel que vous venez de recevoir. La consommation des ménages est partagée en 12 postes (01 : produits alimentaires et boissons non alcoolisées, 02 : Boissons alcoolisées, tabac et stupéfiants…), le poste 15 (Solde territorial) est là pour faire la balance (la somme des postes 01 à 15 doit donner ce que vous observez à la ligne total (Dépense de consommation finale des ménages). Viennent ensuite les Dépenses de consommation individuelle des institutions sans but lucratif au service des ménages et les Dépenses de consommation individuelle des administrations publiques. Vous faites la sommes des postes 01 à 15, des dépenses des institutions sans but lucratif et des administrations, vous arrivez à la consommation finale effective des ménages (mais comme vous vous souvenez de vos cours de comptabilité nationale, vous le saviez déjà).

Nous allons nous concentrer sur les dépenses par poste (lignes 01 à 12) et à la somme des lignes 01 à 12 + 15 (Dépense de consommation finale des ménages) – les lignes suivantes (13 – 14 et le dernier total) ne seront pas considérées par notre analyse.

Parce que oui, nous souhaitons mener une analyse.

Il se dit régulièrement que les dépenses liées au logement prenaient une part de plus en plus importante dans le budget des ménages et que l’alimentation prenait une part de moins en moins importante. Nous allons vérifier ici au moyen de la part que prennent ces dépenses dans les dépenses de consommation finale des ménages.

J’ai donc rédigé ce programme :

Code:

libname conso XLSX "C:\Users\Sebastien\Documents\Master ESA\M1 2018-2019\exam macro session 1\t_2201.xlsx";

** petit rappel : l'instruction LIBNAME ne fonctionne pas si le fichier XLXS est ouvert dans Excel ;

data temp ;
set conso.t_2201 ;
where _2_201_Consommation_finale_effec="04" 
   or _2_201_Consommation_finale_effec contains "Total:";
run;

** j'ai bien entendu "regardé" ma table pour savoir que les dépenses liées au logement, c'était le poste 04 et que pour
trouver la ligne qui correspond à la Dépense de consommation finale des ménages, il fallait que la modalité de la 
première variable (au nom étrange, je le concède), contiennent la chaine "Total:" ;

proc transpose data=temp out=temp2;
run;

** on transpose...;

data temp3;
  set temp2;
  part1=col1/col2;
  keep part1;
run;

** et on calcule une première part – on ne conserve que cette variable ;

data temp4 ;
set conso.t_2201 ;
where _2_201_Consommation_finale_effec="01" 
   or _2_201_Consommation_finale_effec contains "Total:";
run;

** même manoeuvre avec les dépenses liées à l'alimentation ;

proc transpose data=temp4 out=temp5;
run;

data temp6;
  set temp5;
  part2=col1/col2;
  keep part2;
run;

data temp7;
   merge temp3 temp6;
   retain annee 1958;
   annee=annee+1;
run;

** temp3 et temp6 ont forcément le même nombre d'observations, on peut merger les deux tables sans instruction BY ;
** et on recrée une variable ANNEE ;

Title 'Part de la dépense Logement, eau, gaz, électricité et autres combustibles';
Title2 'et part de la dépense Produits alimentaires et boissons non alcoolisées' ;
title3 'dans la dépense de consommation finale des ménages';
footnote "Source : Comptabilité nationale, tableau T_2201 et calculs de l'auteur";
proc sgplot data=temp7;
   yaxis display=(nolabel);
   xaxis display=(nolabel);
   series x=annee y=part1 / lineattrs=(thickness=2pt) 
          curvelabel='On est passé de 10.9% à 26.6%' 
          curvelabelloc=inside name='a';
   series x=annee y=part2 / lineattrs=(thickness=2pt) 
          curvelabel='On est passé de 25.9% à 13.4%' 
          curvelabelloc=inside name='b';
   inset "Période d'observation : 1959-2017" / position=bottomright;
   format part1 nlpct10.1;
   label part1='Logement, eau, gaz, électricité et autres combustibles'
         part2='Produits alimentaires et boissons non alcoolisées';
   keylegend "a" "b" ;
run;

** vous remarquez que j’ai entré des informations « à la main »… mais vous allez bientôt arranger cela…

et on obtient :

http://www.sas-sr.com/img/macro_2019_1.png

Rudement chouette…

Votre objectif :

Construire un macro programme paramétré qui va donner les résultats que nous décrivons maintenant :

Admettons que ce programme s’appelle TOTO. Si vous demandez l’exécution suivante :
%toto(liste) (ou %toto(Liste), ou %toto (LISTE) etc. ), vous devez voir apparaître le tableau suivant :

http://www.sas-sr.com/img/macro_2019_2.png

Parce que tout le monde ne connait pas, comme vous, par cœur les codes de la nomenclature des types de consommation des ménages…

Vous placerez au-dessus de ce tableau le titre suivant :

Voici les codes et les types de consommation associés

Vous devinez qu’in fine que vous allez devoir produire un graphique identique au mien si vous demandez l’exécution suivante :
%toto(04,01)

Mais, si, au lieu de %toto(04,01), vous demandez %toto(4,01) ou %toto(04,1) ou %toto(4,1) ou %toto(27,52) ou %toto(zz,xx) etc… refaites apparaître le tableau précédent en ajoutant le titre suivant :

Les paramètres du macro-programme doivent impérativement être compris entre 01 et 12.

Si vous demandez l’exécution suivante : %toto(04,04), faites à nouveau apparaitre le tableau accompagné du titre suivant :

Ce serait bien de pouvoir comparer 04 (et là vous rappelez ce que signifie ce type de consommation 04) avec autre chose que lui-même…

Bon, maintenant qu’on a prévu tous les mauvais usages que pourrait faire un utilisateur de votre macro, voyons ce qui doit se passer si votre macro-programme est utilisé correctement.

http://www.sas-sr.com/img/macro_2019_3.png

J’ai entouré tous les éléments qui devront obligatoirement s’adapter à votre demande d’exécution.


le fichier Excel peut être téléchargé en suivant ce lien

voici le programme débarrassé des commentaires :

Code:

libname conso XLSX "C:\Users\Sebastien\Documents\Master ESA\M1 2018-2019\exam macro session 1\t_2201.xlsx";

data temp ;
set conso.t_2201 ;
where _2_201_Consommation_finale_effec="04" 
   or _2_201_Consommation_finale_effec contains "Total:";
run;

proc transpose data=temp out=temp2;
run;

data temp3;
  set temp2;
  part1=col1/col2;
  keep part1;
run;

data temp4 ;
set conso.t_2201 ;
where _2_201_Consommation_finale_effec="01" 
   or _2_201_Consommation_finale_effec contains "Total:";
run;

proc transpose data=temp4 out=temp5;
run;

data temp6;
  set temp5;
  part2=col1/col2;
  keep part2;
run;

data temp7;
   merge temp3 temp6;
   retain annee 1958;
   annee=annee+1;
run;

Title 'Part de la dépense Logement, eau, gaz, électricité et autres combustibles';
Title2 'et part de la dépense Produits alimentaires et boissons non alcoolisées' ;
title3 'dans la dépense de consommation finale des ménages';
footnote "Source : Comptabilité nationale, tableau T_2201 et calculs de l'auteur";
proc sgplot data=temp7;
   yaxis display=(nolabel);
   xaxis display=(nolabel);
   series x=annee y=part1 / lineattrs=(thickness=2pt) 
          curvelabel='On est passé de 10.9% à 26.6%' 
          curvelabelloc=inside name='a';
   series x=annee y=part2 / lineattrs=(thickness=2pt) 
          curvelabel='On est passé de 25.9% à 13.4%' 
          curvelabelloc=inside name='b';
   inset "Période d'observation : 1959-2017" / position=bottomright;
   format part1 nlpct10.1;
   label part1='Logement, eau, gaz, électricité et autres combustibles'
         part2='Produits alimentaires et boissons non alcoolisées';
   keylegend "a" "b" ;
run;

vous avez deux heures...

Hors ligne

 

#2 15-05-2019 14:49:36

SAS-SR
Administrateur
Lieu: Université d'Orléans
Date d'inscription: 01-09-2008
Site web

Re: sujet examen macro sous SAS 2019

Bon...

nous avons essentiellement deux choses à faire :
1- gérer le mauvais usage qui pourrait être fait du macro-programme
2- produire le graphique quand le macro-programme est utilisé à bon escient.

commençons par produire le graphique et surtout, ne commençons pas par une instruction %MACRO....

un macro-programme, c'est au départ un programme SAS qui fonctionne et si vous attaquez bille en tête par un sandwich %macro / %mend, quand vous demandez une exécution de votre macro programme, si ça ne marche pas, vous aurez bien du mal à trouver pourquoi... est-ce lié à vos éléments de macro programmation ou alors à votre programme en langage SAS "non macro" ?

je le dis, je l'écris (section 10.6.2 ED4), j'insiste... mais j'ai toujours des étudiants qui ne m'écoutent pas....

alors procédons avec ordre et méthode : on dispose déjà du programme qui produit un résultat correct, introduisons quelques macro-variables...

Code:

%let p1=04 ;
%let p2=01;

voilà qui commence bien !

ensuite...

nous allons avoir besoin pour la légende du graphique et pour son titre de l'intitulé en clair des types de dépense analysés par le graphique. Pour le premier type de consommation, on va pour cela légèrement modifier notre première étape DATA qui devient :

Code:

data temp ;
   set conso.t_2201 ;
   where _2_201_Consommation_finale_effec="&p1" 
      or _2_201_Consommation_finale_effec contains "Total:";
   if _2_201_Consommation_finale_effec="&p1" then call symputx("conso1",b);
run;

pas plus compliqué que cela...

il va nous falloir présenter dans le graphique la période d'observation des données : on imagine ici que le programme doit pouvoir offrir un graphique correct si dans votre fichier excel de départ couvre une autre période que 1959-2017... pour cela, il faut faire des hypothèses :

1- l'année la plus ancienne est toujours présentées dans la troisième colonne de la feuille Excel (variable C une fois que LIBNAME XLSX a "vu" votre fichier Excel)
2- elle est toujours présentée sur la troisième ligne du fichier Excel / seconde observation du fichier Excel vu par LIBNAME EXCEL.

ainsi, pour capturer dans une macro variable l'année de départ des observations, vous pouvez procéder comme suit :

Code:

data _null_;
   set conso.t_2201;
   if _n_=2 then call symputx("anneedeb",c);
run;

pour l'année de fin, on verra plus tard...

le proc transpose qui suit n'est pas modifié. Dans l'étape DATA qui suit, on calcule les parts et comme nous allons avoir besoin de ces parts pour les présenter dans l'étiquette de la courbe, on va compléter notre étape data :

Code:

proc transpose data=temp out=temp2;
run;

data temp3;
  set temp2 end=last;
  part1=col1/col2;
  keep part1;
  if _n_=1 then call symputx("debc1",put(part1,nlpct8.1));
  if last=1 then call symputx("finc1",put(part1,nlpct8.1));
run;

vous stockez ainsi sous la forme xx,x% la part observée pour la première année de vos observations et pour la dernière année de l'observation.

on va faire la même chose pour le second type de dépense (sans la construction de la macro qui contient l'année qui débute la période d'observation puisqu'on en dispose déjà) :

Code:

data temp4 ;
set conso.t_2201 ;
where _2_201_Consommation_finale_effec="&p2" 
   or _2_201_Consommation_finale_effec contains "Total:";
   if _2_201_Consommation_finale_effec="&p2" then call symputx("conso2",b);
run;

proc transpose data=temp4 out=temp5;
run;

data temp6;
  set temp5 end=last;
  part2=col1/col2;
  keep part2;
  if _n_=1 then call symputx("debc2",put(part2,nlpct8.1));
  if last=1 then call symputx("finc2",put(part2,nlpct8.1));
run;

on fait un break en vérifiant que les macro-variables demandées ont bien été construites :

Code:

%put conso1= &conso1 ;
%put conso2= &conso2 ;
%put anneedeb= &anneedeb ;
%put debc1=&debc1;
%put finc1=&finc1;
%put debc2=&debc2;
%put finc2=&finc2;

pourquoi ce break maintenant ? parce que nous allons maintenant utiliser ces macro-variables et qu'avant d'utiliser des macro-variables, ce n'est peut être pas idiot de vérifier qu'elles existent bien et qu'elles ont les bonnes valeurs...

la suite : on réunit les deux tables contenant les parts et on crée la variable ANNEE :

Code:

data temp7;
   merge temp3 temp6 end=last;
   retain annee &anneedeb;
   annee=annee+1;
   if last then call symputx("anneefin",annee);
run;

Dans la série, on en apprend tous les jours, je vous présente l'option END= de l'instruction MERGE (je vous promets que je ne savais pas, jusqu'à aujourd'hui, que cette option était aussi possible pour MERGE (on n'en a pas besoin tous les jours quand même....))

vous vérifiez que la macro-variable anneefin est correctement construite et il n'y a plus qu'à construire le graphique - on reprend le programme proposé la semaine dernière en replaçant déjà les quotes simples par des quotes doubles puis en introduisant nos macro variables.

le coup des quotes simples à remplacer par des quotes doubles, je le fais chaque année... si un étudiant qui passe un examen de langage macro sous SAS ne sait pas qu'un appel de macro-variable n'est pas résolu s'il est placé entre quotes simples, ben... ça en dit beaucoup sur son degré de préparation à l'examen...

bref...

la dernière partie du programme devient donc :

Code:

Title "Part de la dépense &conso1";
Title2 "et part de la dépense &conso2" ;
title3 'dans la dépense de consommation finale des ménages';
footnote "Source : Comptabilité nationale, tableau T_2201 et calculs de l'auteur";
proc sgplot data=temp7;
   yaxis display=(nolabel);
   xaxis display=(nolabel);
   series x=annee y=part1 / lineattrs=(thickness=2pt) 
          curvelabel="On est passé de &debc1 à &finc1%" 
          curvelabelloc=inside name='a';
   series x=annee y=part2 / lineattrs=(thickness=2pt) 
          curvelabel="On est passé de &debc2 à &finc2" 
          curvelabelloc=inside name='b';
   inset "Période d'observation : &anneedeb-&anneefin" / position=bottomright;
   format part1 nlpct10.1;
   label part1="&conso1"
         part2="&conso2";
   keylegend "a" "b" ;
run;

et voilà.

vous avez un graphique correct.

Nous insèrerons ce programme dans le macro-programme que nous construirons la semaine prochaine...

en attendant, voici le programme complet :

Code:

%let p1=04 ;
%let p2=01;

data temp ;
   set conso.t_2201 ;
   where _2_201_Consommation_finale_effec="&p1" 
      or _2_201_Consommation_finale_effec contains "Total:";
   if _2_201_Consommation_finale_effec="&p1" then call symputx("conso1",b);
run;

data _null_;
   set conso.t_2201;
   if _n_=2 then call symputx("anneedeb",c);
run;

proc transpose data=temp out=temp2;
run;

data temp3;
  set temp2 end=last;
  part1=col1/col2;
  keep part1;
  if _n_=1 then call symputx("debc1",put(part1,nlpct8.1));
  if last=1 then call symputx("finc1",put(part1,nlpct8.1));
run;

data temp4 ;
set conso.t_2201 ;
where _2_201_Consommation_finale_effec="&p2" 
   or _2_201_Consommation_finale_effec contains "Total:";
   if _2_201_Consommation_finale_effec="&p2" then call symputx("conso2",b);
run;

proc transpose data=temp4 out=temp5;
run;

data temp6;
  set temp5 end=last;
  part2=col1/col2;
  keep part2;
  if _n_=1 then call symputx("debc2",put(part2,nlpct8.1));
  if last=1 then call symputx("finc2",put(part2,nlpct8.1));
run;

data temp7;
   merge temp3 temp6 end=last;
   retain annee &anneedeb;
   annee=annee+1;
   if last then call symputx("anneefin",annee);
run;

Title "Part de la dépense &conso1";
Title2 "et part de la dépense &conso2" ;
title3 'dans la dépense de consommation finale des ménages';
footnote "Source : Comptabilité nationale, tableau T_2201 et calculs de l'auteur";
proc sgplot data=temp7;
   yaxis display=(nolabel);
   xaxis display=(nolabel);
   series x=annee y=part1 / lineattrs=(thickness=2pt) 
          curvelabel="On est passé de &debc1 à &finc1%" 
          curvelabelloc=inside name='a';
   series x=annee y=part2 / lineattrs=(thickness=2pt) 
          curvelabel="On est passé de &debc2 à &finc2" 
          curvelabelloc=inside name='b';
   inset "Période d'observation : &anneedeb-&anneefin" / position=bottomright;
   format part1 nlpct10.1;
   label part1="&conso1"
         part2="&conso2";
   keylegend "a" "b" ;
run;

à suivre

Hors ligne

 

#3 Aujourd'hui 07:47:23

SAS-SR
Administrateur
Lieu: Université d'Orléans
Date d'inscription: 01-09-2008
Site web

Re: sujet examen macro sous SAS 2019

concluons ce sujet.

A ce stade, nous savons quoi faire si un graphique est à produire.

Il nous reste à voir comment faire pour obtenir une liste des valeurs possibles des différents types de consommation, pour obtenir un résultat particulier si au moins une des valeurs des deux paramètres n'est pas comprise entre 01 et 12 (seules valeurs autorisées) et si vous indiquez la même valeurs pour les deux paramètres.

Ici aussi, plutôt que d'attaquer "bille en tête" en mélangeant des instructions macro avec des instructions "langage SAS non macro", il peut être intéressant de construire au préalable un "prototype" en ne mobilisant que des instructions macro.

L'idée, c'est ici de construire un premier macro programme qui aura l'allure suivante :

Code:

%macro proto(p1,p2);
%if ... %then %do ;
   %put le premier résultat possible ;
%end;
%else %if ... %then %do ;
   %put le deuxième résultat possible ;
%end;

%etc

%mend;

Quand on disposera d'une structure qui offre bien les bons embranchements, alors on pourra ajouter des choses (comme par exemple le programme construit la semaine dernière...).

Notre macro programme doit avoir deux paramètres mais il faut qu'il produise un résultat si on demande une liste des valeurs possibles.

Avons nous besoin d'un troisième paramètre ?
la réponse est non.

petit prototype pour vérifier cela :

Code:

%macro proto(p1,p2);
   %if &p1=liste %then %do ;
      %put p1 est égal à &p1 ;
   %end;
   %else %do ;
      %put valeur de p1 : &p1;
      %put valeur de p2 : &p2;
   %end;
%mend;
%test(liste)

et que voyez vous dans votre journal ?

Code:

423  %test(liste)
p1 est égal à liste

si vous spécifiez liste en premier paramètre de votre macro programme, le fait de ne pas spécifier de valeur au second n'empêche absolument pas son exécution.

Dans le sujet on indique que liste,LISTE, LIstE etc. doivent produire la liste. Votre condition doit être modifiée en :

Code:

   %if %upcase(&p1)=LISTE %then %do ;

donc, poursuivons : si P1 et P2 sont tous les deux compris entre 01 et 12 (mais qu'ils sont différents l'un de l'autre), alors on veut un graphique

Code:

options minoperator ;
%macro proto(p1,p2);
   %if %upcase(&p1)=LISTE %then %do ;
      %put p1 est égal à &p1 ;
   %end;
   %else %if &p1 in (01 02 03 04 05 06 07 08 09 10 11 12) and
             &p2 in (01 02 03 04 05 06 07 08 09 10 11 12) %then %do ;
      %if &p1 ne &p2 %then %do ;
         %put on va faire un graphique ;
      %end;
      %else %do ;
          %put on produit le résultat lorsque p1 et p2 sont identiques;
      %end;
   %end;
%mend;

%proto(liste)
%proto(01,02)
%proto(01,01)

et vous obtenez dans votre journal :

Code:

496  %proto(liste)
p1 est égal à liste
497  %proto(01,02)
on va faire un graphique
498  %proto(01,01)
on produit le résultat lorsque p1 et p2 sont identiques

nous avons besoin au préalable d'activer l'option globale MINOPERATOR puisque nous utilisons IN dans notre macro programme.

vous pourriez juger le in (01 02 03 04 05 06 07 08 09 10 11 12) peu élégant... et je le confirme... on pouvait tout à fait remplacer la liste des valeurs possibles par l'appel à une macro variable contenant cette liste construite, soit au moyen de PROC SQL :

Code:

proc sql noprint;
   select _2_201_Consommation_finale_effec into :liste separated by " "
      from conso.t_2201
      where _2_201_Consommation_finale_effec between '01' and '12';
quit ;

(mais mes étudiants de première année n'ont pas encore eu leur cours PROC SQL)

on pouvait aussi passer par une étape data :

Code:

data _null_;
   set conso.t_2201 end=last;
   where _2_201_Consommation_finale_effec between '01' and '12';
   length liste $ 200 ;
   retain liste;
   liste=catx(" ",liste,_2_201_Consommation_finale_effec);
   if last then call symputx ("liste",liste);
run;

(vous remarquerez que ce dernier programme est quand même très proche de l'exemple "Léa Frédéric Subira Luc" de la section 3.6... (page 219 ED4)).

bref...

que nous reste-t-il à faire ?

Traiter le cas où au moins un des deux paramètres ne serait pas compris entre 01 et 12...

il ne nous manque qu'un %else %do final...

Code:

%macro proto(p1,p2);
   %if %upcase(&p1)=LISTE %then %do ;
      %put p1 est égal à &p1 ;
   %end;
   %else %if &p1 in (01 02 03 04 05 06 07 08 09 10 11 12) and
             &p2 in (01 02 03 04 05 06 07 08 09 10 11 12) %then %do ;
      %if &p1 ne &p2 %then %do ;
         %put on va faire un graphique ;
      %end;
      %else %do ;
          %put on produit le résultat lorsque p1 et p2 sont identiques;
      %end;
   %end;
   %else %do;
      %put si on arrive ici, au moins un des deux paramètres ne convient pas ;
   %end;
%mend;

%proto(liste)
%proto(01,02)
%proto(01,01)
%proto(01,zozo)
%proto(zozo,01)
%proto(zozo,zozo)

et votre journal vous confirme que votre prototype est terminé. Il ne nous reste plus qu'à le "remplir" mais ici aussi, on ne fonce pas bille en tête !

Avant d'insérer quoi que ce soit dans notre prototype, voyons comment, sans macro programmation obtenir les résultats demandés dans le sujet :

Le tableau est obtenu de la façon suivante :

Code:

proc print data=conso.t_2201 label noobs;
   var _2_201_Consommation_finale_effec b;
   label _2_201_Consommation_finale_effec="code"
         b="Type de consommation";
   where _2_201_Consommation_finale_effec is not missing;
run;

Ensuite, seuls les titres changent. Dans deux cas (liste et p1 et/ou p2 non conformes aux valeurs possibles), ces titres peuvent être saisis "à la main".

Lorsque p1 et p2 sont identiques et compris en 01 et 12, il faut compléter le programme :

Code:

data _null_;
  set conso.t_2201;
  where _2_201_Consommation_finale_effec="&p1";
  call symputx ("typec",b);
run;

Title "Ce serait bien de pouvoir comparer &p1 (&typec) avec autre chose que lui-même…";
* +production du tableau;

et voilà ! il n'y a plus qu'à assembler :

Code:

%macro final(p1,p2);
   title ; foonote ; 
   %if %upcase(&p1)=LISTE %then %do ;
      title "Voici les codes et les types de consommation associés";
      proc print data=conso.t_2201 label noobs;
         var _2_201_Consommation_finale_effec b;
         label _2_201_Consommation_finale_effec="code"
               b="Type de consommation";
         where _2_201_Consommation_finale_effec is not missing;
      run;
   %end;
   %else %if &p1 in (01 02 03 04 05 06 07 08 09 10 11 12) and
             &p2 in (01 02 03 04 05 06 07 08 09 10 11 12) %then %do ;
      %if &p1 ne &p2 %then %do ;

data temp ;
   set conso.t_2201 ;
   where _2_201_Consommation_finale_effec="&p1" 
      or _2_201_Consommation_finale_effec contains "Total:";
   if _2_201_Consommation_finale_effec="&p1" then call symputx("conso1",b);
run;

data _null_;
   set conso.t_2201;
   if _n_=2 then call symputx("anneedeb",c);
run;

proc transpose data=temp out=temp2;
run;

data temp3;
  set temp2 end=last;
  part1=col1/col2;
  keep part1;
  if _n_=1 then call symputx("debc1",put(part1,nlpct8.1));
  if last=1 then call symputx("finc1",put(part1,nlpct8.1));
run;

data temp4 ;
set conso.t_2201 ;
where _2_201_Consommation_finale_effec="&p2" 
   or _2_201_Consommation_finale_effec contains "Total:";
   if _2_201_Consommation_finale_effec="&p2" then call symputx("conso2",b);
run;

proc transpose data=temp4 out=temp5;
run;

data temp6;
  set temp5 end=last;
  part2=col1/col2;
  keep part2;
  if _n_=1 then call symputx("debc2",put(part2,nlpct8.1));
  if last=1 then call symputx("finc2",put(part2,nlpct8.1));
run;

data temp7;
   merge temp3 temp6 end=last;
   retain annee &anneedeb;
   annee=annee+1;
   if last then call symputx("anneefin",annee);
run;

Title "Part de la dépense &conso1";
Title2 "et part de la dépense &conso2" ;
title3 'dans la dépense de consommation finale des ménages';
footnote "Source : Comptabilité nationale, tableau T_2201 et calculs de l'auteur";
proc sgplot data=temp7;
   yaxis display=(nolabel);
   xaxis display=(nolabel);
   series x=annee y=part1 / lineattrs=(thickness=2pt) 
          curvelabel="On est passé de &debc1 à &finc1%" 
          curvelabelloc=inside name='a';
   series x=annee y=part2 / lineattrs=(thickness=2pt) 
          curvelabel="On est passé de &debc2 à &finc2" 
          curvelabelloc=inside name='b';
   inset "Période d'observation : &anneedeb-&anneefin" / position=bottomright;
   format part1 nlpct10.1;
   label part1="&conso1"
         part2="&conso2";
   keylegend "a" "b" ;
run;
      %end;
      %else %do ;
         data _null_;
           set conso.t_2201;
           where _2_201_Consommation_finale_effec="&p1";
           call symputx ("typec",b);
         run;
         Title "Ce serait bien de pouvoir comparer &p1 (&typec) avec autre chose que lui-même…";
         proc print data=conso.t_2201 label noobs;
            var _2_201_Consommation_finale_effec b;
            label _2_201_Consommation_finale_effec="code"
                  b="Type de consommation";
            where _2_201_Consommation_finale_effec is not missing;
         run;
      %end;
   %end;
   %else %do;
      Title "Les paramètres du macro-programme doivent impérativement être compris entre 01 et 12.";
      proc print data=conso.t_2201 label noobs;
         var _2_201_Consommation_finale_effec b;
         label _2_201_Consommation_finale_effec="code"
               b="Type de consommation";
         where _2_201_Consommation_finale_effec is not missing;
      run;
   %end;
%mend;


%final(liste)
%final(01,02)
%final(01,01)
%final(01,zozo)
%final(zozo,01)
%final(zozo,zozo)
%final(06,08)

et ça marche...

évidemment, pour que votre macro programme fonctionne, ne pas oublier au préalable l'instruction LIBNAME XSLX ainsi que l'option MINOPERATOR.

vous remarquerez aussi au passage au début du macro programme deux instructions globales TITLE et FOOTNOTE.

Elles me permettent d'être certain que les titres et pieds de page seront bien définis à chaque exécution du macro programme.
Pour vous convaincre de l'utilité de ces instructions, retirez l'instruction footnote puis demandez les deux exécutions suivantes :

Code:

%final(06,08)
%final(liste)

et regardez le pied de page du dernier tableau produit.

Ce sujet est maintenant terminé.

A tout de suite pour un nouveau sujet des beaux mercredis

Hors ligne

 

Pied de page des forums

Propulsé par FluxBB
Traduction par FluxBB.fr
Flux RSS