BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Bright
Obsidian | Level 7

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!

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

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.

View solution in original post

8 REPLIES 8
Reeza
Super User

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!


 

Kurt_Bremser
Super User

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.

Bright
Obsidian | Level 7
Thanks for the reply. Could you please explain the dates you used in %let.
Kurt_Bremser
Super User

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.

Satish_Parida
Lapis Lazuli | Level 10

 

 

%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.

Bright
Obsidian | Level 7

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!

Satish_Parida
Lapis Lazuli | Level 10

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.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

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.

Discussion stats
  • 8 replies
  • 601 views
  • 4 likes
  • 4 in conversation