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.
Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.
Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.
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.