Coding efficiently using SAS macros

0
38

Macro programming is generally 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 and the next article explains how you can create SAS macro variables.

Using these techniques you can create an 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 to greatly 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 then the Proc step will be compiled and executed whereas macros are resolved and compiled prior to 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 basic 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 by 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 useful as it has the ability to pass parameters much 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. In a keyword parameter, you can apply a default value. In the above example of the keyword parameter, the default variable ‘age’ has been given. If the macro is called without specifying any parameter, the default variable will be taken as ‘age’.

Passing Multiple Parameters

Mostly, a combination of positional and keyword parameters are used. However, positional parameters must come before keyword parameters.

Working with Macro Strings

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

Quotes are not necessary around the values of a macro variable. 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 macro variable &filename is inside a double quote.

Evaluating Numeric Strings

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

%let sum = 1+1;
%put ∑
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.

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 = 1 - odd
 i = 2 - even
 i = 3 - odd
 i = 4 - even
 i = 5 - odd
 i = 6 - even
 i = 7 - odd
 i = 8 - even
 i = 9 - odd

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

SYMPUT and SYMGET

Macros are resolved prior to 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;
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.

Hence, the above code has to be replaced with:

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

Using Symget:

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

SYMGET returns a character value that is 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 of the program issues a message for an invalid argument to a function.

Debugging SAS macros

Debugging a macro code isn’t an easy process. By seeing the ERROR messages in LOG it is difficult to identify the problem. Hence, with the use of the below system option, you will be able to debug macros easily.

1. MPRINT

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

2. 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.

3. 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 the 3 systems options have enabled which shows 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

For detailed information on troubleshooting steps in macros, you can refer to the SAS V8 documentation website.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

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