University of Rochester Medical Center
SearchDirectoryNewsEventsStrong HealthURMC Home

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)