Watch this Ask the Expert session to learn how to transform static code by adding macro language to create data-driven programming logic.
Watch the Webinar
You will learn how:
The SAS Macro Language is a separate language that can write your SAS code for you.
Using macro language elements in your SAS code can make it more dynamic.
Macro variable lists are a convenient way to organize data values.
The questions from the Q&A segment held at the end of the webinar are listed below and the slides from the webinar are attached.
Q&A
What if more than one person is named Alfred?
In that case, only the first value of age would have been stored in the macro variable. This was just a contrived example to illustrate the point, and we knew in advance there was only one Alfred in that data set. In real work, I would make the code more dynamic.
Can you use a triple ampersand?
Absolutely - it's rare that there is a need to do so, but Art Carpenter has some examples in his book.
What did Highlow mean in the PROC SQL?
The highlow was part of the PROC SGPLOT. It creates a high-low plot, which is frequently used for stock charts.
Is there a way to use %let macro value in the dataset name part of a data step?
Once a macro variable has been assigned a value using a %LET statement, that value can be used anywhere in your SAS code, including as the name of a data set in a DATA step. The key is that the %LET needs to be executed before the DATA step so that the macro variable is already available on the symbol table before the DATA step code is processed by the macro facility. Keep in mind that if there is a macro definition after the %LET statement and the macro definition assigns a value to the same macro variable name, then within the macro definition, the new value will be used. Outside the macro definition, the value on the %LET statement will be used.
Does :alfred_age need to be initialized prior to running that PROC SQL step? Or can the PROC SQL step contain the first ever instance of :alfred_age?
No, there is no need to initialize a macro variable prior to PROC SQL. The INTO clause of the SELECT statement creates whatever macro variable(s) you specify.
Is this outside a data step?
Unfortunately, we cannot answer this question without the context in which it was asked.
Can we see all the code together? I'm used to doing macros, so after the data step the %MACRO Graph_stocks (var1, var2, etc...).
The complete slides from the presentation are available, including those that contained code. We’re not quite sure if you’re asking for something else, but feel free to contact us directly and we’ll be happy to help.
Why do we have 3 dots e.g. . . . pdf?
The dot character is used as a delimiter to indicate the end of a macro variable reference. It’s only required when a macro variable reference is immediately followed by other characters that are valid characters in a macro variable name. The dot eliminates the ambiguity regarding where the macro variable reference ends and is absorbed by the macro processor as part of the resolution. Since this macro variable reference includes a double ampersand, it requires a two-pass resolution as discussed. One dot is absorbed during each pass. We want to leave a dot in the final resolved code as part of the filename, so we need to start with 3 dots.
Where would a . be used other than in a filename?
A dot could potentially appear between a library name and a data set name as part of a two-level naming convention. It could also be part of a format reference or just part of some quoted text. The key is to understand that the macro language is simply generating SAS code, and it’s the job of the programmer to ensure that the desired SAS code is produced.
Sorry if I had missed it, but will you touch on Macro Variables scope? Your sample macro programs keep using Global macro variables!
Macro variable scope is a complex topic that is mostly beyond the scope of this presentation. A good resource is Art Carpenter’s excellent book from SAS Press, Carpenter’s Complete Guide to the SAS® Macro Language, Third Edition (2016). There are also numerous SAS user group conference papers available online for free at LexJansen.com
Why %str(age=12) rather than just (age=12)?
The %STR macro function masks the equal sign character (=) so that it is not interpreted as part of the syntax of our macro call.
Can we have link to SAS help views documentation please?
You can use this link for the documentation.
I'm just asking about efficiency: to create variable lists, I usually use this syntax:
proc sql; select x into :mylist separated by ' ' from dsx; quit;
Then I use scanlist inside my do loop and count the number of entries using A. Carpenter's macro %wordcount(). Is that less efficient than creating so many variables?
We have also used that approach. Art Carpenter refers to it as a “horizontal” macro variable list and to the approach we presented as a “vertical” macro variable list. Both can be useful, and some situations lend themselves more to one approach than the other. We are not aware of any significant performance differences between the two, but that could vary depending on your specific application. It would be a good idea to perform some benchmarking with each method to understand the performance impacts if that is of concern.
Could you reiterate why you're using %sysfunc(compress(E RROR:)) . . . is there a problem if you use just %put ERROR: ?
That simpler approach will also work. However, we typically use automated log scanners to check our logs for errors and warnings. Since the code itself also appears in the log, a log scanner which is simply looking for any occurrence of “ERROR:” would identify the “%put ERROR:” as such an occurrence. The approach we showed avoids this.
Is there a way to use USERID macro when the userid is part of a data set name?
We aren’t quite clear on what you are asking. If you wish to create a data set that includes the current user’s ID as part of the data set name, you can simply reference &sysuserid in the SAS code that creates the data set. If that’s not what was meant, please feel free to contact us directly and we will do our best to help you.
How do you make the lists of macro variables that you generate through PROC SQL local or global?
By default, if the PROC SQL is within a macro definition, then any macro variables created will be on the local symbol table for that macro, and if the PROC SQL is not within a macro definition, then the macro variables will be on the global symbol table. However, if the PROC SQL is within a macro definition but the macro variables specified already exist as global macro variables, then those global macro variables will be used instead of local macro variables being created. When in doubt, use the %GLOBAL or %LOCAL statement before the PROC SQL to declare which macro symbol table is to be used for the macro variables and eliminate any ambiguity. Since you may not know in advance how many macro variables the PROC SQL will need to create, you will have to make sure you declare more than enough.
Recommended Resources
Carpenter’s Complete Guide to the SAS Macro Language, 3rd Edition
SAS 9.4 Macro Language Reference, 5th Edition
Using SAS® Macro Variable Lists to Create Dynamic Data-Driven Programs
Please see additional resources in the attached slide deck.
Want more tips? Be sure to subscribe to the Ask the Expert board to receive follow up Q&A, slides and recordings from other SAS Ask the Expert webinars.
... View more