I am trying to create multiple flags in my dataset GB1_1, GB1_2, ....... GB1_36, but failing miserably, how do I create numeric variables using macro code (below is what I tried)
%macro gb1(howmany);
%do i=1 %to &howmany;
%if status&i = 1 %then %let &gb1_&i = %syseval(1*1);
%else %if status&i = 2 %then %let &gb1_&i = %syseval(1*1);
%else %if dpd&i >= 2 %then %let &gb1_&i = %syseval(1*1);
%else %if ((dpd&i < 2) and (dpd&i >= 1)) %then %let &gb1_&i = %syseval(2*1);
%else %let &gb1_&i = %syseval(0*1);
%end;
%mend gb1;
GB takes the value 0,1,2 dependent on the conditions above
please help
Is statusn a variable in your data step?
Macro logic can handle creation of regular programming syntax, but not based on values/conditions within a data step.
If you need to create and assign dynamic no variable depending on values in a data step, it's quite complex - not quite understand the logic in your attempt.
What do your try to achieve - what does the logic represent?
being a data modeler, creating lot's of variables/columns is seldom a good way forward. Preparing for data mining is one of very few use cases I know of.
Provide example (test data in a datastep), required output. I can't see what your trying to do here. Macro variables are *always* character. Macro language is basically a code generator, nothing more. Logic should be done in Base SAS. If you really need a macro flag then:
data _null_;
if &STATUS1="Y" then result="Y";
...
else result="N";
call symput('RESULT',result);
run;
status&i will resolve to "status1", "status2", and so on. Note that I used the quotes to make clear that we are dealing with strings here.
When the macro compares "status1" to "1" (because macro values are ALWAYS character), this condition will never be true. The same goes for "dpd1" and so on.
Since there never has been a declaration of macro variable gb1_, all the references to it will fail.
If macro variable gb1_ was set to X, then &gb1_&i would resolve to X1 in the first iteration of the macro do loop.
Actually, what do you want to achieve (logically)?
Just a single line from your code illustrates the issues you have to fix:
%if status&i = 1 %then %let &gb1_&i = %syseval(1*1);
First, it needs to be simplified. Assigning a numeric value is straightforward and does not require a function:
%if status&i = 1 %then %let &gb1_&i = 1;
If you were to use a function, there is no function named %SYSEVAL. There's %EVAL, and %SYSEVALF, but not %SYSEVAL.
Next, what is the outcome supposed to be? Assigning a value to the macro variable GB1_1 should remove an ampersand:
%if status&i = 1 %then %let gb1_&i = 1;
If the intended result is something different, you will need to explain.
Finally, what in the world is STATUS1 supposed to be? A macro variable named STATUS1? A DATA step variable named STATUS1? A series of 7 characters "STATUS1"? You will definitely need to explain that as well.
Good luck.
Sounds like you want to use ARRAY instead of macro logic.
data want ;
set have ;
array s status1-status36 ;
array d dpd1-dpd36 ;
array g gb1-gb36 ;
do i=1 to dim(s);
if s(i) =1 then g(i)=1 ;
....
end;
run;
I'll back up Tom's answer: use arrays
and suggest assignment with a select series block
do i = dim(s);
select;
when() g(i) =1;
when() g(i) =2;
otherwise g(i) =0
end;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.