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?
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....
This does not work. I would like the value of n%eval(&k-1) instead of the name of it.
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;
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?
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.
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)));
%let j= %eval(&k-1);
when &&n&j le myvar le &&n&k then %scan(&response,&k," ")
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?
Why do you say that the %let j= can't be used in the case structure?
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 &&¤t 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
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," ")
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.