Questo in parte dipende da cosa sta facendo la tua macro. Se supponiamo che la tua macro stia facendo qualcosa che è destinato ad essere eseguito al di fuori di un passo di dati (cioè, non si tratta solo di assegnare una variabile del passaggio dati), allora hai diverse opzioni.
chiamata execute è già stato spiegato, ed è una buona opzione per alcuni casi. Ha alcuni aspetti negativi, tuttavia, in particolare con la temporizzazione delle macro, che richiede in alcuni casi un'attenzione particolare da proteggere, in particolare quando si creano variabili macro all'interno della macro. Quentin nei suoi commenti mostra un modo per aggirare questo problema (aggiungendo %NRSTR
alla chiamata), ma trovo che preferisco usare CALL EXECUTE solo quando c'è un vantaggio rispetto agli altri metodi - in particolare, se voglio usare SAS tecniche di step di dati (come FIRST o LAST, ad esempio, o qualche forma di looping) nella creazione delle mie macro chiamate, o quando devo fare comunque le cose in un passo di dati e posso evitare il sovraccarico di leggere il file un'altra volta. Se sto semplicemente scrivendo un passo di dati come il tuo qui sopra: dati qualcosa, imposta qualcosa, chiama execute, run - non lo userei.
PROC SQL SELECT INTO
è tipicamente quello che uso per l'elaborazione lista (che è in gran parte di cosa si tratta). Mi piace la semplicità di SQL un po 'meglio quando faccio cose che non sono troppo complicate; ad esempio, è possibile ottenere facilmente una sola versione di ciascuna macro chiamata con DISTINCT
senza dover scrivere esplicitamente un proc sort nodupkey
o utilizzare la prima/ultima elaborazione. Ha anche il vantaggio di eseguire il debug che è possibile scrivere tutte le chiamate macro alla finestra dei risultati (se non si aggiunge noprint
), che è un po 'più facile da leggere rispetto al registro per me se sto cercando di capire perché le mie chiamate non sono state generate correttamente (e non prende alcuna istruzione PUT in più).
proc sql;
select catx(',','%macro(',arg1,arg2,arg3)||')'
into :mvarlist separated by ' '
from dataset;
quit;
&mvarlist.
Che li corre molto semplicemente, e non ha problemi di temporizzazione (come si sta solo scrivendo un sacco di chiamate macro out).
Lo svantaggio principale di questo metodo è che hai un massimo di 64k caratteri in una variabile macro, quindi se stai scrivendo un numero enorme di questi ti imbatterai in quello. In tal caso, utilizzare i file CALL EXECUTE
o %INCLUDE
.
%INCLUDE
file sono in gran parte utile sia come ricambio per SELECT INTO
quando la chiamata è sopra il limite di caratteri, o se lo trovate utile avere un file di testo da guardare con le chiamate (se si sta eseguendo questo per esempio, in modalità batch, questo potrebbe essere più facile da raggiungere e/o analizzare rispetto all'output di registro o elenco). Basta scrivere le chiamate su un file, e quindi il file %INCLUDE
.
filename myfile temp; *or a real file if you want to look at it.;
data _null_;
set dataset;
file myfile;
put @1 catx(',','%macro(',arg1,arg2,arg3)||')';
run;
%include myfile;
non ho davvero usare questo molto più, ma è una tecnica comune usata soprattutto dai più anziani programmatori SAS così bello sapere.
DOSUBL
è un metodo relativamente nuovo, e in qualche misura può essere utilizzato per sostituire CALL EXECUTE
come il suo comportamento predefinito è in genere più vicino a quello che ci si aspetta in modo intuitivo di CALL EXECUTE
's. La pagina doc ha davvero il miglior esempio di come funzioni in modo diverso; fondamentalmente, risolve il problema di temporizzazione lasciando che ogni chiamata separata sembri importare ed esportare le variabili macro da/verso l'ambiente chiamante, il che significa che ogni iterazione di DOSUBL
viene eseguita in un momento distinto rispetto a CALL EXECUTE
dove tutto viene eseguito in un mazzo e la macro l'ambiente è 'fisso' (cioè, qualsiasi riferimento a una variabile macro viene corretto in fase di esecuzione, a meno che non lo si passi in modo disordinato con %NRSTR
).
più Una cosa degno di nota è RUN_MACRO
, una parte del linguaggio FCMP
. Ciò consente di eseguire completamente una macro e di importarne il contenuto al passaggio dati, che in alcuni casi è un'opzione interessante (ad esempio, è possibile racchiudere una chiamata in un PROC SQL che ha selezionato un conteggio di qualcosa, quindi importalo nel dataset come variabile, tutto in un unico datastep). È applicabile se stai facendo questo allo scopo di chiamare una macro per assegnare una variabile di passaggio dati, non per eseguire un processo che fa cose che non devono essere importate nel passo dati, ma è qualcosa che vale la pena considerare se vuoi che quei dati tornino tutti nel set di dati che ha chiamato il processo.
Riassunto molto bello. Sto ancora sperando che più documentazione arriverà da SAS re DOSUBL e RUN_MACRO. Mi sembra che entrambi questi codici eseguano in qualche modo una sessione mini-SAS separata. E quando ci ho giocato un paio di anni fa, le regole di scoping non erano molto chiare. Ad esempio, le opzioni di sistema impostate in una macro richiamata con run_macro potrebbero o potrebbero non modificare le opzioni della sessione principale. Ma sono certamente strumenti potenti, vale la pena imparare. – Quentin
Bella risposta. Vale anche la pena considerare che la macro può essere riscritta come una funzione FCMP? –
Non vedo l'ora che le funzioni FCMP siano più numerose delle macro ... anche se in questo caso sembra un'analisi completa, che probabilmente è meglio non essere scritto in questo modo per ora (mentre RUN_MACRO consente di scrivere in questo modo , non sono convinto che sia davvero una buona idea se non ci sono altri grandi vantaggi ad esso). – Joe