Dear all,
I wanted to set up a macro to run quite a few logistic regression models. My question is how to I code it in such a way that
for the first 10 models, the macro would use bi as the dependent variable, for the next 10 models, use bi2 as the dependent variable etc.
The codes highlighted in purple wouldnt work.
%MACRO a;
%IF 1 <= &i <= 10 %THEN %DO; %LET &dep = bi; %END;
%IF 11 <= &i <= 20 %THEN %DO; %LET &dep = bi2; %END;
%IF 21 <= &i <= 30 %THEN %DO; %LET &dep = bi3; %END;
PROC LOGISTIC DATA = x;
MODEL &dep (REF = "Yes")= &indep;
RUN;
%MEND a;
%a(indep = mde, i = 1)
%a (indep = pds, i = 2)
%a (indep = pts, i = 3)
%a (indep = so, i = 4)
%a (indep = sp, i = 5)
:
%a(indep = pe, i = 30)
Any input is much appreciated. Thanks!
I can see several problems there.
Try it like this:
%MACRO a(indep=, i=);
%if %eval(&i >= 1 and &i <= 10)
%then %let dep = bi;
%else %if %eval(&i >= 11 and &i <= 20)
%then %let dep = bi2;
%else %if %eval(&i >= 21 and &i <= 30)
%then %let dep = bi3;
PROC LOGISTIC DATA = x;
MODEL &dep (REF = "Yes")= &indep;
RUN;
%MEND a;
The %eval isn't strictly necessary, but I always use it - it tends to pick up typing mistakes faster that I inevitably introduce to my code! I also like to use %else like this, where the conditions are mutually exclusive; sadly macro code doesn't have a %select statement. (Indentation like this not obligatory, of course…)
The %IF statement, really the implied %EVAL() function call, will not convert
A <= B <= C
into
(A<=B) and (B<=C)
like the IF statement will.
So you need to do that yourself.
I can see several problems there.
Try it like this:
%MACRO a(indep=, i=);
%if %eval(&i >= 1 and &i <= 10)
%then %let dep = bi;
%else %if %eval(&i >= 11 and &i <= 20)
%then %let dep = bi2;
%else %if %eval(&i >= 21 and &i <= 30)
%then %let dep = bi3;
PROC LOGISTIC DATA = x;
MODEL &dep (REF = "Yes")= &indep;
RUN;
%MEND a;
The %eval isn't strictly necessary, but I always use it - it tends to pick up typing mistakes faster that I inevitably introduce to my code! I also like to use %else like this, where the conditions are mutually exclusive; sadly macro code doesn't have a %select statement. (Indentation like this not obligatory, of course…)
Since you have control of &i as a parameter, you don't really need to safeguard against unusual values. You could simplify this to:
%if &i <= 10 %then %let dep = bi;
%else %if &i <= 20 then %let dep = bi2;
%else %let dep = bi3;
It's remotely possibly that the original %LET statements were correct. More likely, the %LET statements should assign a value to DEP (as illustrated above), not to &DEP (as in your original code).
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.