DATA Step, Macro, Functions and more

date series from start and end dates.

Reply
Frequent Contributor
Posts: 139

date series from start and end dates.

Hello

I want to create a date series from start and end dates.

I know how to do it and you can see the  code below.

I need to do further task and I don;t know how to do it.

I want to create a list of parameters called:  m0  m1  m2  m3......etc that will receive the values from table want_month.

So will we get

%put &m0.; /*1707*/

%put &m1.; /*1708*/

%put &m1.; /*1709*/

and so on.

 

%let start=1707;
%let end=1803;

data want_month;
ddate=&start_date.;
do while (ddate<=&end_date.);
output;
ddate=intnx('month', ddate, 1, 's');
end;
format ddate YYMMn4.;
run;
data want_month2;
Set want_month;
char_ddate=put(ddate,YYMMn4.);
Run;

Super User
Posts: 6,762

Re: date series from start and end dates.

OK taking you at your word that you know how to get the values to assign, you could add to your final DATA step:

 

data want_month2;

set want_month;

char_ddate = put(ddate, YYMMn4.);

call symputx('m' || put(mon,z2.), char_ddate);

mon + 1;

drop mon;

run;

 

This actually adds a zero so the parameter names are &m00 &m01 &m02 ... probably a good idea if you ever have a year's worth of data.  But if you don't like that and know that you will never need two-digit years, you can always use:

 

put(mon, 1.)

 

instead of 

 

put(mon, z2.)

Super User
Super User
Posts: 8,089

Re: date series from start and end dates.

[ Edited ]

You say you want "parameters" but you are not showing any code that is using these "parameters".

Instead you appear to want to create macro variables.  

How will the macro variables be used?  Why not just leave the value in a dataset?

 

If you want to make a numbered series it is probably easier to use an iterative DO loop instead of rolling your own loop.

do month = 1 to intck('month',start,end) ;
...
end;

 If you do need to make macro variables then use the CALL SYMPUTX() function.

do month = 1 to intck('month',start,end) ;
  call symputx(cats('M',month),put(intnx('month',start,i),yymmn4.));
end;
Frequent Contributor
Posts: 139

Re: date series from start and end dates.

Hello

Thanks for nice answers.

I found the best code that is working well.

 

%let start=1701;
%let end=1803;

%let date_start=%sysfunc(inputn(&start.,yymmn4.));
%let date_end=%sysfunc(inputn(&end.,yymmn4.));
%put &date_start.;
%put &date_end.;


Data want_month;
do j=0 to intck('month',&date_start.,&date_end.) ;
ddate=intnx('month', &date_start., j, 's');
char_ddate = put(ddate, YYMMn4.);
/*Var_Macro_name=compress('m'||put(J,2.));*/
Var_Macro_name='m'||strip(put(J,2.));
call symputx('m'||strip(put(J,2.)), char_ddate);
output;
end;
Run;

 

 

I have 2 other problems:

Problem1-

I want to calculate number of months between start and end and create a sas macro variable with this value.

One way to do it is working well.

PROC SQL Noprint;
select count(*) INTO:n
from want_month
;
QUIT;
%put &n.;

 

I have tried to do it in open code but didn't succeed

%let n=%sysfunc(intck('month',&date_start.,&date_end.));

/*Here we have a problem and we get in log a message:
WARNING: An argument to the function INTCK referenced
by the %SYSFUNC or %QSYSFUNC macro function is out of range.*/

 

 

Problem2-

I want to see sas macro varaibles values in log.

%put &m0;
%put &m1;
%put &m2;
%put &m3;
%put &m4;
%put &m14;
%PUT &&m&n..;
/*Here there is a problem and I don't get value of macro varaible m15*/
/*In log we can see :
WARNING: Apparent symbolic reference M not resolved.
&m 15.*/

 

Frequent Contributor
Posts: 139

Re: date series from start and end dates.

When I say that I need to careate SAS macro varaibles m0,m1,m2,m3...... there is a reason for that.

I have input SAS data sets that are created every month.

I need to use only tables for specific months that are defined by user.

For example:

%let start=1612;

%let end=1803;

It means that I will use following tables: tbl_1612,tbl_1701,tbl_1702....................tbl_1803.

 

%macro mmacro;
%DO j=1 %TO &n.;
PROC SQL;
create table tbl2_&&m&j..   as
select *
from tbl_&&m&j..

where   out_condition...........
;
QUIT;
%end;
%mend;
%mmacro;

Super User
Posts: 10,217

Re: date series from start and end dates.

You don't need macro variable lists for that. Instead wrap your code into a simple macro:

%macro do_once(period);

proc sql;
create table tbl2_&period. as
select *
from tbl_&period.
where out_condition...........
;
quit;

%mend;

and then call that macro from a do loop:

%let start=1612;
%let end=1803;

data _null_;
start_date = input("&start",yymmn4.);
end_date = input("&end",yymmn4.);
do until (start_date > end_date);
  call execute('%nrstr(%do_once(' !! put(start_date,yymmn4.) !! '));');
  start_date = intnx('month',start_date,1,'s');
end;
run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Ask a Question
Discussion stats
  • 5 replies
  • 85 views
  • 0 likes
  • 4 in conversation