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,
Your problem is a list processing example:
how to split a data set into groups
this page has a macro that illustrates the parameter
text=%nrstr(...)
http://www.sascommunity.org/wiki/Macro_CallText
Based on my reading of your Q and commentary
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
The A to your Q is no.
I have this page of looping through dates
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
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.
Hello finans_sas,
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
Your problem is a list processing example:
how to split a data set into groups
this page has a macro that illustrates the parameter
text=%nrstr(...)
http://www.sascommunity.org/wiki/Macro_CallText
Based on my reading of your Q and commentary
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
Thank you so much for helping me out with this problem.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.