The SAS Macro language enables you to write programs that generate SAS code, which is then submitted to the SAS interpreter for execution. A macro can be as simple as text substitution, creating a short placeholder for a long string of code, or a macro can generate SAS code dynamically, generating different code depending upon some input.
Macro Variables and %LET
Working with macro variables is a two-part process. First you assign a value to a macro variable - this value will be some string of text. Then you use the macro variable to substitute that text into some block of SAS code. This is called macro resolution.
Although macro values are text, you typically do not use quotes in defining them - if you do, the quotes are included when the text is substituted.
A macro value will typically be a token, a token fragment, or a collection of tokens. To make a macro value include more than one SAS statement requires the use of macro functions, and this is more typically done as a macro than as a macro variable. Where the value is a token fragment to be combined with a suffix, the macro variable is called with a leading ampersand and a trailing period.
A macro value may be hard-coded as a constant, but it can also be defined as the result of macro functions. Whatever is on the right-hand side of the equals sign in a %LET statement is evaluated before the assignment is made.
Note that when you create a macro variable, you give it a SAS name following the same rules you use for variable names within data sets (no spaces, no special characters, capitalization does not matter). When you go to use the macro variable, the name is always prefixed by an ampersand, "&".
In the following example, we just illustrate with two marital status variables (different years). Imagine how much output would be produced if we used the full list.
* Assigning values to macro variables;
%let dsn = y.nlswomen;
%let mstatus = R0002400 R0133700 /*R0205100 R0288200
R0308300 R0367600 R0455600 R0491300 R0661400 R0666600 R0721700
R0869900 R0997700 R1290700 R1664710 R3507200 R4278200
R5447500 R6516200*/;
* Using the macro variables;
proc freq data=&dsn;
tables &mstatus / nocum;
run;
The FREQ Procedure
MAR_STAT, 67
R0002400 Frequency Percent
-----------------------------------------------
MARRIED SPOUSE PRESENT 4064 79.95
MARRIED SPOUSE ABSENT 46 0.90
WIDOWED 145 2.85
DIVORCED 253 4.98
SEPARATED 285 5.61
NEVER MARRIED 290 5.71
MAR_STAT, 71
R0133700 Frequency Percent
-----------------------------------------------
MARRIED SPOUSE PRESENT 3568 77.72
MARRIED SPOUSE ABSENT 27 0.59
WIDOWED 206 4.49
DIVORCED 285 6.21
SEPARATED 282 6.14
NEVER MARRIED 223 4.86
Frequency Missing = 492
By default the code that is echoed in the log is just what you send to the macro interpreter. If you want to see what the code looks like after macro variable substitution, you need to invoke the SAS option SYMBOLGEN. In much of the SAS documentation, macro variables are called "symbols" and lists of macro variables are called "symbol tables". Your log will look like this:
%let dsn = y.nlswomen;
%let mstatus = R0002400 R0133700 ;
options symbolgen;
proc freq data=&dsn;
tables &mstatus / nocum;
run;
Notice the echo of PROC FREQ includes notes on the macro values used.
2 %let dsn = y.nlswomen;
3 %let mstatus = R0002400 R0133700 ;
4
5 options symbolgen;
6 proc freq data=&dsn;
SYMBOLGEN: Macro variable DSN resolves to y.nlswomen
7
SYMBOLGEN: Macro variable MSTATUS resolves to R0002400 R0133700
7 ! tables &mstatus / nocum;
8 run;
NOTE: There were 5083 observations read from the data set Y.NLSWOMEN.
NOTE: The PROCEDURE FREQ printed page 1.
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
The FREQ Procedure
MAR_STAT, 67
R0002400 Frequency Percent
-----------------------------------------------
MARRIED SPOUSE PRESENT 4064 79.95
MARRIED SPOUSE ABSENT 46 0.90
WIDOWED 145 2.85
DIVORCED 253 4.98
SEPARATED 285 5.61
NEVER MARRIED 290 5.71
MAR_STAT, 71
R0133700 Frequency Percent
-----------------------------------------------
MARRIED SPOUSE PRESENT 3568 77.72
MARRIED SPOUSE ABSENT 27 0.59
WIDOWED 206 4.49
DIVORCED 285 6.21
SEPARATED 282 6.14
NEVER MARRIED 223 4.86
Frequency Missing = 492
More examples:
2 %let test = TEXT;
3 %put test=&test;
test=TEXT
4
5 %let test = "TEXT";
6 %put test=&test;
If a macro variable contains a semi-colon, use the macro function %quote
.
%LET test = %quote(proc print; run;);
data class;
set sashelp.class;
run;
&test;
Obs Name Sex Age Height Weight
1 Alfred M 14 69.0 112.5
2 Alice F 13 56.5 84.0
3 Barbara F 13 65.3 98.0
4 Carol F 14 62.8 102.5
5 Henry M 14 63.5 102.5
6 James M 12 57.3 83.0
7 Jane F 12 59.8 84.5
8 Janet F 15 62.5 112.5
9 Jeffrey M 13 62.5 84.0
10 John M 12 59.0 99.5
11 Joyce F 11 51.3 50.5
12 Judy F 14 64.3 90.0
13 Louise F 12 56.3 77.0
14 Mary F 15 66.5 112.0
15 Philip M 16 72.0 150.0
16 Robert M 12 64.8 128.0
17 Ronald M 15 67.0 133.0
18 Thomas M 11 57.5 85.0
19 William M 15 66.5 112.0