Do Looping within macro

Accepted Solution Solved
Reply
Contributor
Posts: 28
Accepted Solution

Do Looping within macro

Hi -

 

I want to write a do loop within a macro so that I don't need to type each number in for 26 times for the start_time and stop_time variables (the data set has start_time1-start_time26, stop_time1-stop_time26). Right now my code looks like this:

%macro change(spot);
data want;
   retain participantid inter000-inter009 inter0010-inter0023 start_time&spot. stop_time&spot.;
   set data;
run;
%mend(change);
%change(1)
%change(2)
%change(3)
%change(4)
%change(5)
%change(6)
%change(7)
%change(8)
%change(9)
%change(10)
%change(11)
%change(12)
%change(13)
%change(14)
%change(15)
%change(16)
%change(17)
%change(18)
%change(19)
%change(20)
%change(21)
%change(22)
%change(23)
%change(24)
%change(25)
%change(26)

This works but does not seem to be efficient, I tried do loop but did not work:

%macro change();
   %do n = 1 %to 26;
   data want;
   retain participantid inter000-inter009 inter0010-inter0023 start_time&n stop_time&n;
   set data;
   %end;
   run;
%mend change;

Any ideas?

 

Thanks!!


Accepted Solutions
Solution
4 weeks ago
Respected Advisor
Posts: 4,992

Re: Do Looping within macro

[ Edited ]

Idea #1:  Do nothing.  If these variables are already part of your SAS data set, they are automatically retained.  However, if they are going to be new variables created by additional programming statements yet to be added ...

 

Idea #2:  RETAIN supports variable lists.  This statement is perfectly acceptable:

 

retain stop_time1-stop_time26;

 

 

Based on your later clarification, perhaps this is what you are looking for;

 

%macro change;

 

%local n;

 

data want;

retain participantid inter000-inter009 inter00010-inter0013

   %do n=1 %to 26;

      start_time&n stop_time&n

   %end;

   ;

set have;

run;

 

%mend change;

 

%change

View solution in original post


All Replies
Grand Advisor
Posts: 10,223

Re: Do Looping within macro

[ Edited ]

Since you do not change the name of the data set the only Data Want you have is the one from the last run of the loop.

Try

%macro change();
   %do n = 1 %to 26;
   data want&n.;
   retain participantid inter000-inter009 inter0010-inter0023 start_time&n stop_time&n;
   set data;

   run;
   %end;
%mend change;

HOWEVER you likely have another issue if the Retained variable exists in your data set DATA the incoming value from the Set statement will overwrite the "retained" version at each execution of the SET. To actually retain the value of an existing variable you would need to create a new variable and then assign the value from the data set as needed. I hope you were just trying to shorten the code since you didn't show any any use of any of the retained variables.

 

By any chance are you attempting to keep variables? Retain is used to retain the value of a variable across interations of a data step.

KEEP is the indicate which variables are in the resulting output set (or kept when bringing data in from another set)

 

Super User
Super User
Posts: 6,364

Re: Do Looping within macro

Neither of your methods make much sense.  What are you actually trying to do?

Do you want to convert your 26 variables into 26 rows?

data want ;
  set have ;
  array s start_time1-start_time26;
  array e stop_time1-stop_time26;
  do timepoint=1 to dim(s);
    start_time=s(timepoint);
    stop_time=e(timepoint);
    output;
  end;
 drop start_time1-start_time26 stop_time1-stop_time26;
run;

You will probably also need to add a FORMAT statement to format the new variables START_TIME and STOP_TIME.

 

Contributor
Posts: 28

Re: Do Looping within macro

Sorry my question was not clear. I just want to change the sequence of the variables so that it will goes from start_time1 to start_time26 and from stop_time1 to stop_time26.

 

 

Solution
4 weeks ago
Respected Advisor
Posts: 4,992

Re: Do Looping within macro

[ Edited ]

Idea #1:  Do nothing.  If these variables are already part of your SAS data set, they are automatically retained.  However, if they are going to be new variables created by additional programming statements yet to be added ...

 

Idea #2:  RETAIN supports variable lists.  This statement is perfectly acceptable:

 

retain stop_time1-stop_time26;

 

 

Based on your later clarification, perhaps this is what you are looking for;

 

%macro change;

 

%local n;

 

data want;

retain participantid inter000-inter009 inter00010-inter0013

   %do n=1 %to 26;

      start_time&n stop_time&n

   %end;

   ;

set have;

run;

 

%mend change;

 

%change

Super User
Super User
Posts: 6,364

Re: Do Looping within macro

If you use variable lists you can have all of the start variables followed by all of the stop variables.

data want ;
  retain start1-start26 stop1-stop26;
  set have;
run;

You would rather have the start/stop variables in pairs then you could use a macro loop to generate the names.  So you want to put the %DO loop in the middle of the RETAIN statement, so make sure not to include and semi-colons in the SAS code that the %DO loop generates.

%macro set_order;
%local i;
data want ;
  retain
%do i=1 %to 26 ;
   start&i stop&i
%end;
  ;
  set have;
run;
%mend set_order;
%set_order;

You can add back the other variable lists either in the same RETAIN statement or another one.  You could make the 26 a parameter if it changes from run to run.

Esteemed Advisor
Posts: 6,685

Re: Do Looping within macro

Apart from what has already been said, I prefer to use a format statement (without any formats) to set the order of variables. That prevents any confusion caused by the original purpose of the retain statement.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 122 views
  • 4 likes
  • 5 in conversation