SAS Macros

An Introduction to SAS Macro Programming

Macro programming is considered to be an advanced topic in SAS. Though macros can be challenging, it is also true that the basic concepts are not difficult to learn.

Assuming you know the basics of SAS Programming, In this tutorial, you will learn how the macro processor works and how to use SAS macros. The following article explains how you can create SAS macro variables.

Using these techniques, you can create efficient and reusable code that can save you time and effort.

Why use SAS macros?

Macros can automatically generate SAS codes and allow you to make more dynamic and generalized SAS programs. Macros can help significantly reduce the effort required to read or write repetitive SAS codes.

SAS program compilations

SAS codes are compiled and executed alternatively in steps. First, A data step will be compiled and executed, and then the Proc step will be compiled and executed, whereas macros are resolved and compiled before the compilation of SAS code.

codes without macros
Code without macros
code with macros
Code with Macros

In a standard SAS program, SAS compiles and then immediately executes it. Whereas in macro code, there is an extra step.

SAS passes your macro statements to the macro processor, which then “resolves” your macros generating standard SAS code. Then, SAS can compile and execute the program.

The two essential elements of macro code are SAS macro variables and SAS macros.

Macro variables hold the value as a text string. The easiest way to assign a value to a macro variable is using the %let statement.

UPCASE(character-value)%let macro_var = Hello;
%put The value of macro_var is &mac_var;

In the above example, &macro_var refers to a macro variable and %macro_var refers to a macro.

SAS Macro Parameters

SAS Macros are more beneficial as they can pass parameters like any functions in other languages.

For example, for calculating means, we often vary the set of variables without changing the rest of the code:

%macro means (var);
	proc sort data=sashelp.class out=class;
		by &var;
	run;
proc means data=class; 
by &var; 
run;
%mend;
%means(age);

Positional vs Keyword Parameters

You can specify macro parameters in two ways.

Positional Parameters

%macro means (var);
	proc sort data=sashelp.class out=class;
		by &var;
	run;
proc means data=class; 
by &var; 
run;
%mend; 
%means(age height);

Keyword Parameters

%macro means (var=age);
	proc sort data=sashelp.class out=class;
		by &var;
	run;
proc means data=class; 
by &var; 
run;
%mend; 
%means(var=height);

Each of the above ways has its advantages. For example, you can apply a default value in a keyword parameter.

The default variable ‘age’ has been given in the above example of the keyword parameter.

The default variable will be considered ‘age’ if the macro is called without specifying any parameter.

Passing Multiple Parameters

A combination of positional and keyword parameters is primarily used; however, positional parameters must come before keyword parameters.

Working with Macro Strings

Macros and macro variables can only be assigned strings of text. String functions on macro variables are handled implicitly:

Quotes are not necessary around the values of a macro variable. However, a period(.) is a signal in SAS to end a macro variable name if the requirement is to import data from a file called “customer_details.xls”, which is assigned in a macro variable filename.

The below code doesn’t work.

%let filename=customer_details;
proc import datafile="/folders/myfolders/&filename.xls" out=customers
replace;
run;

We need to replace the &filename.xls with &filename..xls.

%let filename=customer_details;
proc import datafile="/folders/myfolders/&filename..xls" out=customers
replace;
run;

Double vs Single Quotes in SAS Macros

Double quotes and single quotes affect SAS macro variables differently, and macro variables inside a single quote are not resolved.

proc import datafile='/folders/myfolders/&filename..xls' 
out=customers replace; 
run;

This does not work.

proc import datafile="/folders/myfolders/&filename..xls" 
out=customers replace; 
run;

This will work as a macro variable &filename is inside a double quote.

[Recomended Reading: SAS macro parameters with commas]

Evaluating Numeric Strings

Since SAS macro variables are strings and not numerical values, the below expression will not work.

%let sum = 1+1;
%put sum
1+1

The function %eval is used to obtain the integer or numeric value of an expression containing SAS macro variables.

%let total = %eval(&sum);
%put &total;
2

Floating-point evaluations can be performed with %sysevalf.

