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;

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

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

%put &anneefin ;

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

 

Pied de page des forums

Propulsé par FluxBB
Traduction par FluxBB.fr
Flux RSS