Writing a SAS Macro

The SAS macro language helps to reduce the amount of repetitive SAS code and it facilitates passing information from one procedure to another procedure. Furthermore, we can use it to write SAS programs that are "dynamic" and flexible. Generally, we can consider macro language to be composed of macro variables and macro programs. In this chapter will demonstrate how to create macro variables and how to write basic macro programs.

SAS Macro Variables

Many times we create macro variables to make them available through out various data steps and procedures.  The scope of the variables is mostly limited to the data step or the procedures where they are created or used but through macro facility we can make them available throughout the program. For example its possible to declare a list of variables used in print and freq procedures repetitively as a macro variable and use it instead of a long list of variables. Also its possible to compute the data range of the data for a report and assign that to a macro variable so that all procedures and data step can access this information.

A macro variable can be created by using the %let statement. All the key words in statements that are related to macro variables or macro programs are preceded by percent sign %; and when we refer a macro variable it is preceded by an ampersand sign &. When we submit our program, SAS will process the macro variables first, substituting them with the text string they were defined to be and then process the program as a standard SAS program

There are two functions that are particularly useful when we want to get information in and out of a data step. These are symput and symget. You use symput to  get information from a data step into a macro variable and symget is used when we want to get information from a macro variable into a data step.

Now let us look at some examples:

DATA account_perf;

format current_os dollar10.2  ;

label account="Account #"

fico_seg = "Fico Segments";

INPUT client $ account fico_seg $  current_os tot_payment  ext_status_code $ ;

cards;

Cmart 1002 401-500 300  100 A  C

Cmart 1003 501-600 200  150 A  C

Cmart 1004 601-700 1200 180 A  D

Cmart 1005 701-800 800  190 Z  A

Cmart 1006 801-900 450  200 Z  A

GIA     1007 401-500 560  210 Z  A

GIA     1008 501-600 450  180 A  D

GIA     1009 601-700 900  145 A  D

GIA     1110 701-800 300  148 Z  D

;run;

%let varlist =  current_os tot_payment;

Proc print data =account_perf;

Title " Weekly report ";

var &varlist;

run;

proc means data = account_perf;

var &varlist;run;

 

First line after the DATA step uses %LET statement to declare a macro variable ‘varlist’. Two columns are assigned to the variable.(Note that there could be more variables or string that could be assigned)

Line:4 – Var statement uses the ‘varlist’ variable with a ‘&’ prefix.

Line:7- The PROC Means procedure also uses the same variable to generate the statistics.

Though this example is not a good use of macro variables, this will give some idea about the scope of variables and their availability.

The program below demonstrates the use of SYMPUT function to create macro variables from a SAS data step. This is particularly useful, as many times we have to assign values to macro variables from a SAS data step.

%let sweek =-1;

data _null_;

bd= INTNX('WEEK',today(), &sweek,'B');

edate = put(bd+6, date9.);

bdate = put (bd, date9.);

call symput ("edatec",edate);

call symput ("bdatec",bdate);

run;

Proc print data =account_perf;

Title " Weekly report from &bdatec to &edatec";

var &varlist;

run;

The program above is written for a weekly application reporting purpose where every table in the report should have a header with start date and end date. Further applications considered for these reporting should fall between these dates., finally, the report file also should have this date stamp.

To achieve this previous week start date and end dates are computed in a data step and assigned to macro variables. Now these dates are available during data extraction and reporting steps of the program.

Line 1: declares macro variable ‘week’ with %let statement.

Line 3: INTX function is used to compute the beginning day of previous week.

Line 4: end date is computed using the beginning date.

Lines 6&7 : Call symput statement is used to assign the value of edate and bdate to macro variables edatec and bdatec.

Line 10: The macro variables are used in the title statement of Print procedure to print start date and end date.

There are some uses of macro variables but they are extensively used in macro processing to pass on values into a SAS Macro. We will see that in the following sessions.

Macro Programs

A macro program is similar to a subroutine or a function in other programming languages. Sas programs are usually written to do a task repetitively.

A macro program always starts with the %macro statement including the user defined program name and it ends with a %mend statement.

Now let us look at a program to understand the macro processing . A sample data set is created with three clients and various score segments.

DATA account_perf;

INPUT client $ account fico_seg $  current_os tot_payment  ext_status_code $ ;

cards;

Lowes 1008 101-200 450  180 A 

Lowes 1009 201-300 900  145 A 

Lowes 1110 301-400 300  148 Z 

Lowes 1002 401-500 300  100 A 

Lowes 1003 501-600 200  150 A 

Lowes 1004 601-700 1200 180 A 

Lowes 1005 701-800 800  190 Z 

Lowes 1006 801-900 450  200 Z 

GIA 1008 101-200 450  180 A 

GIA 1009 201-300 900  145 A 

GIA 1110 301-400 300  148 Z 

GIA 1002 401-500 300  100 A 

GIA 1003 501-600 200  150 A 

GIA 1004 601-700 1200 180 A 

GIA 1005 701-800 800  190 Z 

GIA 1006 801-900 450  200 Z 

Cmart 1008 101-200 450  180 A

Cmart 1009 201-300 900  145 A 

Cmart 1110 301-400 300  148 Z 

Cmart 1002 401-500 300  100 A 

Cmart 1003 501-600 200  150 A 

Cmart 1004 601-700 1200 180 A 

Cmart 1005 701-800 800  190 Z 

Cmart 1006 801-900 450  200 Z 

;

run;

%macro score_seg (client,st_code,dataset);

proc print data = &dataset;

Title "FICO Segment for External Status=&st_code and Client =&client";

var client ext_status_code  fico_seg current_os;

where client=&client and ext_status_code =&st_code;

run;

%mend;

%score_seg('GIA','A',account_perf)

%score_seg('GIA','Z',account_perf)

%score_seg('Cmart','A',account_perf)

%score_seg('Cmart','Z',account_perf)

%score_seg('Lowes','A',account_perf)

%score_seg('Lowes','Z',account_perf)

Objective is to produce a set of reports to show FICO score segments and Current Outstanding based on the External Status code.  The report needs to be produced individually for the clients specified. Now let us assume that the data set has more than 10 client and several status codes and a large number of records. We can write a proc print step for each and every combination but this macro simplifies that.

This task is repetitive. Only client status code and datasets are variables so they are the best candidates for parameters (macro variables) that can be passed on from a Macro call.

After the data step line 1: defines the macro with %macro statement followed by macro name ‘%score_seg’.  This is followed by, in parenthesis, the arguments or macro variables that are passed on to the macro. These variables can take different values, every time a macro call is made .

Line 2: Proc print statement is specified and data statement takes a macro variable as the input data. The value assigned to this macro variable will be read as dataset name

Line 3: Title statement in PROC print . The macro variable passed on are used to print a meaningful title

Line 5:  Where statement takes the values from macro variables passed on . This will ensure that the data is filtered as per the specifications of the user.

Line: 7 Tells SAS to end the macro with a %mend statement

Line 8:  Calls the macro ‘%score_seg’. Values are passed on to the macro with a comma.

Line 9 onwards: the same macro is called for various combinations. Proc print is customized for the analyst requirement

What we have seen above are basic macro constructs and some simple examples. Macros are extremely useful in SAS programming environment and used in various contexts to simplify the programs or to bring efficiency to data processing.

    • Exercise for you:  Collect 3 Macro programs from your team members written for various purposes. List down the functionality (what the macro does) and the context they are used.  Explain what way it simplifies the program.
Copyright free public information. All trademarks,service marks, logos and names are properties of their respective owners.