A More Involved Macro Application

by Irina 10. August 2007 10:19
Example: Generate several SAS dataset names.
%MACRO DSNAMES(PREFIX,FIRST,LAST);
%LOCAL N;
%DO N=&FIRST %TO &LAST;
&PREFIX&N
%END;
%MEND DSNAMES;
data
%dsnames(count,1,4)
;
. . .
Generates:
data count1 count2 count3 count4;

SAS DATA Step Interfaces

  • SYMGET, SYMPUT, and other interfaces using macro variables can transfer values between SAS steps.
  • SYMGET returns macro variable values to the DATA step
  • Macro variables created with SYMPUT, can be referenced via & in the NEXT step.
Example:
proc means nway median data=sample;
where team_nbr  ne  1 ;
var  ttl_income_neto1 ;
class team_nbr;
output out=res median=income_median;
run;

data k;
set res;
length m $1;
team=put(team_nbr,1.) ;
run;

data _null_;
set k;
call symput('norma'||team,income_median) ;
run;


data sample1;
set  sample;
length m $1;
team=put(team_nbr,1.) ;
run;

data sample3 ;
set sample;
norma=symget('norma'||team);
target=(ttl_income_neto1 ge symget('norma'||team));
run;

CALL SYMPUTX

SYMPUTX will automatically convert and trim numbers.

Example:

%LET SAMPSIZE=5;
DATA SAMPLE;
DO N=1 TO &SAMPSIZE;
OBSNO=CEIL(UNIFORM(0)*TOTOBS);
SET POP POINT=OBSNO NOBS=TOTOBS;
OUTPUT;
END;
CALL SYMPUTX('MTOTOBS',TOTOBS);
STOP;
RUN;

CALL EXECUTE:


Call Execute Using a Macro Define a macro to do most of the work, then call it.
Resolves an argument and executes the resolved value at step boundary. This is a very powerful tool can can use the power of the data step to generate code.
%macro printcty(mcountynm,mctyobs);
PROC PRINT DATA=PERM.COUNTYDT;
SUGI 31 Hands-on Workshops
WHERE COUNTYNM="&mcountynm";
OPTIONS PAGENO=1;
TITLE "REPORT FOR COUNTY &mcountynm";
FOOTNOTE "TOTAL OBSERVATION COUNT WAS &MCTYOBS";
RUN;
%mend printcty;
data pass2;
set perm.countydt;
by countynm;
if first.countynm then ctyobs=0;
ctyobs+1;
if last.countynm then
call execute('%printcty(' !!
countynm !!
',' !!
put(ctyobs,2.) !!
')'
);
run;
The RESOLVE Function

Resolves the value of a text expression during DATA step execution. Syntax: variable=RESOLVE(argument);
%let event=Holiday;
%macro mdate;
SUGI 31 Hands-on Workshops
4th of July
%mend mdate;
data test;
length var1-var3 $ 15;
when='%mdate';
var1=resolve('&event'); /* macro variable reference */
var2=resolve('%mdate'); /* macro invocation */
var3=resolve(when); /* DATA step var with macro call */
put '*** ' var1= var2= var3=;
run;
*** var1=Holiday var2=4th of July var3=4th of July

System options for debugging macros

by Irina 10. August 2007 09:23

These five system options affect the kinds of messages SAS writes in your log. The default settings appear in bold.
MERROR | NOMERROR when this option is on, SAS will issue a warning if you invoke a macro that SAS cannot find.
SERROR | NOSERROR    when this option is on, SAS will issue a warning if you use a macro variable that SAS cannot find.
MLOGIC | NOMLOGIC    when this option is on, SAS prints in your log details about the execution of macros.
MPRINT | NOMPRINT     when this option is on, SAS prints in your log the standard SAS code generated by macros.
SYMBOLGEN | NOSYMBOLGEN when this option is on, SAS prints in your log the values of macro variables.
While you want the MERROR and SERROR options to be on at all times, you will probably want to turn on MLOGIC, MPRINT, and SYMBOLGEN one at a time and only while you are debugging since they tend to make your log hard to read. To turn them on (or off), use the
OPTIONS statement, for example:
OPTIONS MPRINT NOSYMBOLGEN NOMLOGIC;

