If you’ve been writing the same lines of code repeatedly in SAS, you can stop now. It shouldn’t be as laborious as you’ve been. Availability of SAS Macros can make your work faster and save your day. I’ve worked on SAS for 3 years. I remember writing same lines of code every morning, until I learnt Macros. Since then, I’ve persisted to learn every bit of technique to make coding faster in SAS.
Macros provide an incredible way to automate a process. Over the years, I’ve learnt these ways which I’ve shared in this article. Macros are simple to learn but can be confusing at times. Hence, you must pay attention to the command and its output. Lots of people end of mixing the two.
Here is a complete tutorial on using SAS Macros. I hope this will help you to become better and faster in SAS.
The topics covered in this guide are as shown below.
Initiate your SAS software and let’s get started. Performing these commands as you read through would help you memorize these commands better.
I’ll take a simple example so that you can understand this concept better:
Example:
Let’s look at the following SAS program:
[stextbox id = “grey”]proc print data=Sales.Policysnapshot;
where policydate='09Sep14'd;
title “Below are the policy detail for 09-Sep-14”;
Run;[/stextbox]
Above SAS code is written to extract policy level details for 09-Sep-14 and let us say that the user needs to run this code on a daily basis after changing the date (at both the places) to current date.
Thankfully, SAS – like any other programming language, provides the facility of automating codes with use of SAS macro programming. Now, let us look at the same code once automated by SAS macros.
[stextbox id = “grey”]Proc Print Data=Sales.Policysnapshot;
Where policydate=”&sysdate9”d;
Title “Below are the policy detail for %sysdate9”;
Run;[/stextbox]
In this case, the user does not need to provide value for current date. The code will automatically pick current date from system.
SAS macros enable us to:-
Above all, it helps to reduce the efforts required to read and write SAS Code. Macro programming is typically covered as advanced topic in SAS, but the basic concepts of SAS macros are easy to understand.
I will now introduce the concept of SAS programming and I assume that you are aware about basics of SAS programming. We will look at how macro processor works, how to use SAS macros & macro variables and How to create flexible and reusable code to save time and efforts?
A SAS program is a combination of Data steps, global statements, SAS Component Language (SCL), SQL statements and SAS Macro statements. Whenever we submit a program, it gets copied in memory (called input stack) followed by word scanner and there after it goes to compiler and gets executed. When we use Macros in our SAS program, an additional step is added to resolve macros. This step is called as MACRO Processor.
As we can see above, we have an additional step “Macro Processor” when we work with macro i.e. SAS code with macro does not compile or execute faster. It only helps to reuse the SAS code and variables values.
Macro code consists of two basic building blocks: Macros and Macro variables. In a SAS program they are referred differently as:-
A macro variable is just like a standard variable, except that its value is not a data set and has only a single character value. The value of a macro variable could be a variable name, a numeral, or any text you want substituted in your program.
Scope of Macro variable can be local or global,Add Media depending on how we have defined it. If it is defined inside a macro program, then scope is local (only available for that macro code). However, if we have defined it outside (in the main body), then we can use it anywhere in SAS program.
%LET statement is used to create and assign value to macro variables.
% LET <Macro Variable Name>=Value;
Macro variable name follows the SAS naming convention and if variable already exists then value is overwritten.
Value of macro variable in %Let statement can be any string and it has following characteristics:-
Macro variables are referenced by using ampersand (&) followed by macro variable name.
&<Macro variable Name>
Example:-
We can also declare multiple macro variables and use them at different places in SAS Code. Macro variable are not resolved when they are accessed within single quotes. Hence, we should use double quotes to reference them.
We can reference macro variable with text in multiple ways:-
Let’s look at these with a simple example:-
A period (.) is used as delimiter that defines the end of a macro variable.
Let’s look at an example:-
Here, you can see that the program did not execute because we required (ORION.COUNTRY) and not (ORIONCOUNTRY). This happened because here period (.) is used as separator between two macro variables. Now, to use period as a separator between library name and dataset, we need to provide period (.) twice.
SAS Macros are useful when we want to execute same set of SAS statements again and again. This is an ideal case for use of macro rather than typing / copy pasting same statements.
Macro is a group of SAS statements that is identified by a name and to use it in program anywhere, we can reference it with that name.
Syntax:-
%Macro <Macro Name>;
Macro Statements;
%MEND;
Macro Statements can contain combination of the following:-
After definition of macro, we need to invoke/ call it when want to use it.
Syntax for calling a MACRO: –
%<Macro Name> [;]
Here we do not need to end this statement with a semicolon but it is a good programming practice to have it.
Example:-
You can see that we have used same set of statements twice using macro.
We can define a Macro with parameters, which can be referenced within the macro. We can pass the parameters in two ways:-
Positional Parameters: In this method, we supply parameter name at time of defining the macro and values are passed at time of Macro call.
Syntax:-
Definition
[stextbox id = “grey”]%MACRO <macro name>(Parameter1, Parameter2,….Parameter-n);
Macro text;
%MEND;[/stextbox]
Calling
[stextbox id = “grey”]%MacroName (Value1, Value2,…..Value-n); [/stextbox]
At calling stage, values to parameters are passed in similar order as they are defined in the macro definition.
Example:-
[stextbox id = “grey”]%MACRO AV(Country_Criteria, City_Criteria);
Proc Print data=Test.sales;
Where Country=”&Country_Criteria” AND CITY=”&City_Criteria”;
Run;
%AV(AU, Sydney);[/stextbox]
Keyword Parameters: In this method, we provide parameter name with equals to sign and also can assign default value to the parameters. While calling the macro, we have to mention the parameter names followed by equals sign and value.
In this method, parameters with equals sign can be
Syntax:-
Definition
[stextbox id = “grey”]%MACRO <macro name> (Parameter1=Value, Parameter2=Value…….Parameter-n=Value);
Macro Text;
%MEND;
[/stextbox]
Calling
[stextbox id = “grey”]%<macro name> (Parameter1=Value, Parameter2=Value …..Parameter-n=Value);
[/stextbox]
Example:-
Let’s discuss some examples of SAS Macro Variable and SAS Macros, when you want to use a particular value multiple times in a program and its value changes over time.
For example:-
SAS Macros are typically considered as part of advance SAS Programming and are used widely in reporting, data manipulation and automation of SAS programs. They do not help to reduce the time of execution, but instead, they reduce repetition of similar steps in your program and enhance the readability of Programs.
Let’s now proceed further can learn the process of creating conditional and repetitive steps using SAS Macro.
SAS macros provide us with the flexibility to use a piece of code multiple times by simply calling the macro. This flexibility can be exploited to reach next level of sophistication with use of conditional statements and loops using macro statements such as %IF, %DO. These macro statements should always be called inside the macro.
As the name implies, conditional processing is used when we want to execute a piece of code based on the output of single or multiple conditions.
Syntax:-
Here, ELSE part of the syntax is optional.
Both syntax work in similar manner – the only difference is, first one executes only one statement after THEN or ELSE, whereas the second syntax can execute multiple statements.
I am referring to the expression in the condition as Conditional macro expression. In some cases, it is similar to SAS expression:
Dissimilarities compared to SAS Expression:
Let’s say, we have transactional data for a company which deals in food business. Here manager requires details of all the sales on daily basis except on MONDAY. On Monday, he want a additional summary report for item wise total sales (People call it as MONDAY Report!)
Here we will first define a separate macro for Daily and Monday reports (you can combine these together also).
Now on daily basis it will call Macro “Daily” and check if today is MONDAY then it will run MACRO “Monday”. Similarly if we have multiple statements to execute after %IF-%Then then we should go for %IF-%THEN-%DO-%END.
Loops are used to create a dynamic program, which executes for a number of iterations, based on some conditions (called conditional iteration). These statements are also valid only inside a macro.
Syntax:
Key things about syntax:
Let’s say we have a series of SAS data sets YR1990 – YR2013 that contain business detail and now we want to calculate the average sales for each of these years.
If we will not use the SAS macro then we need to write PROC MEANS steps for each of the year, which is not a good idea.
Now let’s look at how we can use SAS Macros to do this job easily:
We can achieve this with %UNTIL and %WHILE.
Conditional statements and loops empower SAS Macros to perform conditional and iterative tasks. They appear similar to SAS conditional statements and loops and they work similar in some cases. The major difference between the two is %if-%then’ can ONLY be used inside the MACRO program (whether inside the DATA step, or outside) and ‘if-then’ is ONLY used inside the DATA step (whether MACRO or non-MACRO).
Now, let’s understand the use of Macro functions to manipulate text, perform arithmetic operations and execute SAS functions.
These Macro functions have similar syntax, compared to their counterpart functions in data steps and they also return results in similar manner. They can manipulate macro variables and expressions and these functions get evaluated only at stage of Macro processing. Most importantly, these do not require quotes around character constant arguments.
Let’s look at some of these one by one:
This function is used to convert case of letters to uppercase:
Syntax: – %UPCASE (Argument)
Example:
%Let heading=this is detail of country; Proc Print Data=Orion.Country; Title %UPCASE(&heading);
Run;
It will print title as “THIS IS DETAIL OF COUNTRY”.
This function returns the given number of characters from specified position.
Syntax: – %SUBSTR (argument, position [, number of characters])
If number of character is not supplied, %SUBSTR function will return characters from given position till end of the string.
Example:
%Let abc=this is detail of country; %LET def=%SUBSTR(&abc,19,7); Proc Print Data=Orion.Country; Title %Upcase(&def); Run;
Here we have first extracted “country” from macro variable abc and store it into def and after that used it to show title in upper case.
This function will return the nth word in a string (having n words separated by delimiters).
Syntax: – %SCAN (argument, n [, delimiter])
It will return NULL value, if string does not have n words separated by delimiter and if we have not given delimiter then it will use default value for it. Default delimiters are blank , . ( & ! $ * ) ; – / %.
Example: –
%LET STR=Analytic Vidhya.Educon; %LET ABC=%SCAN(&STR,2); %LET BCD=%SCAN(&STR,1,i); %PUT &ABC; %PUT &BCD;
ABC will store string “Vidhya”, here it automatically identify the second word based on default delimiter and BCD will have value “Analyt” because we have mentioned that i is a delimiter and we required the first word.
This function is used to perform mathematical and logical operation with macro variables. Remember, macro variable contains only text (numerical values are also stored as text) and therefore we can’t perform any arithmetical and logical operation, if we try to use them directly. EVAL() function also returns a text result.
Syntax: – %EVAL (Expression)
Example: –
%LET A=3 ; %LET B=&A+1; %LET C=%EVAL(&A+1); %PUT &A &B &C;
As we know, macro variables store value as text, macro variable B will store 3+1 and with the use of %EVAL, C will store 4.
If, we create a variable like:
%LET D=%EVAL (&A+3.2);
What would variable D store?
If you answered 6.2, you are wrong! This statement will throw up error because SAS understands “.” as character. Now, to evaluate floating numbers, we will use %SYSEVALF () function and above statement should be written as:
%LET D=%SYSEVALF(&A+3.2);
This function is used to execute SAS functions in macro environment. With the help of this function, we can increase the list of functions available to the macro language significantly. This function can allow us to make almost all DATA step and user-written functions usable in SAS Macros.
Syntax: –
%SYSFUNC (Function(arguments..) [, Format])
It has two arguments, first is for the function and second is optional to format the output of function.
Example: –
%Put %SYSFUNC(Today(),Date9.);
This will display the current date in date9 format.
This function removes/masks the normal meaning of following token + – * /, > < = ; “ LT EQ GT LE GE LE NE AND OR NOT blank. It also preserves leading and trailing blanks of the string. Please note that this does not mask & and %.
Syntax: – %STR (argument)
This functions works exactly as %STR, but it also masks macro triggers % and &.
Example: –
%LET D=5; %LET abc = %STR ( "S &D Analytics"); %PUT &abc;
%LET bcd = %NRSTR ( "S &D Analytics"); %PUT &bcd;
Here first %PUT statement will return S 5 Analytics whereas second one will return S &D Analytics.
This brings me to the end of this tutorial. I hope you learnt some new ways of manipulating data in SAS. In this tutorial, we looked at the basic concepts of SAS and how they become useful to accomplish repetitive tasks easily.
We also looked at how SAS Macros can be used in iterative and conditional circumstances, followed by several functions to perform text manipulations and to apply arithmetical and logical operations in SAS Macros. These, in combination with conditional statements can provide a very powerful mechanism to automate / modularize your SAS programmes.
Did you find this tutorial useful? If you need any more help with SAS Macros, please feel free to ask your questions in the comments below.
Great tutorial!!!
Hi Sunil, Thanks a lot. You explained crystal clear. I have some questions. could you please explain the below code for me. Import all spreadsheets in all subfolders of a top folder This solution uses directory contents data sources, where the directory path is enclosed in angle-brackets: . The names that can appear in a directory contents macro variable list are: filepath – the complete path of the file, including file name with extension filename – the file name, including extension shortname – the file name, excluding extension extension – the file extension, including period isdir – 1 if the file is a directory, 0 if not This solution also demonstrates nested %for loops! %let topfolderpath= ... path to some directory ... ; %for(filepath, in=, do=%nrstr( %let subfolderpath=&filepath; %for(filepath shortname, in=, do=%nrstr( proc import datafile="&filepath" out=&shortname dbms="excel" replace; run; )) )) Regards Sundeep Reddy Allala
Hi Sunil, It's a great tutorial, however, you have mentioned %NSTR() at one place, does it work or R is missing in it? Please suggest me.