Macro DO Loops Across 2 Digit Years

From sasCommunity
Jump to: navigation, search

If you have ever had to work with two digit years (98 instead of 1998) you know that they can be problematic. This is especially true when you must iterate using the two digit years over a series of years in a macro %DO loop. For the simplified examples included here, assume that you need to read a series of data set named using a two digit year. Something like MYDATA.YEAR98.

The Problem

Consider the macro %ALLYR which is designed to concatenate a series of years worth of data. Adding a YEAR variable based on the source year of the data.

%macro allyr(start=11, stop=15);
data combine;
set
%do yr = &start %to &stop;
 mydata.year&yr(in=in&yr)
%end;
;
year=2000
%do yr = &start %to &stop;
 + (in&yr*&yr)
%end;
;
run;
%mend allyr;

This macro will only work for years > 2000 and if the data sets are named YEAR05 (with a leading 0), only for years >2009. How can we work with these two digit years and account for leading zeros and allow the program to cross the century boundary?

A Solution

Four digit years solve a number of the problems. So let's look at how we can convert from two to four digit years and from four digit years back to two digit years.

%macro allyr(start=04,stop=05);
   %local first last year yr;
   %* Use the current setting of the YEARCUTOFF option;
   %* Build 4 digit start and end years;
   %let first = %sysfunc(year(%sysfunc(mdy(1,1,&start))));
   %let last  = %sysfunc(year(%sysfunc(mdy(1,1,&stop))));
 
data combine;
   set
   %do year = &first %to &last;
      %* Create a two digit year;
      %let yr = %sysfunc(mod(&year,100));
      %if %length(&yr)=1 %then %let yr=0&yr;
/*      %* Test values;*/
/*      %put &=first &=last &=year &=yr;*/
     mydata.year&yr(in=in&year)
    %end;
    ;
year=0
   %do year = &first %to &last;
        + (in&yr*&year)
   %end;
    ;
run;
%mend allyr;
 
%allyr(start=98, stop=11)

To create a four digit year from the two digit year it is easiest to first create a SAS date. The MDY function is used to build a SAS date from the two digit year. This is followed by the YEAR function to return the four digit year. By using the MDY function the current setting of the YEARCUTOFF function will be used. (important because the default setting for this option changes between SAS9.3 and SAS9.4)

A two digit year is then built from the four digit year (&YEAR) using the MOD function.

Two digit years between 0 and 9 will be presented without the leading zero. When the leading zero is needed, the single digit is detected using the %LENGTH function, and then it is pre-appended.

The %DO loop increments over the four digit years which eliminates the century boundary problems associated with a two digit year.