Help using Base SAS procedures

how to compare the value of macro variable with normal variable's

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 7
Accepted Solution

how to compare the value of macro variable with normal variable's

code ,results are as followed,

 

why macro varable value when compared with normal var within macro environment happends an error ?

 

code

%macro comp;

data test;
do n = 1 to 5;
output;
end;
run;

data comp;
set test;
length k 3 d1 3 d2 3 d3 3;
%do i = 1 %to 3;
%if n > %eval(&i.) %then %do;
k=%eval(&i.);
d&i.=1;
output;
%end;
%end;
run;

%mend;

%comp;

 

expected :

nkd1d2d3
11   
12   
13   
211  
221  
231  
311  
3211 
3311 
411  
4211 
43111
511  
5211 
53111

 

 

but actually:

nkd1d2d3
111  
1211 
13111
211  
2211 
23111
311  
3211 
33111
411  
4211 
43111
511  
5211 
53111

Accepted Solutions
Solution
‎09-08-2017 11:40 PM
Super User
Super User
Posts: 8,116

Re: how to compare the value of macro variable with normal variable's

[ Edited ]

Turn on the MRINT option so you can see what code your macro logic is generating.

 

The ASCII code for the lowercase letter N is always greater than the ASCII codes for any string of digits that the macro variable I might evaluate to.  So your %IF test is always true where &I is 1 , 2 or 3.  Which means that your macro %DO loop will generating these lines of SAS code for your data step to execute.

   k=1;
   d1=1;
   output;
   k=2;
   d2=1;
   output;
   k=3;
   d3=1;
   output;

I suspect that you actually thought that your macro %IF statement could compare the variable N from the the dataset to the numbers 1, 2 and 3.  But the macro code has finished running and doing its job of generating code before the generated data step begins running.  You would need to use an IF statement instead of a %IF statement if you want to access the value of the variable N.

 

Of course if you want K to go from 1 to 3 then it is much easier to do that using a DO loop instead of trying to use a macro %DO loop to generate a bunch of assignment statements.  

 

Also your expected output does not really depend on the value of N at all, so not sure why you added the comparison to N anyway.

 

Try something like this instead, macro code not required.

data test;
  do n = 1 to 5;
    output;
  end;
run;
data comp;
  set test;
  do k=1 to 3 ;
    array d (3);
    do i=1 to k ;
      d(i)=1;
    end;
    output;
  end;
  drop i;
run;

   

View solution in original post


All Replies
Super User
Super User
Posts: 9,599

Re: how to compare the value of macro variable with normal variable's

You are mixing datastep language and macro language which will not work.  They are two separate pieces.  Learn how to program using Base SAS first, then move onto the more advanced topic of macro creation.  For this question, post example test data in the form of a datastep (so we can run it), and then show what you want the output to look like, there is nothing in the code you posted which can't be done in Base SAS.

 

New Contributor
Posts: 2

Re: how to compare the value of macro variable with normal variable's

Just adding to the correct answer of RW9.  With a few exceptions, it is best to think of the SAS Macro language as a word processor, which does its work BEFORE the data step.

 

With this concept in mind, it seems nonsensical to have a macro %DO loop inside of data step--even if it doesn't throw an error.  The macro statement  will be evaluated before the data step is compiled, let alone executed.  

 

When you think about it this way, you can see that RW9's response is correct--and deserves to be assigned the correct answer--even if you have to go back and rethink your problem! 

 

 

 

 

Occasional Contributor
Posts: 7

Re: how to compare the value of macro variable with normal variable's

Thx for your advice. i've made my way on Cat Happy

Contributor
Posts: 29

Re: how to compare the value of macro variable with normal variable's

[ Edited ]

Hi,

I think you messed up the %macro statement. %macro statement is only used for macro variables. For example, in the line " %if n > %eval(&i.) %then %do;", n is not macro variable, it can not be used in %if statement. I wrote an update for your DATA STEP of comp. The output seems to be similar to your expectation.

 

data comp;
	set test;
	by n;
	retain k d1 d2 d3;
	if first.n then do;
		call missing(d1,d2,d3);
		k=1;
		%do i = 1 %to 3;
			k=&i.;
			d&i.=1;
			output;
		%end;
	end;
run;

 

Contributor
Posts: 29

Re: how to compare the value of macro variable with normal variable's

Thank you for your input. I learned a lot.
Occasional Contributor
Posts: 7

Re: how to compare the value of macro variable with normal variable's

let's move on !Cat Happy

Occasional Contributor
Posts: 7

Re: how to compare the value of macro variable with normal variable's

Thx for your reply , i ran your code , but turned an error. 

 

I've got an solution, 

 

data test;
do n = 1 to 5;
output;
end;
run;

data comp;
set test;
do k=1 to 3 ;
array d (3);
do i=1 to k ;
if n >= i then d(i) = 1;
end;
output;
end;
run;

Solution
‎09-08-2017 11:40 PM
Super User
Super User
Posts: 8,116

Re: how to compare the value of macro variable with normal variable's

[ Edited ]

Turn on the MRINT option so you can see what code your macro logic is generating.

 

The ASCII code for the lowercase letter N is always greater than the ASCII codes for any string of digits that the macro variable I might evaluate to.  So your %IF test is always true where &I is 1 , 2 or 3.  Which means that your macro %DO loop will generating these lines of SAS code for your data step to execute.

   k=1;
   d1=1;
   output;
   k=2;
   d2=1;
   output;
   k=3;
   d3=1;
   output;

I suspect that you actually thought that your macro %IF statement could compare the variable N from the the dataset to the numbers 1, 2 and 3.  But the macro code has finished running and doing its job of generating code before the generated data step begins running.  You would need to use an IF statement instead of a %IF statement if you want to access the value of the variable N.

 

Of course if you want K to go from 1 to 3 then it is much easier to do that using a DO loop instead of trying to use a macro %DO loop to generate a bunch of assignment statements.  

 

Also your expected output does not really depend on the value of N at all, so not sure why you added the comparison to N anyway.

 

Try something like this instead, macro code not required.

data test;
  do n = 1 to 5;
    output;
  end;
run;
data comp;
  set test;
  do k=1 to 3 ;
    array d (3);
    do i=1 to k ;
      d(i)=1;
    end;
    output;
  end;
  drop i;
run;

   

Occasional Contributor
Posts: 7

Re: how to compare the value of macro variable with normal variable's

thanks for you reply. u are right! But the variable n created just for test, it could be any numeric var. so i made a little change in your code ,then things got right!! data test; do n = 1 to 5; output; end; run; data comp; set test; do k=1 to 3 ; array d (3); do i=1 to k ; d(i)=1; end; output; end; drop i; run;
Occasional Contributor
Posts: 7

Re: how to compare the value of macro variable with normal variable's

sorry , i just put the wrong code.

 

here is the solution:

 

data test;
do n = 1 to 5;
output;
end;
run;

data comp;
set test;
do k=1 to 3 ;
array d (3);
do i=1 to k ;
if n >= i then d(i) = 1;
end;
output;
end;
run;

Occasional Contributor
Posts: 7

Re: how to compare the value of macro variable with normal variable's

yeah!

 

An another solution is turnd %if  .. %then to if...then..

☑ This topic is solved.

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

Discussion stats
  • 11 replies
  • 1449 views
  • 3 likes
  • 5 in conversation