Advanced ODS: Controlling precisely what output is displayed

0

A customer asks in SAS Communities if it is possible to call PROC SGPLOT and put one title at the top of the page and a different title in the graph. The answer is "yes!" and there are multiple ways to do it. I decided to write a blog on this topic because it provides me with an opportunity to discuss several advanced features of ODS that you can use for more than controlling titles. Before showing some of the answers, let's review how titles work in SAS and ODS Graphics. The following steps create a PDF file that has three pages.

ods pdf file='b.pdf';
title 'Class Data Set';
 
proc print data=sashelp.class; run;
 
proc sgplot data=sashelp.class;
   title2 'Weight and Height by Sex';
   reg y=weight x=height / group=sex;
run;
 
title2;
proc means data=sashelp.class; run;
ods pdf close;

File b.pdf.

The first page contains the title "Class Data Set", the page number on the same line as the title, and the PROC PRINT output. The second page contains only a page number and a graph. No title is displayed on the line that contains the page number. The two titles both appear inside the graph. The third page contains the title "Class Data Set," the page number on the same line as the title, and the PROC MEANS output (including the PROCTITLE "The Means Procedure"). The TITLE2 statement cleared the second title. Had there been a third or subsequent title, it would have cleared them as well.

What if you wanted a consistent title line to appear in all pages of the report and on the same line as the page number? If you do not want a title in your graph, you can specify the NOGTITLE option in your ODS destination statement. However, that will not work in any of these examples, because we are trying to display titles in both the title line of the page and in the graph. While I do not recommend this solution because it requires you to write a template, you can use the GTL and PROC SGRENDER to make the graph instead of using PROC SGPLOT.

ods pdf file='b2.pdf';
title 'Class Data Set';
 
proc print data=sashelp.class; run;
 
proc sort data=sashelp.class out=class; by sex; run;
 
proc template;
   define statgraph ClassReg;
      begingraph;
         EntryTitle "Weight and Height by Sex";
         layout overlay;
            scatterplot    x=height y=weight / group=sex;
            regressionplot x=height y=weight / group=sex name="reg";
            discretelegend "reg" / title="Sex";
         endlayout;
      endgraph;
   end;
run;
 
proc sgrender data=class template=classreg;
run;
 
proc means data=sashelp.class; run;
ods pdf close;

File b2.pdf.

The TITLE statement sets the title for all three pages. The ENTRYTITLE statement in the template sets the title for the graph. You do not have to write the template yourself, though. You can use PROC SGPLOT to write a template, include it, and then use PROC SGRENDER to make the graph.

ods pdf file='b3.pdf';
title 'Class Data Set';
 
proc print data=sashelp.class; run;
 
ods exclude sgplot;
proc sgplot data=sashelp.class tmplout='t';
   title 'Weight and Height by Sex';
   reg y=weight x=height / group=sex;
run;
 
%inc 't';
 
title 'Class Data Set';
proc sgrender data=sashelp.class template=sgplot;
run;
 
proc means data=sashelp.class; run;
ods pdf close;

File b3.pdf.

The first TITLE statement sets the title for the PROC PRINT step. The TITLE statement in the PROC SGPLOT step sets the ENTRYTITLE for the template. The graph produced by PROC SGPLOT is excluded. The third TITLE statement sets the title for the second page (the graph) and the third page (the PROC MEANS output). The template that PROC SGPLOT wrote is more complicated than the one that I wrote above. You can run the PROC SGPLOT step that has the TMPLOUT= option and examine the data set "t" to see it. It uses a discrete attribute map and the SORT function to manufacture the group variable from the Sex variable and obviates the need for the separate PROC SORT.

You can also approach this by using the ODS LAYOUT. The ODS LAYOUT enables you to put multiple graphs, tables, and text on a page and configure the output in any way that you want.

ods pdf file='b4.pdf';
ods layout gridded;
ods region;
title 'Class Data Set';
 
ods region;
proc print data=sashelp.class; run;
 
ods startpage = now;
ods region;
title 'Class Data Set';
 
ods region;
proc sgplot data=sashelp.class;
   title 'Weight and Height by Sex';
   reg y=weight x=height / group=sex;
run;
 
ods startpage = now;
ods region;
title 'Class Data Set';
 
ods region;
proc means data=sashelp.class; run;
ods layout end;
ods pdf close;

File b4.pdf.

The ODS LAYOUT GRIDDED statement begins the definition of the output format. There is an ODS REGION statement in front of each component of the output. The ODS STARTPAGE = NOW statement starts a new page. The ODS LAYOUT END statement ends the ODS LAYOUT.

This next example also uses the ODS LAYOUT, but this time it displays all of the output in a single page.

