I'd like to compute &rate across the range of variable 'scale' takes. Data 'want' then would have rate01 thru rate2 across all scales. But my code below produces only one column for a single rate.
Any idea why my code fails to create &rate for whole range?
&rate=(agerisk*&scale)/tot_pop;
data temp;
input tot_pop agerisk;
datalines;
15286 0.055
57522 0.217
28017 0.066
21669 0.064
17853 0.071
17325 0.080
19893 0.081
22637 0.072
22788 0.062
21019 0.048
17881 0.038
11968 0.034
8676 0.031
21670 0.060
;
%symdel;
%macro models(rate,scale);
data want; set temp;
&rate=(agerisk*&scale)/tot_pop;
run;
%mend models;
%models(rate01,0.1);
%models(rate02,0.2);
%models(rate03,0.3);
%models(rate04,0.4);
%models(rate05,0.5);
%models(rate06,0.6);
%models(rate07,0.7);
%models(rate08,0.8);
%models(rate09,0.9);
%models(rate1,1);
%models(rate11,1.1);
%models(rate12,1.2);
%models(rate13,1.3);
%models(rate14,1.4);
%models(rate15,1.5);
%models(rate16,1.6);
%models(rate17,1.7);
%models(rate18,1.8);
%models(rate19,1.9);
%models(rate2,2);
Because you always start from the TEMP data set so no previous changes are maintained.
Basically you overwrite your results with each iteration, so you need to reuse the data set in this case if you want to include the previous results.
Because you always start from the TEMP data set so no previous changes are maintained.
Basically you overwrite your results with each iteration, so you need to reuse the data set in this case if you want to include the previous results.
Since your rates are just .1,.2.3,... you could easily do this without macro code.
data want ;
set temp;
array rate rate01-rate20;
do i=1 to dim(rate);
rate(i) = (agerisk*(i/10))/tot_pop;
end;
drop i;
run;
What if rate01-rate20 wasn't known? I eventually would use more granular integers where I have no idea of n points in the range?
Use a separate array for the list of "scale" values.
So if I had 5 "scale" values I could use a program like this to calculate 5 new "rate" variables.
data want ;
set temp;
array rate (5) ;
array scale (5) _temporary_ (.1 .25 .5 1 1.5) ;
do i=1 to dim(rate);
rate(i) = (agerisk*scale(i))/tot_pop;
end;
drop i;
run;
You could make it dynamic by putting the list of values into a macro variable and then using COUNTW() to find out how many there were.
%let scales=.1 .25 .5 1 1.5;
%let n=%sysfunc(countw(&scales,%str( )));
So then use the macro variables to define the arrays.
array rate (&n) ;
array scale (&n) _temporary_ (&scales) ;
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.