LE MACRO

In alcune occasioni ci troviamo nella condizione di dover eseguire del codice più volte durante il programma oppure una parte di programma farebbe al caso nostro anche in altre occasioni. Ad esempio vogliamo scrivere un programma che prima di eseguire una regressione esegua la "miglior trasformazione" box-cox sulla variabile di risposta. Le macro rispondono a questo tipo di esigenze: la caratteristica principale delle macro è la flessibilità nei cambiamenti del codice e la creazione di codice modulare.

Tipicamente una macro accetta parametri in entrata, e produce dei risultati. Una volta creata e mandata in esecuzione la macro,il macro-processore di Sas processa e "produce" codice Sas che verrà eseguito.

Per distingurli dai comandi Sas. i comani macro seguono le seguenti regole:

Qui vedremo i concetti fondamentali delle macro.

 

Creare macro e variabili macro

Creare macro è abbastanza semplice e si fa con due comandi.

%macro nomemacro(parametri);
...comandi....
%mend nomemacro

La macro viene richiamata dal programma sas tramite il comando:

%nomemacro(parametri)

Assegnare una variabile macro è altrettanto semplice e si fa con il comando:

%let variabilemacro=valore;

Di seguito vediamo un esempio in cui creiamo una macro che manda in output dati "filtrati" secondo i paramatri passati alla macro:

%macro filtra(sc=, v=);                                      /*inizia la macro*/
proc sort data=salari out=filtrati;                          /*filtro i dati in base ai parametri creando un nuovo dataset*/
by &v;
where scuola=≻
proc print data=filtrati;                                     /*stampo i dati filtrati*/
title "dati  ordinati (per voto) della scuola &sc ";
%mend filtra;                                                 /*termina la macro*/
                                                       
data salari;                                                  /*importo i dati*/
infile "H:\datiprova\salari.dat" firstobs=2;
input   voto sal scuola $;
run;
%filtra(sc="LA",v=voto);                                      /*richiamo la macro*/
%filtra(sc="E",v=voto);                                     /*richiamo la macro con parametri diversi*         

Il data-set importato contiene informazioni su salari, voto di laurea e tipo di laurea. La macro filtra il data-set selezionando il tipo di scuola (parametro sc) e la variabile su cui ordinare; che in questo caso è il voto ma poteva essere anche il salario.

Codice macro "condizionato"

Una delle potenzialità delle macro sta nel fatto che si può sciegliere dinamicamente quale pezzo di codice (interno alla macro) mandare in esecuzione. Questo si ottiene grazie ai comandi macro:

%if condizione %then azione;                                          oppure                                   %if condizione    %then %do;                  
%else azione                                                                                                                    ...comandi...        
%end                                                                                                                               %end

Riprendiamo l'esempio di prima, solo che stavolta passiamo due variabili di ordinamento: il salario e il voto. Voglio ottenere due report diversi a seconda di qual'e la variabile la variabile di ordinamento passata.

%macro filtra(sc=, v=);                                      /*inizia la macro*/
%if &v=voto %then %do;                                       /*controllo se la variabile di ordinamento è il voto*/
    proc sort data=salari out=filtrati;                     
    by &v;
    where scuola=≻
    proc print data=filtrati;                                   
    title "dati  ordinati (per voto) della scuola " ≻
%end;                                                                      /*fine primo controllo*%
%if &v=sal %then %do;;                                       /*controllo se la variabile di ordinamento è il salario*/
    proc sort data=salari out=filtrati;                      
    by &v;
    where scuola=≻
    proc print data=filtrati;                                   
    title "dati  ordinati (per stipendio) della scuola " ≻
%end;                                                                    /*fine secondo controllo*/
%mend filtra;                                                       /*termina la macro*/
                                                       
data salari;                                                           /*importo i dati*/
infile "H:\datiprova\salari.dat" firstobs=2;
input   voto sal scuola $;
run;
%filtra(sc="LA",v=voto);                                  /*richiamo la macro e passo come variabile di ordinamento il voto*/
%filtra(sc="LA",v=sal);                                    /*richiamo la macro e passo come variabile di ordinamento il salario*/

Come si vede la macro produce  output diversi a seconda di quali sono i parametri passati

 
Creare variabili macro dinamicamente

In alcune occasioni non sappiamo a priori quali variabili macro creare, ma la decisione deve essere presa in run time ossia in maniera dinamica. Sas permette ciò grazie al comando:

call symput("nomevariabile",valore);

In questo modo sas crea una variabile macro di nome nomevariabile a le associa il valore valore. Riprendiamo ancora l'esempio di prima. Stavolta come filtro vogliamo il voto + basso del tipo di scuola che passiamo come parametro

%macro filtra(sc=, v=);                                              /*inizia la macro*/
proc sort data=salari out=filtrati;                          /*filtro i dati in base ai parametri creando un nuovo dataset*/
by &v;
where scuola=≻
data _null_ ;set filtrati;                                        /*considero il data-set filtrato*/
if _N_ = 1 then call symput ("piccolo",voto);    /*creo una variabile macro di nome piccolo a cui do il valore della prima osservazione del data-set filtrato(il minore)*/
proc print data=filtrati;
where &v=&piccolo;
title "il voto + piccolo è &piccolo per la  scuola " ≻
%mend filtra;                                                    /*termina la macro*/
                                                       
data salari;                                                        /*importo i dati*/
infile "H:\datiprova\salari.dat" firstobs=2;
input   voto sal scuola $;
run;
%filtra(sc="BUS",v=voto);  
%filtra(sc="LA",v=voto);
 

Come vediamo è stata creata una variabile dinamicamente. In questo caso le abbiamo attribuito il primo valore del dataset ordinato (il minore).