MAGIC WITH CALL EXECUTE

by Irina 26. May 2007 11:16

Call execute- is a function that can be used if you want to run some code based on the values of a dataset.

Mixing DATA and PROC Steps.

You can't mix DATA and PROC steps. Each SAS step must complete before the next step begins.
For example, this program is illegal:
DATA _NULL_;
SET SALES END=NOMORE;
TOTAL + AMOUNT;
IF NOMORE;
IF TOTAL < 1000000 THEN DO;
PROC MEANS DATA=SALES;
CLASS STATE;
END;
ELSE DO;
PROC MEANS DATA=SALES;
CLASS STATE YEAR;
END;
However, CALL EXECUTE lets you designate the PROC and CLASS statements as statements to be added once the DATA step completes. This approach works, and requires minimal modification to the original:
DATA _NULL_;
SET SALES END=NOMORE;
TOTAL + AMOUNT;
IF NOMORE;
IF TOTAL < 1000000 THEN DO;
CALL EXECUTE
('PROC MEANS DATA=SALES;
CLASS STATE;');
END;
ELSE DO;
CALL EXECUTE
('PROC MEANS DATA=SALES;
CLASS STATE YEAR;');
END;
RUN;

sugi22

Keep only the variables in a data set that end in a particular character

by Irina 23. May 2007 12:03
 

data

one;

input abab ret cca www ttt ggab;

datalines

;

1 2 3 4 5 6

;

options

mprint;

%macro vars(dsn,chr);

%local list dsid num len tmp rc;

%let list=;

%let dsid=%sysfunc(open(&dsn));

%let num=%sysfunc(attrn(&dsid,nvars));

%let len=%length(&chr);

%do i = 1%to &num;

%let var&i=%sysfunc(varname(&dsid,&i));

%let tmp=%sysfunc(reverse(&&var&i));

%if%sysfunc(reverse(%upcase(%substr(&tmp,1,&len)))) = %upcase(&chr) %then%do;

%let list=&list &&var&i;

%end;

%end;

%let rc=%sysfunc(close(&dsid));

%if

&list ne %then%do;

data final;

set &dsn(keep=&list);

run;

proc print data=final;

run;

%end

;

%else

%do;

data _null_;

file print;

put

"No variables found in dataset &dsn that end with &chr";

run;

%end

;

%mend

vars;

/* Invoke the macro passing in the name of the data set */

/* that contains all your variables. Also pass it the */

/* characters you would like the variables to end with. */

%vars(one,ab)

%sysfunc

by Irina 22. May 2007 06:40

%sysfunc :

%sysfunc is useful for retrieving information about datasets, changing column attributes and formatting macro variables.One primary difference between calling a function in %SYSFUNC and elsewhere in the SAS System is this last notion of applying a format to the results of a function call.

Example1.

footnote finished: %sysfunc (today(), date9. );

Example2.

%put %sysfunc (PutN(&Salary,dollar12.));

Example3.

%put With a salary of
%sysfunc (PutN(&Salary,dollar12.));
%put You are %sysfunc(PutN(&salary, income.));

Example4.

If you wanted to find the total number of observations in a dataset and store that number as a macro variable. You might use something like this:

%let dsid= %sysfunc (open(name of the data));
%let nvars= %sysfunc (attrn(&dsid,nlobs));
%put &nvars; 
 

Tags: %sysfunc, macro

SAS | macro

About the author

Irina Spivak Irina Spivak
Team Leader at G-Stat. More...


Send mail Email

Authors

Blogroll

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010

    Sign in

    eXTReMe Tracker