Solved
Contributor
Posts: 57

# Do Loops that start from the same location

Dear Community Members,

I have a variable called cday, which goes from -252 to 252, denoting the number of trading days in a year. I need to choose a window such that it will increase by certain intervals, but will always start from day 0. In particular, I want to choose the following 6 intervals (windows):

0-5

0-21

0-42

0-63

0-126

0-252

Is it possible to have a %do statement where the increments are above the intervals? (something like %do i=0-5 %to 0-252) I thank in advance for your time and help,

Best,

Accepted Solutions
Solution
‎04-05-2013 08:10 AM
Regular Contributor
Posts: 227

## Re: Do Loops that start from the same location

Your problem is a list processing example:

how to split a data set into groups

text=%nrstr(...)

http://www.sascommunity.org/wiki/Macro_CallText

this is the data step you want

Data G_5

G_21

G_42

G_63

G_126

G_252;

do until (EndoFile);

set Library.TheData

end = EndoFile;

if 0 <= cday <= 5   then output g_5;

if 0 <= cday <= 21  then output g_21 ;

if 0 <= cday <= 42  then output g_42 ;

if 0 <= cday <= 63  then output g_63 ;

if 0 <= cday <= 126 then output g_126;

if 0 <= cday <= 252 then output g_252;

end;

stop;

run;

This is my solution.

%Macro Do_(text=%nrstr(g_&Item));

%let list = 21

42

63

126

252;

%local I;

%do I = 1 %to %sysfunc(countc(&List,%str()))+1;

%let item = %scan(&List,I);

%unquote(&Text)

%end;

%mend;

DATA %do_();

do until (EndoFile);

set Library.TheData

end = EndoFile;

%do_(text=%nrstr(if 0 <= cday <= &item   then output g_&item

end;

stop;

run;

This solution is from the HOW:

http://www.sascommunity.org/wiki/List_Processing_Basics_Creating_and_Using_Lists_of_Macro_Variables

Ron Fehd  loops maven

All Replies
Regular Contributor
Posts: 227

## Re: Do Loops that start from the same location

The A to your Q is no.

http://www.sascommunity.org/wiki/Macro_Loops_with_Dates

but that does not read like what you are doing.

my solution is one macro:

%macro do_loop

(start=0

,stop=5

,step=1

);

%local I;

%do I = &Start %to &Stop %by &Step;

%*what goes here?

%end;

%mend;

*called this way:

%do_loop(stop=5)

%do_loop(stop=21)

%do_loop(stop=42)

%*...;

%do_loop(stop=252)

Are you generating reports for these intervals?

Proc Print data = Library.MyData

(where = (0<= Cday <=5 ));

or choosing subsets based on cday?

DATA;

*...;

if 0<= Cday <=5 then ...;

Ron Fehd  loops maven

Contributor
Posts: 57

## Re: Do Loops that start from the same location

Thank you for your quick response. I am interested in choosing a subset based on cday such that the first subset will include observations with cday between 0 and 21, the second subset will include observations with cday between 0 and 42, etc. Let's day that my main dataset is fullrets. I need to convert the following steps into a macro;

data subset1; set fullrets; where 0 le cday le 21;

data subset2; set fullrets; where 0 le cday le 42;

.

.

.

data subset6; set fullrets; where 0 le cday le 252;

I am now going over the code you posted. I really appreciated your help.

Regular Contributor
Posts: 195

## Re: Do Loops that start from the same location

Hello ,

Try the following SAS Code...

data test;

do i = -252 to 252;

if i = 0 then do;

do cday = i, 5, 21, 42, 63, 126, 252;

output;

end;

end;

output;

end;

run;

proc sort data = test(drop = i where = (cday NE .)) nodupkey;

by cday;

run;

proc sql noprint;

select cday into :list separated by ' '

from test;

quit;

%macro subset;

%do i = 1 %to %eval(%sysfunc(countw(&list.)) - 1);

data subset_&i.;

set test;

if %scan(&list.,1) LE cday %scan(&list.,%eval(&i+1));

run;

%end;

%mend;

%subset;

Hope this code meet your requirement...

Regards,

Urvish

Solution
‎04-05-2013 08:10 AM
Regular Contributor
Posts: 227

## Re: Do Loops that start from the same location

Your problem is a list processing example:

how to split a data set into groups

text=%nrstr(...)

http://www.sascommunity.org/wiki/Macro_CallText

this is the data step you want

Data G_5

G_21

G_42

G_63

G_126

G_252;

do until (EndoFile);

set Library.TheData

end = EndoFile;

if 0 <= cday <= 5   then output g_5;

if 0 <= cday <= 21  then output g_21 ;

if 0 <= cday <= 42  then output g_42 ;

if 0 <= cday <= 63  then output g_63 ;

if 0 <= cday <= 126 then output g_126;

if 0 <= cday <= 252 then output g_252;

end;

stop;

run;

This is my solution.

%Macro Do_(text=%nrstr(g_&Item));

%let list = 21

42

63

126

252;

%local I;

%do I = 1 %to %sysfunc(countc(&List,%str()))+1;

%let item = %scan(&List,I);

%unquote(&Text)

%end;

%mend;

DATA %do_();

do until (EndoFile);

set Library.TheData

end = EndoFile;

%do_(text=%nrstr(if 0 <= cday <= &item   then output g_&item

end;

stop;

run;

This solution is from the HOW:

http://www.sascommunity.org/wiki/List_Processing_Basics_Creating_and_Using_Lists_of_Macro_Variables

Ron Fehd  loops maven

Contributor
Posts: 57