Introduction

Welcome to Edition 17 of Making SAS Accessible to Everyone. In this edition, we begin our journey into one of SAS’s most powerful and flexible tools: the macro language.

Macros allow you to:

  • Write dynamic and reusable code

  • Substitute values or statements throughout your program

  • Automate repetitive programming tasks

  • Create parameter-driven processes

Even though the SAS macro facility is often considered advanced, many of its features are surprisingly accessible and extremely helpful even for beginners and intermediate users. This edition demystifies macro variables and shows you how to begin using them to improve your code efficiency and flexibility.


1. What Are Macro Variables?

Macro variables are placeholders that store text strings. They are defined and used to simplify SAS programming by replacing hardcoded values or repeating code fragments.

Macro variables begin with an ampersand (&) when referenced. When you run your program, the macro processor scans your code before SAS execution and substitutes all macro variables with their values.

Example:

%let threshold = 100;
data check;
    set sales;
    flag = (revenue > &threshold);
run;

Here, &threshold is replaced by 100 wherever it appears.

This allows you to modify one line instead of searching and editing many lines throughout your code.


2. Useful Built-in Macro Variables

SAS provides a set of automatic macro variables created at the beginning of each session. Here are two commonly used ones:

  • &SYSDATE9: Stores the session’s date in DDMMMYYYY format

  • &SYSTIME: Stores the session’s start time in hh:mm format

Example:

title "The Date is &sysdate9 - The Time is &systime";

Tip: SAS only resolves macro variables within double quotes. Single quotes will preserve the literal name.


3. Using %LET to Define Macro Variables

Use the %LET statement to define macro variables and assign them fixed values.

Example:

%let var_list = height weight age;
proc means data=patients;
    var &var_list;
run;

This lets you define variable lists or constants in one place for easier reuse or modification.

Another example – Parameterize a loop:

%let n = 5;
data random;
    do i = 1 to &n;
        x = ranuni(0);
        output;
    end;
run;

4. Writing a Simple Macro Program

You can define macros using %MACRO and %MEND. These let you encapsulate code blocks for reuse with different parameters.

Example:

%macro greet(name);
    %put Hello, &name!;
%mend greet;

%greet(Dany)

Macros can have one or multiple positional arguments, which are replaced in the code wherever referenced with &.


5. Automating Data Generation with Macros

Let’s see a more detailed macro that generates a dataset with random integers.

%macro gen(n, Start, End);
/**********************************************
Macro: gen
Purpose: Generate random integers
Arguments:
  n     - number of observations
  Start - minimum value
  End   - maximum value
Example: %gen(4, 1, 100)
**********************************************/
data generate;
    do Subj = 1 to &n;
        x = int((&End - &Start + 1) * ranuni(0) + &Start);
        output;
    end;
run;

proc print data=generate noobs;
title "&n Random Numbers between &Start and &End";
run;
%mend gen;

Invoke the macro like this:

%gen(4, 1, 100)

This generates a dataset of 4 random integers between 1 and 100.


6. Avoiding Common Macro Pitfalls

Macro variables can be confused with other text unless carefully delimited. If a macro variable is followed by characters that form a valid name (letters, numbers, underscores), SAS will try to resolve the whole sequence.

Problem:

%let prefix = abc;
data &prefix123; /* This fails */

SAS tries to resolve &prefix123 instead of &prefix. Fix this with a period:

Solution:

data &prefix.123; /* Now resolves correctly */

7. Using Macros with Dataset Names

Macro variables can also represent librefs or data names:

%let libref = learn;
proc print data=&libref..survey;
title "Survey Dataset from &libref";
run;

Here, .. ensures proper resolution: &libref. becomes learn, resulting in learn.survey.


8. Sharing Values Between Steps with CALL SYMPUT

CALL SYMPUT lets you pass computed values from a DATA step into macro variables for use elsewhere.

Example:

proc means data=blood noprint;
    var RBC WBC;
    output out=means mean=M_RBC M_WBC;
run;

data _null_;
    set means;
    call symput('AveRBC', M_RBC);
    call symput('AveWBC', M_WBC);
run;

data new;
    set blood(obs=5 keep=Subject RBC WBC);
    Per_RBC = RBC / &AveRBC;
    Per_WBC = WBC / &AveWBC;
    format Per_RBC Per_WBC percent8.;
run;

This is ideal for cases where later steps depend on statistical summaries or values derived from previous steps.


Conclusion

In Edition 17, we introduced the SAS macro language, focusing on:

  • Understanding and defining macro variables using %LET

  • Creating flexible and reusable macro programs with %MACRO and %MEND

  • Safely referencing macro variables using periods

  • Using CALL SYMPUT for dynamic value assignment

Mastering these basics enables you to write dynamic, scalable, and easily maintained code in SAS.


What’s Next

In Edition 18, we kick off a Knowledge Quiz to help you review and reinforce what you’ve learned in SAS so far.


Automate with clarity – with 3 D Statistical Learning.

Special thanks to Dr. Dany Djeudeu for inspiring confidence in automation and scalable SAS programming.