BookmarkSubscribeRSS Feed
xuelingshu1047
Calcite | Level 5

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);

5 REPLIES 5
PeterClemmensen
Tourmaline | Level 20

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;
Shmuel
Garnet | Level 18

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 ?

 

xuelingshu1047
Calcite | Level 5

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_0dsupd_1dsupd_2dnodup_supd_0dnodup_supd_1dnodup_supd_2dntdc_0dntdc_1dntdc_2d
1231..010
12312.001

 

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;

  

Tom
Super User Tom
Super User

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;
Shmuel
Garnet | Level 18

Alternative loop would be:

do m=0 to dim(ns);
    if ntdc(m) ne 1 then ns(m) = sp(m);
    else leave;
end;;

sas-innovate-white.png

Register Today!

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!

Register now!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 833 views
  • 0 likes
  • 4 in conversation