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;
%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.
%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.
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.
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.