Search code examples
sassas-macroodssgplot

Organize ODS output by an ID


I need to create 3 graphs for each facility and output these onto 1 page. I have 600 facilities to do this for so I will have a 600 page document. I have created my graphs using the code below. If I specify a "where ID=X" in the proc sgplot statement, it outputs everything fine, but only for facility X. If I don't, it prints Graph 1 for every facility before going to the next graph. I'm guessing I need a macro... does anyone have any advice?

OPTIONS orientation=vertical nodate;

ods rtf file="C:\Users\filename.rtf" STYLE=Styles.rtf;
ods listing close;
ods noproctitle  ;
ODS ESCAPECHAR='^';
title ; footnote;

*First graph;

ods graphics on / height=2.7 in width=8in;
ods rtf startpage=NOW;
ods rtf text= "^{style[fontweight=bold fontsize=11pt textalign=c] Employees}";
ods graphics/noborder;

 
proc sort data=clean4; by ID warehouse county; run;
proc sgplot data=clean4;
by pfi name;
     title2 "ID= #byval(ID) ";

      title3 "Name: #byval(warehouse) ";

      title4 "County: #byval(county) ";

series x=date y=emp  /  markers markerattrs=(symbol=CircleFilled color=blue) lineattrs=(color=blue thickness=2 pattern=1 ) legendlabel='Number of Employees' dataskin=pressed; 
   yaxis  label='Count' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) offsetmin=0  integer;
   xaxis label='Date'  valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold)  ;
      option NOBYLINE;

run;

*Second graph;

ods graphics on / height=2.7 in width=8in;
ods rtf startpage=NO;
ods rtf text=' ';
ods rtf text= "^{style[fontweight=bold fontsize=12pt textalign=c] Hats used daily}";
ods graphics/noborder;

proc sort data=clean4; by ID; run;
proc sgplot data=clean4;
 by ID;
title2; title3;

series x=date y=hats  /  markers markerattrs=(symbol=CircleFilled color=red)
      lineattrs=(color=red thickness=2 pattern=1 ) legendlabel='Number of hats used' dataskin=pressed; 
      yaxis  label='Count' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) fitpolicy=thin 
      offsetmin=0 integer;
   xaxis label='Date'  valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold)  ;

run;


*Third graph;

ods graphics on / height=2.7 in width=8in;
ods rtf startpage=NO;
ods rtf text=' ';
ods rtf text= "^{style[fontweight=bold fontsize=11pt textalign=c] LOESS}";
ods graphics/noborder;


proc sort data=clean4; by ID; run;
proc sgplot data=clean4;
      by ID;
      loess y=var1 x=date/ legendlabel="LOESS" lineattrs=(color=blue)
            FILLEDOUTLINEDMARKERS MARKERFILLATTRS=(color=black);
      yaxis  label='LOESS Plot' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) offsetmin=0;

    xaxis label='Date'  valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) THRESHOLDMIN=0 
     THRESHOLDMAX=0  ;
 option NOBYLINE;

run;

ods rtf close;
ods listing ;

Solution

  • Because you are using the same data set clean4 for producing output in three different ways for each ID you need to change only a minimal amount of code when you convert to macro (macroize) the existing code.

    Two steps

    • macroize existing code to operate on a single 'ID' value (the do'er)
    • run the macro for each ID (the run'er)

    Do'er

    %macro doReport(ID=);
      * move the sort to the top;
      * only need to sort the data once (for your situation);
    
      proc sort data=clean4 out=clean4_oneID; 
        by ID warehouse county; 
        where ID = "&ID";
      run;
    
      * Place all the graphing code here;
      * change all the 'clean4' data set references to 'clean4_oneID';
    
    %mend;
    

    Run'er

    * Place ODS RTF and settings here;
    
    * obtain list of each id;
    
    proc sort nodupkey data=clean4 out=id_list; by id; run;
    
    * 'stackingly' invoke macro for each id;
    
    data _null_;
      set id_list;
      call execute (cats('%nrstr(%doReport(ID=',id,'))');
    run;
    
    * stacked execute code will now be submitted by SAS supervisor;
    
    * close the RTF here;