Read: ̣Exploring SAS Macro functions – eval and sysevalf

Conditional Statements

In SAS Macros, we can apply conditional statements using %IF %THEN, %DO,%WHILE, and %DO % UNTIl like below –

%macro OddEven();
	%do i=1 %to 9;
		%if %sysfunc(mod(&i, 2))=0 %then
			%put i = &i - even;
		%else
			%put i = &i - odd;
	%end;
%mend;
%OddEven();

Output:

 i <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">-</span> odd i <span class="token operator">=</span> <span class="token number">2</span> <span class="token operator">-</span> even i <span class="token operator">=</span> <span class="token number">3</span> <span class="token operator">-</span> odd i <span class="token operator">=</span> <span class="token number">4</span> <span class="token operator">-</span> even i <span class="token operator">=</span> <span class="token number">5</span> <span class="token operator">-</span> odd i <span class="token operator">=</span> <span class="token number">6</span> <span class="token operator">-</span> even i <span class="token operator">=</span> <span class="token number">7</span> <span class="token operator">-</span> odd i <span class="token operator">=</span> <span class="token number">8</span> <span class="token operator">-</span> even i <span class="token operator">=</span> <span class="token number">9</span> <span class="token operator">-</span> odd

Control statements in macro are not valid in open code. They must be contained within macros.

SYMPUT and SYMGET

Macros are resolved before the execution of the data step. There are special routines required for macros to communicate with the data.

  • SYMPUT puts data into a macro.
  • SYMGET extracts data from a macro.
data newClass;
	set sashelp.class;
	%let Age = Age**2;
run;
%put &age;

Output:

Age**2

In the above example, the value in age macro is set to Age**2 as the macro statement was resolved before the data step.

data newClass;
	set sashelp.class;
	call symput('age',age**2);
run;
%put &age; 

Output:

225

Using Symget:

data class;
	set newClass;
	age2=&age;
	age3=symget('age');
run;

SYMGET returns a character value of the maximum length of a DATA step character variable. Any value that is longer is truncated.

SYMGET returns a missing value if it cannot locate the macro variable identified as the argument; as a result, the program issues a message for an invalid argument to a function.

Debugging SAS macros

Debugging a macro code isn’t an easy process. It is difficult to identify the problem by seeing the ERROR messages. Hence, using the below system option, you can debug macros easily.

  1. MPRINT

MPRINT translates the macro language to regular SAS language and writes to the SAS log for each SAS statement.

  1. MLOGIC

MLOGIC marks the beginning of macro execution. It shows the values resolved at macro invocation. Additionally, it shows a %IF condition is TRUE or FALSE.

  1. SYMBOLGEN

The SYMBOLGEN system option writes the results of resolving macro to the SAS log for easy debugging.

options mlogic symbolgen mprintnest;
%macro OddEven();
	%do i=1 %to 9;
		%if %sysfunc(mod(&i, 2))=0 %then
			%put i = &i - even;
		%else
			%put i = &i - odd;
	%end;
%mend;

%OddEven();

In the above example, all three systems options have been enabled, showing detailed information about the macro in the SAS log.

 MLOGIC(ODDEVEN):  Beginning execution.
 MLOGIC(ODDEVEN):  %DO loop beginning; index variable I; start value is 1; stop value is 9; by value is 1.  
 SYMBOLGEN:  Macro variable I resolves to 1
 MLOGIC(ODDEVEN):  %IF condition %sysfunc(mod(&i, 2))=0 is FALSE
 MLOGIC(ODDEVEN):  %PUT i = &i - odd
 SYMBOLGEN:  Macro variable I resolves to 1

You can refer to the SAS V8 documentation website for detailed information on troubleshooting steps in macros.

Every week we'll send you SAS tips and in-depth tutorials

JOIN OUR COMMUNITY OF SAS Programmers!

Subhro

Subhro provides valuable and informative content on SAS, offering a comprehensive understanding of SAS concepts. We have been creating SAS tutorials since 2019, and 9to5sas has become one of the leading free SAS resources available on the internet.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.