Sanity Check - Lack of %eval()

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 122
Accepted Solution

Sanity Check - Lack of %eval()

I have the following code which I managed to run and get desirable results. I did not expect to be able to run the code below, however, because I do not use the %eval() function when evaluating the ratios in the last datastep. Without the %eval(), shouldn't the ratios be evaluated as characters and shouldn't I be getting an ERROR as a result?

Could someone please provide a sanity check?

%macro count_runoff_all;

%do i= 1 %to 9;

proc sql ;  
select count(psts3)     
into :n_def_runoff&i.

from runoff_all&i

where psts3="n6";

quit;


%end;

%put n_def_runoff1 value is: &n_def_runoff1;
%put n_def_runoff2 value is: &n_def_runoff2;
%put n_def_runoff2 value is: &n_def_runoff3;
%put n_def_runoff2 value is: &n_def_runoff4;
%put n_def_runoff2 value is: &n_def_runoff5;
%put n_def_runoff2 value is: &n_def_runoff6;
%put n_def_runoff2 value is: &n_def_runoff7;
%put n_def_runoff2 value is: &n_def_runoff8;
%put n_def_runoff2 value is: &n_def_runoff9;


data default_runoff_all;

set runoff9;

randv=rand("Uniform");
 
  if randv < &n_def_runoff1/&n_def_runoff9 then quarter = 1;

  else if randv < &n_def_runoff2/&n_def_runoff9 then quarter = 2;

  else if randv < &n_def_runoff3/&n_def_runoff9 then quarter = 3;

  else if randv < &n_def_runoff4/&n_def_runoff9 then quarter = 4;
  else if randv < &n_def_runoff5/&n_def_runoff9 then quarter = 5;
  else if randv < &n_def_runoff6/&n_def_runoff9 then quarter = 6;

  else if randv < &n_def_runoff7/&n_def_runoff9 then quarter = 7;

  else if randv < &n_def_runoff8/&n_def_runoff9 then quarter = 8;

  else quarter = 9;

  n_def_runoff1_ratio=&n_def_runoff1/&n_def_runoff9;
  n_def_runoff2_ratio=&n_def_runoff2/&n_def_runoff9;
  n_def_runoff3_ratio=&n_def_runoff3/&n_def_runoff9;
  n_def_runoff4_ratio=&n_def_runoff4/&n_def_runoff9;
  n_def_runoff5_ratio=&n_def_runoff5/&n_def_runoff9;
  n_def_runoff6_ratio=&n_def_runoff6/&n_def_runoff9;
  n_def_runoff7_ratio=&n_def_runoff7/&n_def_runoff9;
  n_def_runoff8_ratio=&n_def_runoff8/&n_def_runoff9;
  /*drop fcst_mon draw randv n_def_runoff1_ratio n_def_runoff2_ratio n_def_runoff3_ratio n_def_runoff4_ratio n_def_runoff5_ratio
    n_def_runoff6_ratio n_def_runoff7_ratio n_def_runoff8_ratio;*/

run;

%mend;


%count_runoff_all;


Attachment
Attachment

Accepted Solutions
Solution
‎07-21-2014 04:10 PM
Super User
Posts: 11,343

Re: Sanity Check - Lack of %eval()

Posted in reply to maroulator

%eval is to resolve integer arithmetic with macro variables. You have created data step syntax which resolves as it should.

Since each of your macro variables apparently resolve to numbers you are generating syntax like    9/45 which the data step processes as a division statement.

View solution in original post


All Replies
Solution
‎07-21-2014 04:10 PM
Super User
Posts: 11,343

Re: Sanity Check - Lack of %eval()

Posted in reply to maroulator

%eval is to resolve integer arithmetic with macro variables. You have created data step syntax which resolves as it should.

Since each of your macro variables apparently resolve to numbers you are generating syntax like    9/45 which the data step processes as a division statement.

Super User
Super User
Posts: 7,039

Re: Sanity Check - Lack of %eval()

Posted in reply to maroulator

Huh?  I do not see any macro conditional logic there that would require %EVAL().

This line of code is just generating a simple SAS statement.

   if randv < &n_def_runoff1/&n_def_runoff9 then quarter = 1;


So if those two macro variables evaluate to 3 and 103 , respectively, then it is the same as if you wrote


if randv < 3/103 then quarter = 1;

SAS knows how to divide numeric constants.

🔒 This topic is solved and locked.

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

Discussion stats
  • 2 replies
  • 225 views
  • 3 likes
  • 3 in conversation