DATA Step, Macro, Functions and more

Understanding Call Execute

Accepted Solution Solved
Reply
Respected Advisor
Posts: 4,936
Accepted Solution

Understanding Call Execute

Is there a functional difference between these two code blocks?

 

filename execute temp;
data _null_;
file execute; put "data test;";
do i = 1 to 5;
    file execute; put "x=" i "; output;";
    end;
file execute; put "run;";
run;
%include execute / source2;

data _null_;
call execute("data test;");
do i = 1 to 5;
    call execute(cats("x=", i, "; output;"));
    end;
call execute("run;");
run;

They seem perfectly equivalent to me. When would the two programming approaches differ?

PG

Accepted Solutions
Solution
‎01-15-2016 11:27 AM
Super User
Posts: 5,518

Re: Understanding Call Execute

They're the same (at least they appear to be) for this particular example, but there can be differences in theory.  Any macro language statements (%let, macro invocations, etc.) execute at different times with these two approaches.  Macro language statements execute immediately when initiated by CALL EXECUTE, which is not necessarily the order you would expect.  Only the SAS language statements generated by CALL EXECUTE wait for the current DATA step to complete.  On the other hand, %INCLUDE executes the statements in the order you would expect.

 

A simple example:

 

data _null_;

call execute ('%let color=Blue; data test; color=symget("color"); run; %let color=Red;');

run;

 

 

View solution in original post


All Replies
Solution
‎01-15-2016 11:27 AM
Super User
Posts: 5,518

Re: Understanding Call Execute

They're the same (at least they appear to be) for this particular example, but there can be differences in theory.  Any macro language statements (%let, macro invocations, etc.) execute at different times with these two approaches.  Macro language statements execute immediately when initiated by CALL EXECUTE, which is not necessarily the order you would expect.  Only the SAS language statements generated by CALL EXECUTE wait for the current DATA step to complete.  On the other hand, %INCLUDE executes the statements in the order you would expect.

 

A simple example:

 

data _null_;

call execute ('%let color=Blue; data test; color=symget("color"); run; %let color=Red;');

run;

 

 

Respected Advisor
Posts: 4,936

Re: Understanding Call Execute

[ Edited ]
Posted in reply to Astounding

Thanks! I tried

 

%let color=yellow;
data _null_;
call execute ('%let color=Blue; data test1; color=symget("color"); run; %let color=Red;');
color=symget("color");
put "Call Execute Color =" color;
run;

filename execute temp;
%let color=yellow;
data _null_;
file execute; put '%let color=Blue; data test2; color=symget("color"); run; %let color=Red;';
color=symget("color");
putlog "Include Temp File Color =" color;
run;
%include execute / source2;

I think I understand a bit better the difference now. As you said, what's going on is not immediately obvious. Would it be fair advice to keep call execute for the simpler tasks where the timing of macro execution is not an issue?

PG
SAS Super FREQ
Posts: 3,756

Re: Understanding Call Execute

My two cents: Writing the whole file and the using %INCLUDE is easier to understand and debug.  It works exactly like the corresponding SAS program would, and the interaction between global statements, macro, DATA step compilation, and DATA step execution is easier to figure out. As an added bonus, you can look at the program and even modify it if necessary.  You can also run the program many times without regenerating it.

 

The fact that certain statements are executed immediately whereas others are compiled and then executed at runtime makes this a hard problem.

 

In an interactive procedure (DATASETS, SQL, GLM, IML, ...) the problems with combining macro and CALL EXECUTE can be even more complex. It can require understanding the way that SAS compiles and executes statements, as shown in this PROC IML example that updates a macro variable in a loop.  See also this example of using CALL EXECUTE to set a global statement.

Super User
Posts: 10,046

Re: Understanding Call Execute

The implied difference is %include will execute the code directly ,will not interpret it .

While the code generated by  call execute() will be interpreted by compiler and then execute it .

Therefore %include is going to be faster .

 

For the small code , they are almost the same. I like CALL EXECUTE() better, but Tom like %include better though.

Occasional Contributor
Posts: 7

Re: Understanding Call Execute

I think in both cases %include or call execute the code has to be interpreted and then executed. I see no difference. Am I missing something?
Super User
Posts: 10,046

Re: Understanding Call Execute

No. %include is not going to be interpreted, while call execute() will . Did you see my example at last ? That is reason explain why the macro variable is not resolved in LOG , but %include will not  complain that .

 

the code generated by call execute() will firstly pass through compiler and try to resolve macro value, if can't resolve , it will print a WARNING message. 

the code generated by %include  will not pass through compiler, just execute the code directly like it is in code editor .and you will not see any WARNING message. 

Super User
Posts: 10,046

Re: Understanding Call Execute

One more different is the order of macro variable resolved is different .

Note: start two new sas session to run these two code . and You will see the difference.

 

/* First Code*/

filename execute temp;
data _null_;
file execute;
i=1;
put 'data _null_;call symputx("x",' i ');run; %put &x;';
run;
%include execute / source2;

 

 

 

/*Second Code*/

data _null_;
i=1;
call execute(cats('data _null_;call symputx("x",' ,i, ');run; %put &x;'));
run;

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 7 replies
  • 457 views
  • 5 likes
  • 5 in conversation