gordon.dewis.ca - Random musings from Gordon

Subscribe

Conditionally executing external code in SAS

June 23, 2014 @ 16:45 By: gordon Category: Programming, SAS

I use SAS fairly regularly in my job. I’ve taken a number of SAS programming courses, yet I don’t get to use much of what I’ve learned because the manner in which I use SAS is fairly basic. (A lot of SAS courses seem to use examples that don’t really relate to my work, such as business processes, evaluating credit scores and so on. I do a lot of statistical analysis of survey microdata.)

In a program I’m enhancing, I want to execute some code in another SAS program based on whether a certain variable is set to a certain value. In most languages, such as Perl or C, you would put this in an if-then-else construct and you’d be done. Because of the procedural nature of SAS, with data steps and macros, it’s not that straightforward.

I did some googling on the basis that I can’t possibly be the only person wanting to do this (it turns out I’m not) and found a thread on this very topic in the SAS Support Community forums. Wading through the responses, I found a several different ways people suggested doing it; some people who couldn’t possibly envision why you’d want to do it; a couple who got hung up on the content of the programs that the original poster wanted to conditionally execute; and one answer that stood out from all the others in terms of its simplicity, which I’ve included almost verbatim below, with some comments for clarity.

Scenario: You want to setup some variables using some external snippets of code, depending on whether a flag is set to “red” or “blue” or “pumpkin” or… (you get the idea).
Using a _null_ datastep, you can %INCLUDE the external snippets of code using CALL EXECUTE like this:

%let colour="blue"; /*Set the flag variable as required. */
:
:
data _null_;
colour = "&colour"; /* Bring value of the SAS macro variable &colour into the datastep variable colour */
if colour='blue' then call execute ('%include "program1.sas";'); /* include program1.sas only if colour is blue */
else if colour='red' then call execute ('%include "program2.sas";'); /* include program2.sas only if colour is red -- additional if-elses as required */
run;
:
:

The desired external program file will be executed at that point in the program and then it carrys on after the run at the end of the _null_ datastep.
This is a great way to do it because it avoids SAS MACROs, which can get a little hairy, and it’s quite flexible. If you wanted to run more than one external program when colour is blue, you could either add a DO block to the THEN and then put as many CALL EXECUTEs are needed in the block or you could put the other %includes in the same CALL EXECUTE statement after the semicolon in the parameters to the CALL EXECUTE like this:

if colour='blue' then call execute ('%include "program1.sas"; %include "program3.sas";');

Personally, I wouldn’t choose this option because it’s not as clear as this structure, particularly with the nested quotes:

if colour='blue' then do;
call execute ('%include "program1.sas";');
call execute ('%include "program3.sas";');
end;

Hopefully, this will help the next person trying to figure out how to conditionally execute code in external programs in SAS.


A tip o’ the hat to SAS Support Community member SASKiwi for providing the most elegant answer.

Leave a Reply