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