Hello
Lets say I have list of variables names in a macro variable separated by '+'.
Lets say that I want to run macro that run on each of the variables.
What is the way to do it please via code that do it automatically?
%let numeric_Vars=
a_Shir_SmlHov_Pigur+
a_Shir_AKM_HZRHIUV+
a_Shir_Vetek_age_Balut+
a_CDO_ExCC_mx_pos_prob
;
/**Want to run this***/
%inf_value(ttt,information_value,a_Shir_SmlHov_Pigur,Ind_Failure);
%inf_value(ttt,information_value,a_Shir_AKM_HZRHIUV,Ind_Failure);
%inf_value(ttt,information_value,a_Shir_Vetek_age_Balut,Ind_Failure);
%inf_value(ttt,information_value,a_CDO_ExCC_mx_pos_prob ,Ind_Failure);
In a DATA step, run a DO loop over the string containing the macro value (use COUNTW to detrrmine the number of iterations). Use SCAN to extract the single variable names.
Either use CALL EXECUTE to call the macro, or write the code to a temporary file for a later %INCLUDE.
You need make a macro to repeat %inf_value() .
%macro inf_value(ttt,information_value,numeric_Vars,Ind_Failure);
%put &numeric_Vars.;
%mend;
%let numeric_Vars=
a_Shir_SmlHov_Pigur+
a_Shir_AKM_HZRHIUV+
a_Shir_Vetek_age_Balut+
a_CDO_ExCC_mx_pos_prob
;
%macro repeat(let);
%do i=1 %to %sysfunc(countw(&let.,+));
%let temp=%scan(&let.,&i,+);
%inf_value(ttt,information_value,&temp.,Ind_Failure);
%end;
%mend;
%repeat(&numeric_Vars.)
You could use one of the methods you just learned for parsing the macro variable.
A data step for example:
data _null_;
do i=1 to to countw("&numeric_Vars",'+');
call execute('%nrstr(%inf_value)(ttt,information_value,'
||scan("&numeric_vars",i,'+')
||',Ind_Failure)'
);
end;
run;
But perhaps the code that macro is generating using that third positional parameter is something that can accept multiple variables? For example if the macro definition as something like:
%macro inf_value
(parm1 /* ttt */
,parm2 /* information_value */
,parm3 /* numeric variable */
,parm4 /* Ind_Failure */
);
proc reg dataset=analysis_set_&parm1 ;
where group ="&parm2";
model &parm4 = &parm3 ;
run;
%mend inf_value;
Then you could call with something like:
%inf_value(ttt,information_value
,a_Shir_SmlHov_Pigur
a_Shir_AKM_HZRHIUV
a_Shir_Vetek_age_Balut
a_CDO_ExCC_mx_pos_prob
,Ind_Failure);
And it might make sense.
In that case it would be better to use space instead of + as the delimiter between the variable names.
If not you could possible modify the macro to add a %DO loop to loop over the list of values.
%macro inf_value(parm1,parm2,parm3_list,parm4);
%local i parm3 ;
%do i=1 %to %sysfunc(countw(&parm3_list,+));
%let parm3=%scan(&parm3_list,&i,+);
/* body of the original macro */
%end;
%mend inf_value;
In which case you could call it with your list substituted into the third positional parameter.
%inf_value(ttt,information_value,&numeric_vars,Ind_Failure);
And if you cannot modify the macro then make a new macro so you can have it run the %DO loop and generate the calls to the original macro.
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
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.
Ready to level-up your skills? Choose your own adventure.