title;
options nonumber;
ods noproctitle;
ods pdf file='b5.pdf';
ods layout start;
title 'Class Data Set';
 
ods region y=0.1in x=0.1in height=4.2in;
ods graphics / height=4in;
proc sgplot data=sashelp.class;
   title 'Weight and Height by Sex';
   reg y=weight x=height / group=sex;
run;
 
ods region y=4.5in x=.25in width=4in height=6in;
proc print data=sashelp.class; run;
 
ods region y=4.5in x=3.75in  width=4in height=6in;
proc means data=sashelp.class; run;
ods layout end;
ods pdf close;

File b5.pdf.

The ODS LAYOUT START statement begins the definition of the output format. The TITLE statement has its usual function. Three LAYOUT REGION statements specify different regions of the page for each piece of output. Options include the horizontal and vertical starting position of each region along with the height and width. There are many other things that you can do using the ODS LAYOUT. For more information, see the Output Delivery System User's Guide.

Here is another way. This one produces slightly different output. There is no page number on any page or PROCTITLE before the PROC MEANS output.

proc template;
   define style mystyle;
   parent=styles.pearl;
   class usertext from systemtitle / just=c;
   end;
run;
 
title;
options nonumber;
ods pdf file='b6.pdf' style=mystyle;
ods text='Class Data Set';
 
proc print data=sashelp.class; run;
 
ods pdf startpage=now;
ods text='Class Data Set';
 
ods pdf startpage=no;
proc sgplot data=sashelp.class;
   title 'Weight and Height by Sex';
   reg y=weight x=height / group=sex;
run;
title;
 
ods pdf startpage=now;
ods text='Class Data Set';
ods noproctitle;
proc means data=sashelp.class; run;
ods pdf close;

File b6.pdf.

This example begins by creating a style that will display the text specified in an ODS TEXT= statement as a system title. This style is specified in the ODS PDF statement. The OPTIONS NONUMBER statement suppresses the page numbers. The ODS PDF STARTPAGE= statements start a new page (NOW) or suppress a page break (NO). The ODS NOPROCTITLE statement suppresses PROCTITLEs. For more information on this example, see the ODS TEXT= Statement.

This last example uses the ODS document. It also relies on suppressing the page numbers.

ods document name=MyDoc (write);
title 'Class Data Set';
 
proc print data=sashelp.class; run;
 
proc sgplot data=sashelp.class;
   title 'Weight and Height by Sex';
   reg y=weight x=height / group=sex;
run;
 
title 'Class Data Set';
proc means data=sashelp.class; run;
ods document close;
 
proc document name=MyDoc;
   list / levels=all;
quit;
 
options nonumber;
ods pdf file='b7.pdf';
proc document name=MyDoc;
   replay \Print#1\Print#1;
   obstitle \SGPlot#1\SGPlot#1 'Class Data Set';
   replay \SGPlot#1\SGPlot#1;
   replay \Means#1\Summary#1;
quit;
ods pdf close;

File b7.pdf.

The tabular and graphical results are captured in an ODS document. PROC DOCUMENT and the LIST statement are not required to make the output, but they show you the path that you need to specify to replay each object. The REPLAY statements display each table and graph. The OBSTITLE statement assigns a subtitle to the graph. Specifying OBTITLE (title as opposed to subtitle) does not work.

These are the ways that I could think of to approach this question. There might be more. There are certainly other variations on the LAYOUT OVERLAY approach that will also work. In summary, ODS gives you incredible flexibility in how it displays output. I show you so many examples because each can be generalized to do other things. For more information about the statements shown here, see the User's Guide, Global Forum papers (such as An Insider's Guide to ODS LAYOUT Using SAS 9.4 and Have It Your Way: Rearrange and Replay Your Output with ODS DOCUMENT), and other blogs (such as Do you need multiple graphs on a page?, Arrange matrices and graphs in a gridded layout, and Using the ODS statement to add layers in your ODS sandwich).

Share

About Author

Warren F. Kuhfeld

Distinguished Research Statistician

Warren F. Kuhfeld is a distinguished research statistician developer in SAS/STAT R&D. He received his PhD in psychometrics from UNC Chapel Hill in 1985 and joined SAS in 1987. He has used SAS since 1979 and has developed SAS procedures since 1984. Warren wrote the SAS/STAT documentation chapters "Using the Output Delivery System," "Statistical Graphics Using ODS," "ODS Graphics Template Modification," and "Customizing the Kaplan-Meier Survival Plot." He also wrote the free web books Basic ODS Graphics Examples and Advanced ODS Graphics Examples.

Related Posts

Leave A Reply

Back to Top