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," ")
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
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.