SAS Helpful Hints
SAS Macro Language and Functions
*SAS has a few macro variables built
in;
%Put Sysdate=&sysdate
Sysdate9=&sysdate9;
Sysdate=16OCT02 Sysdate9=16OCT2002
%Put Sysday=&sysday Systime=&systime;
Sysday=Wednesday Systime=09:11
%Put Sysscp=&sysscp Sysscpl=&sysscpl;
Sysscp=WIN Sysscpl=WIN_PRO
*Symput creates macros out of data elements, very
useful, better compressed;
Data work.A;
x=34;
Call Symput('MacroX1',x);
Call Symput('MacroX',compress(x));
Run;
%Put MacroX1=&MacroX1;
MacroX1= 34
%Put MacroX=&MacroX;
MacroX=34
/*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*/
*SAS command that uppercases the first character of a string;
comment=Upcase(Substr(comment,1,1))||Lowcase(Substr(comment,2,Length(comment)-1));
*A simple macro procedure that uppercases the first character of
a string;
%Macro UpCaseFirst(string);
&string=Upcase(Substr(&string,1,1))||Lowcase(Substr(&string,2,Length(&string)-1));
%Mend UpCaseFirst;
Data work.A;
comment="who let the dogs out? ";
%UpCaseFirst(comment);
Put comment=;
comment="arthur let the dogs out.";
%UpCaseFirst(comment);
Put comment=;
Run;
comment=Who let the dogs out?
comment=Arthur let the dogs out.
/*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*/
*A macro that modifies a macro variable!;
*Useless macro, but good example of &&&;
%Macro mUpCaseFirst(string);
%Let length=%Length(&&&string);
%Let &string=%Upcase(%Substr(&&&string,1,1))%Lowcase(%Substr(&&&string,2,%Eval(&length-1)));
%Mend mUpCaseFirst;
%Let astring=arthur let the dogs out.;
%mUpCaseFirst(astring);
%Put astring=&astring;
astring=Arthur let the dogs out
/*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*/
*Calling sas language functions.;
*This converts a space delimeted list into a comma delimented list;
%Let commalist=%sysfunc(translate(Art
let the dogs out,","," "));
%Put commalist=&commalist;
commalist=Art,let,the,dogs,out
*Another example;
%Let list=Art let the dogs out;
%Let commalist=%sysfunc(translate(&list,",","
"));
%Put commalist=&commalist;
commalist=Art,let,the,dogs,out
/*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*/
*Classic use of macro language to reduce repetitive code;
%Macro plot(dataset, xvar, yvar);
Proc Plot Data=&dataset;
Plot &xvar*&yvar;
Run;
%Mend plot;
*%plot(dataset, xvar, yvar);
%plot(work.A, age, education);
%plot(work.A, age, gmat);
%plot(work.A, age, sat);
*Saves a lot of code, But can we do better??;
*Typically, investigators like to look at lots of outcomes, not just
a few;
*Wouldn't it be nice to pass a list of variables to a macro and let
it loop through each one?;
/*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*}{*/
*A macro that returns the first word from a list;
%Macro NextWord(string,word);
%Let space=%Index(&&&string,%Str(
));
%Let size=%Length(&&&string);
%If %Eval(&space)>0 %Then %Do;
%Let &word=%Substr(&&&string,1,&space);
%Let &string=%Substr(&&&string,&space+1,&size-&space);
%End; %Else %Do; %Let &word=&&&string;
%Let &string=; %End;
%Mend NextWord;
%Macro PlotAll(dataset,xvar,list);
%Let item=unknown; *Must initialize item;
%NextWord(list,item);
%Do %While(%Length(&item)>0);
*%plot(&dataset,
&xvar, &item);
%Put Item=&item
Remaining list=&list;
%NextWord(list,item);
%End;
%Mend PlotAll;
*Now we have one procedure call that can make several plots!;
%PlotAll(work.A,age,education gmat sat gpa average);
Please send your comments and suggestions about this web page to A. Watts
(watts@bst.rochester.edu)
|