%scan in macro

Reply
Occasional Contributor yym
Occasional Contributor
Posts: 6

%scan in macro

Hi, I was trying to create lag variables for all my variables in the data. To make it easy, assusme I only have two variables in the data: a and b. However the code below does not work. 

 

data t2;
set t;
do i=1 to 2;
%let var=%scan(&vars.,i);
&var._lag1 = lag1(&var.);
end;
run;

 

The errow message was "ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: i
ERROR: Argument 2 to macro function %SCAN is not a number."

 

but after I put it in macro function the code below works. Can anybody help me to understand the reason?


%macro ts;
data t2;
set t;
%do i=1 %to 2;
%let var=%scan(&vars.,&i.);
&var._lag1 = lag1(&var.);
%end;
run;
%mend;
%ts;

 

Super User
Posts: 5,367

Re: %scan in macro

What do you mean by "the code below works"?  The error message might disappear, but does it really do what you want it to do?

Occasional Contributor yym
Occasional Contributor
Posts: 6

Re: %scan in macro

yes it does what I wanted. But I am trying to figure out why the first part does not work

Super User
Posts: 11,134

Re: %scan in macro

Run the code with OPTIONS MPRINT; run prior to the call to the macro. The log will show the code generated by the macro call. That may help you see why it isn't doing quite what you expect.

Super User
Posts: 5,367

Re: %scan in macro

OK ... it doesn't work because macro language does not use data step variables.  This expression causes trouble:

 

%let var=%scan(&vars.,i);

 

The last parameter to %scan, "i", is just text.  It is not a reference to a variable.

Super User
Posts: 19,167

Re: %scan in macro

Your mixing a data step loop with a macro loop. The data step loop does not create a macro variable, i, but the macro loop does.
Trusted Advisor
Posts: 1,116

Re: %scan in macro

The %LET statement cannot be used in a data step, although it does not always cause a syntax error if it is (misleadingly) placed inside a data step.

 

As a macro language statement it is executed before the data step is even compiled. Therefore, values of data step variables are unavailable to it. For the data step, in turn, the %LET statement is completely invisible.

 

The same holds for other macro language statements which are valid in open code. For example, try a %PUT statement in an IF-THEN-DO-END block of a data step. You will see that %PUT is executed regardless of the IF condition being true or false and even if compilation of the data step stops prematurely because of some syntax error. So, it does not make sense to place it there.

 

Super User
Posts: 9,874

Re: %scan in macro

Make a macro variable to hold these statement. OR Would you like to use IML code ?

 

data have;
 set sashelp.class;
run;
proc sql;
 select cats(name,'_lag1=lag(',name,')') into : lag separated by ';'
  from dictionary.columns 
   where libname='WORK' and memname='HAVE' and type='num';
quit;
data want; 
 set have;
 &lag ;
run;
Regular Learner
Posts: 1

Re: %scan in macro

Hi,

 

%scan function distinctively designed for Macro's, but here, you are mixing macro function in open source data step. SAS does not allow you to do this. when ever you call / create any macro related functionality it sould be done within the macros(though there are exeptions like creating macro varible using Call symput).

 

Thank you,

Srinath.

Ask a Question
Discussion stats
  • 8 replies
  • 539 views
  • 0 likes
  • 7 in conversation