SAS Macros Made Easy

This post explains SAS macro programming with practical examples. SAS Macro programming is considered as an advanced SAS. Knowing SAS Macros is an advantage in the job market over other candidates. Upon completion of this tutorial, you would understand how to create macros and where they can be used. It's generally said smart programming reduce workload and helps to win over your boss.
Complete Tutorial on SAS Macros
What are Macros

Macros are used to automate the repetitive task. It can make your work faster by automating the task that requires writing same lines of code every day. It can also be used when you design a complex algorithm and want to make usage of code user friendly so that people who are not comfortable with programming can use your algorithm.

Introduction to SAS Macro Programming

I. Macro Variables

A macro variable is used to store value. The value can be text or numeric.

Macro Variables are of two types -
  1. Local -  If the macro variable is defined inside a macro code, then scope is local. It would be available for use in that macro only and gets removed when the macro is finished.
  2. Global - If the macro variable is defined outside a macro code, then scope is global. It can be use any where in the SAS program and gets removed at the end of the session.

5 ways to create macro variables -

1.  %LET

It can defined inside or outside a macro.

The syntax of the %LET statement -
%LET macro-variable-name = value;
%LET x = 5;

Example - To store system date 
%let dt =   &sysdate;

How to use Macro Variables

Macro variables are referenced by using ampersand (&) followed by macro variable name.
& <Macro variable Name> 
To view in log window what macro variable would return, use %PUT statement :
%put &dt.;
%put NOTE : system data is &dt.;
Result :  NOTE : system data is 23DEC16

Notice that unlike the PUT statement the text string is not enclosed in quotes. The quotes are not needed because, unlike in the DATA step, the macro facility does not need to distinguish between variable names and text strings.

2. Macro Parameters

Example : Suppose you are asked to write a macro that returns mean value of a variable. The analysis variable, input and output data sets are dynamic.
%macro test (input =, ivar=, output=);
proc means data = &input noprint;
var &ivar;
output out = &output mean= ;
run;
%mend;
In the above code, test is a macro, input, ivar and output are local macro variables.

How to call a macro -
%test(input=sashelp.heart, ivar= height, output=test);
In this case, we are giving flexibility to users to provide information of input dataset name, the analysis variable and output dataset and the macro returns the mean value of the analysis variable in the output dataset.

3. INTO clause in PROC SQL

Example : Calculate average height and store in a macro variable
proc means data = sashelp.heart noprint;
var height;
output out = test mean= avg_height;
run;
proc sql noprint;
select avg_height into :var1
from test;
quit;
%put &var1; 

 Result :  64.81318

4. CALL SYMPUT routine 

The syntax of CALL SYMPUT :
CALL SYMPUT(macro_varname,value);
data _null_;
set test;
call symput ('var2',avg_height);
run;
%put &var2;
5. ITERATIVE %DO

The syntax of iterative %DO -
%DO macro-variable = start %TO stop <%BY increment>;
. . . text . . .
%END;
Example - 
%macro calcl(start,stop);
%do year = &start %to &stop;
data test;
set yr&year;
year = 2000 + &year;
run;
%end;
%mend calcl;
 How to use conditional processing %IF %THEN ?
options mindelimiter=,;
options minoperator;
%MACRO test();
%DO i = 1 %to 9 ;
%if &i in (1,3,5,7,9) %then %do;%PUT i = &i - odd;
%END;
%ELSE %DO;
%PUT i = &i - even;
%end;
%end;
%MEND;
%test();

SAS Macro Functions

1. %EVAL Function

It is used to perform mathematical and logical operation with macro variables.

Example -
%let x = 10;
%let y = 20;
%let z = &x * &y;
%put &z;
It returns "10*20".
%let z2 = %eval(&x*&y);
%put &z2;
It returns 200.

Note :

%let last = %eval (4.5+3.2); returns error as it cannot perform arithmetic calculations with operands that have the floating point values. It is when the %SYSEVALF function comes into picture.
%let last2 = %sysevalf(4.5+3.2);
%put &last2;
It returns 7.7


2. %SYSFUNC Function

There are several useful Base SAS function that are not directly available in Macro, %Sysfunc enables those function to make them work in a macro.
%let dt3 = %sysfunc(date(),yymmdd10.);
It returns  2016-12-23.


3. %STR Function

Usage I : This function removes the normal meaning of following token + – * /, > < = ; “ LT EQ GT LE GE LE NE AND OR NOT blank.

Suppose we need to store PROC PRINT; RUN; command in a macro variable.
%let exmp0 = proc print; run;;
%put &exmp0;
Result : proc print
Since the semicolon following PRINT terminates the %LET statement. It does not consider RUN statement. To workaround this issue, let's use %STR function.
%let exmpl = %str(proc print; run;) ;
%put &exmpl;
Result : proc print; run;

Usage II : Precede with % sign when you use single or double quotation in macro

