Tuesday, September 10, 2013

Create a calendar using SAS PROC REPORT

This collection is from SAS website at http://support.sas.com/kb/50/099.html

The sample code below contains two sections. The top section creates a calendar that contains only the dates. The bottom section creates a calendar that includes text within date cells.

proc format;
   value dow
   1='Sun' 2='Mon' 3='Tue' 4='Wed' 5='Thu' 6='Fri' 7='Sat'
;
run;

%let year=2013;
%let beg_yr=%sysfunc(mdy(1,1,&year));
%let end_yr=%sysfunc(mdy(12,31,&year));


/************* Monthly calendar *************/

/* Create a data set containg one observation for each day in
  the time period specified above. */ 
data calendar_&year;
   format date mmddyy8. dow dow.;
   do date=&beg_yr to &end_yr;
      monthNum = month(date); 
      year = year(date); 
      dow = weekday(date);
      monthname = strip(upcase(put(date,monname9.)))||' '||put(year(date),z4.); 
      dom = input(put(date,day2.), 2.); 
      week = intnx('week',date,0,'e');
      output;
   end;
run;

/* Create a week number. */
data calendar_&year;
   set calendar_&year;
   by monthnum week;
   if first.monthnum then weeknum=0;
   if first.week then weeknum+1;
run;

options missing='' nobyline;
ods escapechar="^";

/* Create calendar output that contains only dates. */
title "&year";
proc report data=calendar_&year center nowd
     style(report)=[font=(Arial, 8pt)] 
     style(column)=[font=(Arial, 8pt)  cellheight=.5in cellwidth=.5in] 
     style(header)=[font=(Arial, 8pt) font_weight=bold]
     split='*';
   by monthnum;
   columns weeknum monthnum, (dow, dom);
   define weeknum / group order=internal noprint;
   define monthnum / across '' center order=data format=nlstrmon.;
   define dow / across order=data '' center preloadfmt format=dow.;
   define dom / analysis '' left;
run;


/************* Monthly calendar with holidays and notes *************/

/* Create a data set containg one observation for each day in
  the time period specified above. */ 
data calendar_&year(drop=fdoy);
   format date mmddyy8. dow dow.;
   do date=&beg_yr to &end_yr;
      monthnum = month(date); 
      year = year(date); 
      dow = weekday(date);
      monthname = strip(upcase(put(date,monname9.)))||' '||put(year(date),z4.); 
      dom = input(put(date,day2.), 2.); 
      week = intnx('week',date,0,'e');

      /* Get holidays */
      fdoy=mdy(1,1,&year);    
      length note $100; 
      note = ' '; 
                           
      if date = mdy(1,1,&year) 
         then note = "New Year's Day";

      if date = intnx('week.2',fdoy,(weekday(fdoy) ne 2)+2) 
         then note = "Martin Luther King Day";                                                                                
                                                                                                     
      else if date = intnx('week.2',intnx('month',fdoy,1),(weekday(intnx('month',fdoy,1)) ne 2)+2)
         then note = "President's Day"; 
                                                                                                   
      else if date = intnx('week.2',intnx('month',fdoy,4),(weekday(intnx('month',fdoy,4)) in (1,7))+4)
         then note = "Memorial Day";   

      else if date = mdy(7,4,&year) 
         then note = "Independence Day";

      else if date = intnx('week.2',intnx('month',fdoy,8),(weekday(intnx('month',fdoy,8)) ne 2))
         then note = "Labor Day"; 

      else if date = intnx('week.2',intnx('month',fdoy,9),(weekday(intnx('month',fdoy,9)) ne 2)+1)
         then note = "Columbus Day";    

      else if date = mdy(11,11,&year) 
         then note = "Veteran's Day";

      else if date = intnx('week.5',intnx('month',fdoy,10),(weekday(intnx('month',fdoy,10)) ne 5)+3) 
         then note = "Thanksgiving Day";

      else if date = mdy(12,25,&year) 
         then note = "Christmas Day";
      output;
   end;
run;

/* Create notes for personal dates. */
data mydates;
   length note $100;
   date = mdy(1,20,&year); note = "Mom's B-day"; output;
   date = mdy(5,25,&year); note = "^{style [foreground=blue] GRADUATION!}"; output;
   date = mdy(8,21,&year); note = "^{style [foreground=red] First Day of School}"; output;
run;

/* Merge the two date data sets together. */
data calendar_&year;
   merge calendar_&year mydates;
   by date;
   /* Append note text to the day of month value */
   length dom_notes $200;
   dom_notes = put(dom,8.) || "^n" || note;
run;

/* Create a week number. */
data calendar_&year;
   set calendar_&year;
   by monthnum week;
   if first.monthnum then weeknum=0;
   if first.week then weeknum+1;
run;

/* Transpose the data for the calendar with notes. */
proc transpose data=calendar_&year out=notes_calendar_&year;
   by monthnum monthname weeknum;
   id dow;
   var dom_notes;
run;

/* Create a calendar with dates and notes. */
title "#byval(monthnum) &year";
proc report data=notes_calendar_&year center nowd
     style(report)=[font=(Arial, 8pt)] 
     style(column)=[font=(Arial, 8pt) cellheight=1in cellwidth=1in] 
     style(header)=[font=(Arial, 8pt) font_weight=bold]
     split='*';
   by monthnum;
   format monthnum nlstrmon.;
   columns weeknum Sun Mon Tue Wed Thu Fri Sat;
   define weeknum / group order=internal noprint;
run;

No comments:

Post a Comment