I tried to create new variables called nodup_supd_&m.d when ntdc_&m.d=0 (m could be 0,1,2,3). I used a do-loop which should have stopped once ntdc_&m.d changed to 1. However, it did not stop when ntdc_&m.d=1. It completed the loop until &m>3. It seems neglect the condition of "&done2" = "yes". Could someone help fix it? Thanks!
%macro drug_ntdc(type,num,op);
data ntdc_&type.&Num.d_wide1;
set ntdc_&type.&Num.d_wide ;
%let done2=no;
%let m=0;
%do %until (("&done2" = "yes") or (&m>3));
nodup_supd_&m.d= supd_&m.d;
/*this step did not work*/
if ntdc_&m.d=1 then call symput('done2','yes');
%let m = %eval(&m+1);
%end;
run;
%mend;
%drug_ntdc(opioid,3,op=1);
The SAS macro language is a text generator. Macro statements are executed before Data Step Statements. So the timing is off here. In the snippet below, you have a condition in your %do %until macro statement that is based on &done2. You try to manipulate the value of &done2. during data step execution and use that value in a macro statement that has already run through the macro processor.
Try expressing your problem in terms of data step code only. Then we can see what you're actually trying to do and help you from there 🙂
%do %until (("&done2" = "yes") or (&m>3));
nodup_supd_&m.d= supd_&m.d;
if ntdc_&m.d=1 then call symput('done2','yes');
%let m = %eval(&m+1);
%end;
It is not clear what you are trying to do.
I guess you want:
%macro drug_ntdc(type,num,op);
data ntdc_&type.&Num.d_wide1;
set ntdc_&type.&Num.d_wide ;
array ns {4} nodup_supd_0d nodup_supd_1d nodup_supd_2d nodup_supd_3d;
array sp {4} supd_0d supd_1d supd_2d supd_3d;
done2 = "no";
m=0;
do until (done2 = "yes" or m>3);
ns(m)= sp(m);
if ns(m) = 1 then done2='yes';
m = m+1);
end;
run;
%mend;
%drug_ntdc(opioid,3,op=1);
But this is equal to:
%macro drug_ntdc(type,num,op);
data ntdc_&type.&Num.d_wide1;
set ntdc_&type.&Num.d_wide ;
nodup_supd_0d = supd_0d;
nodup_supd_1d = supd_1d;
run;
%mend;
%drug_ntdc(opioid,3,op=1);
Is that what you want ?
Thanks for your response. I am sorry I didn't express my problem clearly. Here I tried to express in a simple way. Whether the value of supd_0d will be copied to nodup_supd_0d depends on if ntdc_0d equals to 0; once ntdc_xd changes to 1, the process of coping will stop and leave the rest variables called nodup_supd_xd blank. I would like to use macro since I have to repeat this process for several variables, not only supd_xd and nodup_supd_xd
supd_0d | supd_1d | supd_2d | nodup_supd_0d | nodup_supd_1d | nodup_supd_2d | ntdc_0d | ntdc_1d | ntdc_2d |
1 | 2 | 3 | 1 | . | . | 0 | 1 | 0 |
1 | 2 | 3 | 1 | 2 | . | 0 | 0 | 1 |
data wide1;
set wide;
array ns{4} nodup_supd_0d nodup_supd_1d nodup_supd_2d nodup_supd_3d;
array sp {4} supd_0d supd_1d supd_2d supd_3d;
array ntdc {4} ntdc_0d ntdc_1d ntdc_2d ntdc_3d;
done2 = "no";
m=0;
do until (done2 = "yes" or m>3);
ns(m)= sp(m);
if ntdc(m) = 1 then done2='yes';
m = m+1;
end;
run;
You don't have to manually increment the loop counter, let the DO loop do that.
do m=1 to dim(sp) until (ntdc[m] = 1);
ns[m]= sp[m];
end;
Alternative loop would be:
do m=0 to dim(ns);
if ntdc(m) ne 1 then ns(m) = sp(m);
else leave;
end;;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Save $200 when you sign up by March 14!
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.