%let var=%str(a%");
%put &var; 

Result : a"

If you would not use %STR function in the above example, you would not be able to store quotes in a macro variable.

Usage III : It also preserves leading and trailing blanks of the string.
%let dt= %str( a );
%put &dt;
Run the above code and compare it with the code below, you would understand the difference -
%let dt=  a ;
%put &dt;

4. %NRSTR Function

%NRSTR works similar to %STR works except it does not resolve the % and & but stop the macro triggers.
%let exmpl = %nrstr(proc print; run;) ;
%put &exmpl;
 Result : proc print; run;
%put "Difference between %NRSTR(&SYSDATE9) and &SYSDATE9";
Result : "Difference between &SYSDATE9 and 23DEC2016"

In the above case, %NRSTR() stops the &SYSDATE9 macro function.


5. %SCAN Function

It returns the nth word in a string.
%let var = var1 var2 var3;
%let varName =%scan(&var,1,%str( ));
%put &varName;
Result : var1

Concatenation of Macro Variables

Suppose you have 3 macro variables and the third variable is actually a concatenation of the first 2 variables' value.
%let x = var;
%let y = 1 ;
%let var1 = 25;
%let z = &&&x&y;
%put &x &y &z;
Result : var 1 25
&z returns 25 because first && resolves to &, &x resolves to var, &y. resolves to 1. So var1 returns 25
Detailed Tutorial : Multiple Ampersand Macro Variables

How to store list of values in a macro variable

Suppose you have a list of names and you want to store them in a macro variable. It can be done by using SEPARATED BY ' ' keyword in PROC SQL.
data temp;
input name $16.;
cards;
Deepanshu Bhalla
Dave Jhonson
Ram Prasad
;
run;
proc sql;
select name into: myvar separated by ','
from temp;
quit;

%put &myvar; returns  Deepanshu Bhalla,Dave Jhonson,Ram Prasad

In this case, we have used comma(,) as a delimiter. We can use any other delimiter.

How to debug SAS Macros

There are some system options that can be used to debug SAS Macros:

1. MPRINT

MPRINT translates the macro language to regular SAS language. It displays all the SAS statements of the resolved macro code.
options mprint;
%macro test (input =,output=);
proc means data = &input noprint;
var height;
output out = &output mean= ;
run;
%mend;
%test(input=sashelp.heart,output=test);
2.  MLOGIC

It is very helpful when we deal with nested macros (Macro inside another macro). Often we use %DO loops and or %IF-%THEN-%ELSE statements inside the macro code and LOGIC option will display how the macro variable resolved each time in the LOG file as TRUE or FALSE.
options mlogic;
options mindelimiter=,;
options minoperator;
%MACRO test();
%DO i = 1 %to 9 ;
%if &i in (1,3,5,7,9) %then %do;
%PUT i = &i - odd;
%END;
%ELSE %DO;
%PUT i = &i - even;
%end;
%end;
%MEND;
%test();
3. SYMBOLGEN

When we use multiple ampersands (ex: &&&x&y) and SYMBOLGEN option prints the message in the LOG file about how the macro variable is resolved.
options symbolgen;
%let x = var;
%let y = 1 ;
%let var1 = 25;
%let z = &&&x&y;

Important Tips

1. Use double quotes to reference macro variables.
SAS Macro

2. The quotes are not needed in %PUT.
%put NOTE : system data is &dt.;

3. Use Proc PRINTTO for saving log in an external text file.
proc printto log="C:\Users\Deepanshu\Downloads\LOG2.txt" new;
run;
4. Clear LOG and OUTPUT Window
DM "Log" clear continue;
DM "Output" clear continue;

SAS Tutorials : 100 Free SAS Tutorials

Get Free Email Updates :
*Please confirm your email address by clicking on the link sent to your Email*

Related Posts:

12 Responses to "SAS Macros Made Easy"

  1. Nice Explanation.Thanks!

    ReplyDelete
  2. Nice one..can you please give us some practical examples on macros...
    Thanks in advance

    ReplyDelete
  3. Nice one..can you please give us some practical examples on macros...
    Thanks in advance

    ReplyDelete
  4. Hi guys,

    I have a dataset :

    data imptbase.data_manipulation;
    infile datalines;
    input filename $ macroname $ sequence;
    datalines;
    area inserted 1
    area deleted 2
    area dropped 3
    country inserted 1
    country deleted 2
    country sorted 3
    ;
    run;

    My intension is to create a macro variable called MAC1 to MAC&mx1 that will hold the macro names. Eg.for filename AREA mac1 will hold value as "Inserted", mac2 will hold "deleted" and so on.

    NOTE : &mx1 will be clear from below given code.
    %macro abc;
    proc sql;
    select count(distinct filename)into :ank from imptbase.data_manipulation;
    %let ank1 = %eval(&ank);
    quit;
    proc sql;
    %do i = 1 %to &ank1;

    select distinct(filename) into :file1 - :file&ank1 from imptbase.data_manipulation;
    select max(sequence) into :mx from imptbase.data_manipulation where filename = "&&file&i";

    %let mx1 = %eval(&mx);

    select distinct(macroname) into :mac1 - :mac&mx1 from imptbase.data_manipulation where filename = "&&file&i";

    %put &file1 &file2 &mx &mac1 &mac2 &mac3;

    %do j = 1 %to &mx1;

    %&&mac&j;

    %end;

    %end;
    quit;
    %mend;

    Desired value of mac1 = inserted, mac2 = deleted, mac3 = dropped.
    But it is getting displayed in log as mac1 = deleted, mac2 = dropped, mac3 = inserted.

    problem with this code is value of macroname are getting sorted alphbetically(dont know why?)

    Can anybody plz help to get the desired output.

    Thanks in advance.

    ReplyDelete
  5. Hi Guys
    Could someone please tell me that a SAS Macro use PDV or not.
    If yes then in what circumstances because how much i know Macro facility does not have PDV.

    Deepanshu could you please add a page about this in SAS Macro section. If you could then i will be very much thankfull to you.

    ReplyDelete
    Replies
    1. Hi,
      I guess you are confusing yourself by comparing SAS PDV with SAS MACRO Processing, both are different.

      SAS PDV get created while data step processing while SAS macro gets processed by SAS macro processor.

      Delete
  6. Nice tutorial. Heowever, you mentioned %LET. Does it work?
    Thanks,
    Jeshwika

    ReplyDelete
    Replies
    1. It works. Please let me know if you face any issue(s) related to it.

      Delete
    2. Plz, can u give explanation about autocall macros.?

      Delete
  7. Hi Deepanshu,

    There is one mmore I know iss %window statement

    ReplyDelete

Next → ← Prev