Hi,
I have a dataset with dates ranging from Feb2018 to Feb2019. I need to exclude the data corresponding to each month and perform some procedures for the data of the remaining months (i.e., I need to do this 12 times). For example my code for running a logistic regression excluding the data of Nov2018 is as follows. Anybody can help to automate this process (instead of manually changing dates in the "where"
proc logistic data=have (where=(Date_r >= '01Dec2018'd | Date_r <'1Nov2018'd));
model High_level (event='1')= Score_r Length_r;
run;
statement)? Thanks!
A slightly different approach, using your original code with minimal changes, to show creation of macro variables from parameters:
%macro logit(year,month);
%let from = %sysfunc(mdy(&month.,1,&year.));
%let to = %sysfunc(intnx(month,&from,1,b));
proc logistic data=have (where=(Date_r >= &to. | Date_r < &from.));
model High_level (event='1')= Score_r Length_r;
run;
%mend;
data _null_;
date = '01feb2018'd;
do until (date > '01feb2019'd);
call execute(cats('%nrstr(%logit(',year(date),',',month(date),'))'));
date = intnx('month',date,1,'b');
end;
run;
The %nrstr in the call execute is necessary to prevent premature resolution of macro statements within the macro.
UCLA introductory tutorial on macro variables and macros
https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/
Tutorial on converting a working program to a macro
This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md
The UCLA has some tutorials on macros that can help you with this.
Note that you can simplify your WHERE clause to
where put(date_r, yymmn6.) NE "201812";
where month(date) ne 12 and year(date) ne 2018;
Examples of common macro usage - including how to loop through dates in a macro.
https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...
*create macro;
%macro runMyCode(myMonth = );
title "Regression for Month= &myMonth";
proc logistic data=have (where=put(date_r, yymmn6.) ne "&myMonth.";
model High_level (event='1')= Score_r Length_r;
run;
title;
%mend;
data demo;
*set start date;
start_date = '01Jan2018'd;
*loop through 12 months of the year;
*change here to include longer periods;
do i=1 to 12;
*find date of the month;
date = intnx('month', start_date, i-1, 'b');
*format to correct format for macro;
macro_param = put(date, yymmn6.);
*create macro call;
str = catt('%runMyCode(myMonth=', macro_param, ');');
*execute macro, currently commented out;
*call execute(str);
end;
run;
Untested but should give you a good idea of what you need, if it doesn't work, the links above have everything you need to build your own or debug it.
@Bright wrote:
Hi,
I have a dataset with dates ranging from Feb2018 to Feb2019. I need to exclude the data corresponding to each month and perform some procedures for the data of the remaining months (i.e., I need to do this 12 times). For example my code for running a logistic regression excluding the data of Nov2018 is as follows. Anybody can help to automate this process (instead of manually changing dates in the "where"
proc logistic data=have (where=(Date_r >= '01Dec2018'd | Date_r <'1Nov2018'd)); model High_level (event='1')= Score_r Length_r; run;
statement)? Thanks!
A slightly different approach, using your original code with minimal changes, to show creation of macro variables from parameters:
%macro logit(year,month);
%let from = %sysfunc(mdy(&month.,1,&year.));
%let to = %sysfunc(intnx(month,&from,1,b));
proc logistic data=have (where=(Date_r >= &to. | Date_r < &from.));
model High_level (event='1')= Score_r Length_r;
run;
%mend;
data _null_;
date = '01feb2018'd;
do until (date > '01feb2019'd);
call execute(cats('%nrstr(%logit(',year(date),',',month(date),'))'));
date = intnx('month',date,1,'b');
end;
run;
The %nrstr in the call execute is necessary to prevent premature resolution of macro statements within the macro.
The first one is built from the supplied month and year, with day 1. The second is the beginning of the next month.
Since those dates are used in code, they need not be formatted.
%macro runit(month=,year=);
proc logistic data=have (where=(month(Date_r) = &month. and year(Date_r) =&year.));
model High_level (event='1')= Score_r Length_r;
run;
%mend runit;
proc sql noprint;
create table have1 as
select distinct month(Date_r) as m, year(Date_r) as y from have;
quit;
data _null_;
set have1;
call execute('%runit(month='||put(m,8.)||',year='||put(y,8.)||');');
run;
Please let us know if it worked for you.
Thanks for the reply. I guess there is a mismatch between dates. I need to exclude one month and run the regression on the data of remaining months. So I guess I need to change this line of your code as follows, correct?
proc logistic data=have (where=(month(Date_r) ne &month. and year(Date_r) ne &year.));
Thanks!
No, The exclusion must happen in the calling system. See comments bellow.
%macro runit(month=,year=);
proc logistic data=have (where=(month(Date_r) = &month. and year(Date_r) =&year.));
model High_level (event='1')= Score_r Length_r;
run;
%mend runit;
proc sql noprint;
create table have1 as
select distinct month(Date_r) as m, year(Date_r) as y from have
where month(Date_r) ne '2' and year(Date_r) ne '2019';
/*Please put your choice of month and year to exclude in this where block instead*/
quit;
data _null_;
set have1;
call execute('%runit(month='||put(m,8.)||',year='||put(y,8.)||');');
run;
Please let us know if it worked for you.
The OP wants to run the procedure for 11 months at a time, your code can only run it for 1 month at a time.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.