Say here is a dataset contain 10 rows, and each row contains parameters for calling a macro(return a value) ... how to make doable?!
data ds_para;
input ind indst indend sign;
datalines;
1 800 1100 -1
2 4000 5000 1
3 6000 7000 -1
4 7500 8500 1
5 9000 9500 -1
6 14000 15000 1
7 18000 20000 -1
8 20500 21500 1
9 22000 23000 -1
10 23000 24000 1
10 24000 25000 -1
;run;quit;
%macro macro2call(ind, indst, indeend, sign);
.....
&ReturnVar
%mend;
If the macro does not generate any SAS code then use the RESOLVE() function.
data want;
set ds_para ;
result=resolve(cats('%macro2call(',catx(',',ind,indst,indend,sign),')'));
run;
If the macro generates SAS code then CANNOT return the results as if it was a function. In that case look into use DOSUBL() function call so that the macro does not generate any SAS code in the current session.
The best outcome would be a dataset with 10 rows, each has the ReturnVar
One approach is to use CALL EXECUTE like in this post: https://communities.sas.com/t5/SAS-Programming/Assigning-value-to-a-macro-variable-within-a-datastep...
Thanks,
But somehow %let ReturnVar=%eval(&indst.+&indend.); complains?!
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand
is required. The condition was: indend+
3704 call execute(%macro2call(indst, indend));
If %let ReturnVar=%eval(5+8); then it is fine. Confused ...
data ds_para;
input ind indst indend sign;
datalines;
1 800 1100 -1
2 4000 5000 1
3 6000 7000 -1
4 7500 8500 1
5 9000 9500 -1
6 14000 15000 1
7 18000 20000 -1
8 20500 21500 1
9 22000 23000 -1
10 23000 24000 1
;run;quit;
%global ReturnVar;
%macro macro2call(ind, indst, indend, sign);
/*%let ReturnVar=%eval(5+8); works*/
%let ReturnVar=%eval(&indst.+&indend.);/*?!*/
&ReturnVar
%mend;
data ds_para;
set ds_para;
call execute(%macro2call(indst, indend));
mmind=&ReturnVar.;
run;quit;
If the macro does not generate any SAS code then use the RESOLVE() function.
data want;
set ds_para ;
result=resolve(cats('%macro2call(',catx(',',ind,indst,indend,sign),')'));
run;
If the macro generates SAS code then CANNOT return the results as if it was a function. In that case look into use DOSUBL() function call so that the macro does not generate any SAS code in the current session.
Tom:
Thanks a huge. It indeed works. But how to save out the result on each call(the results are diff. but I can only save out the last call result).
/* pass coln as para
call macro within dataset*/
data ds_para;
input ind indst indend sign;
datalines;
1 800 1100 -1
2 4000 5000 1
3 6000 7000 -1
4 7500 8500 1
5 9000 9500 -1
6 14000 15000 1
7 18000 20000 -1
8 20500 21500 1
9 22000 23000 -1
10 23000 24000 1
;run;quit;
data tempx;
do i=1 to 30000;
x=ranuni(0);
output;
end;
run;quit;
%global ReturnVar;
%macro test(ind, indst, indend, sign);
%if &sign=-1 %then %do;
proc sql noprint;
select i into: ReturnVar
from tempx
where i between &indst. and &indend.
having x=min(x);
quit;
%end;
%if &sign= 1 %then %do;
proc sql noprint;
select i into: ReturnVar
from tempx
where i between &indst. and &indend.
having x=max(x);
quit;
%end;
%put "ReturnVar=&ReturnVar.";
%mend;
/* works below: resolve() but only without "any" sas code
DOSUBL() if sas code
*/
data want ;
set ds_para ;
/*result=resolve(cats('%test(',catx(',',ind,indst,indend,sign),')'));*/
t=DOSUBL(cats('%test(',catx(',',ind,indst,indend,sign),')'));
res="&ReturnVar.";
result=put("&ReturnVar.",8.);
run;
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: