DATA Step, Macro, Functions and more

&var and %eval, cannot combine??

Reply
Contributor
Posts: 50

&var and %eval, cannot combine??

I have defined macro variables nclass, n0, n1, ..., n&nclass, and response, then I have the following code:

proc sql undo_policy=none;

  create table temp as

  select *,

         case

           %do k=1 %to &nclass;

               when &n%eval(&k-1) le myvar le &&n&k then %scan(&response,&k," ")

           %end;   

           else .   

         end as RC

  from temp;

quit;

The problem with the above code is: &n%eval(&k-1), there is no problem with &&n&k.

Basically it evaluates &n then combine with 0 when k=1. If n is not defined, then it will have unresolved macro variable N problem; if n is defined as 357, for instance, then it will give 3570 for

&n%eval(&k-1) when k=1. What I really want is the value of macro variable n0.  Even when I use &&n%eval(&k-1), it still does not work. How can I represent the value of n0 when k=1?

Contributor
Posts: 61

Re: &var and %eval, cannot combine??

Just Use 'n%eval(&k-1)' this should work.

when you use &n%eval(&k-1), sas will consider n as mactro variable, but now it will be considered a string for macro processing and after that it will be considered as n0,n1--- accordingly after the macro variable resolution....

Contributor
Posts: 50

Re: &var and %eval, cannot combine??

This does not work. I would like the value of n%eval(&k-1) instead of the name of it.

Super User
Super User
Posts: 7,407

Re: &var and %eval, cannot combine??

Hi,


What are you attempting to do.  Provide test data and example output.  I would avoid using macro lists and loops to scan over these, its gets complicated and messy.  Have a look at array processing for instance.

Assuming dataset of:

A          B          N1NCLASS     N2NCLASS     N3NCLASS     N1K     N2K     N3K     N1RESPONSE     N2RESPONSE     N3RESPONSE

Then code such as:
data want;

     set have;

     array nvals{3} n1nclass n2nclass n3nclass;

     array kvals{3} n1k n2k n3k;

     array rvals{3} n1response n2response n3response;

     do I=2 to 3; /* Note 1 does not have a -1! */

          if nvals{I-1} le kvals{I} then result=scan(rvals{I},i," ");

     end;

run;

Of course, if you number your variables such:

NCLASS1 NCLASS2 NCLASS3, NK1 NK2 etc.

then you can also use the - to show list which will shrink your code.

data want;

     set have;

     array nvals{3} n1nclass-n3nclass;

Contributor
Posts: 50

Re: &var and %eval, cannot combine??

While arrray is an alternative and helpful sometimes, but it is not macro programming. The response variable is a input parameter. Can we use arrray as an input parameter of a macro program?

Super User
Super User
Posts: 7,407

Re: &var and %eval, cannot combine??

Its hard to tell, as there is no full code to show what you are doing.  My first question would be why do you need reponse var as a parameter, or have this in a macro at all?  Put response var in a dataset, then use joins to get the result rather than a where clause.  Best bet, provide some test code/data and what you want out of it.

Contributor
Posts: 61

Re: &var and %eval, cannot combine??

Use this code this should work,

%sysfunc(cat(&n,%eval(&k-1)))

The error is mainly because the values &n and %eval are considered as different macro invocations, I thought that if we can make this concatinated.

This resolves the value, but the warning is still there.

I tried it with below code,
%let n1 = afdsjhysadjh;
%let k = 2;
%put %sysfunc(cat(&n,%eval(&k-1)));

Super User
Posts: 10,516

Re: &var and %eval, cannot combine??

%let j= %eval(&k-1);

when &&n&j le myvar le &&n&k then %scan(&response,&k," ")

Contributor
Posts: 50

Re: &var and %eval, cannot combine??

If you check my above code, you see it was in a sql case structure. I guess you cannot use %let j= %eval(&k-1) in the case structure. That is why I did not assign %eval(&k-1) to an auxilary variable. Do you have other ways?

Super User
Posts: 10,516

Re: &var and %eval, cannot combine??

Why do you say that the %let j= can't be used in the case structure?

Super User
Super User
Posts: 6,502

Re: &var and %eval, cannot combine??

To do that type of relative name expansion it is easier if you make a new variable to hold the name.

%let n0=000;

%let k=1 ;

%let name=n%eval(&k-1);

%put &&&name ;

So your loop could be re-written as :

%do k=1 %to &nclass;

   %let previous=n%eval(&k-1);

   %let current=n&k;

   when &&&previous le myvar le &&&current then %scan(&response,&k," ")

%end; 

But you can eliminate the N0,N1,... macro variables and just make a delimited list of values like you have a delimited list of responses.

%let values=0 10 20 ;

%let responses=X Y Z ;

%let nclass=%sysfunc(countw(&values,%str( )));

...

   case

%do k=1 %to &nclass-1;

   when %scan(&values,&k,%str( )) <= MYVAR <= %scan(&values,&k+1,%str( ))

   then %scan(&response,&k,%str( ))

%end; 

   else %scan(&response,&nclass,%str( ))

   end

SAS Employee
Posts: 23

Re: &var and %eval, cannot combine??

I believe that this question has already been answered, but here is yet another solution:

when %unquote(%nrstr(&n)%eval(&k-1)) le myvar le &&n&k then %scan(&response,&k," ")

Ask a Question
Discussion stats
  • 11 replies
  • 423 views
  • 1 like
  • 6 in conversation