When you create PROC PRINT output using a BY statement it will create a table per BY-group in ODS as shown in the print example below.
When you create a table with FILE PRINT _ODS and PUT _ODS_ statements and are using a BY statement it does not split the output this way, rather all output is ending in one long table.
However I want to break the output per BY group to include some dynamic header lines. How can I create the same situation as illustrated for PROC PRINT output using FILE PRINT _ODS_ and PUT _ODS_?
Problem solved.
As already mentioned in response to Cynthia I planned to try to solve it with the DATA step ODSOUT object. This is still "pre-production in SAS 9.3 and it took some experimenting, but eventually it does exactly what I want.
You declare the ODSOUT object once, Then you start a table construction for each BY group and close the table at the end of the BY group. Cells can be formatted any way you like. This is how the output looks (some data fields covered for confidentiality reasons):
Hi:
I'm not exactly sure I understand what you mean when you say that you want to split the output and have some dynamic header lines. But I reworked an ODS DOCUMENT/PROC DOCUMENT example from a previous SGF paper to show how you could make completely different titles, footnotes, before notes, after notes, etc, for every BY group.
The FILE PRINT with ODS does not work with BY groups as the procedures work. This is what made me think of ODS DOCUMENT and PROC DOCUMENT. But this may not be at all what you want, depending on what you mean by "header" lines. But I thought it was worth showing as a possibility.
cynthia
title;
** make 3 BY groups;
proc sort data=sashelp.class out=class;
by age sex name;
where age in (12, 13, 14);
run;
ods document name=work.orig;
ods html file='c:\temp\classby.html';
proc print data=class;
by age;
pageby age;
var sex name height weight;
run;
ods html close;
ods document close;
ods listing;
proc document name=work.orig;
list /levels=all;
run;
quit;
*** Make a new Document store;
*** copy from the ORIG document store and create a different;
*** set of titles, footnotes, before-notes, etc;
*** on every page of output, based on AGE;
*** Then replay to PDF and HTML;
proc document name=work.mynewrep(write);
make age12;
make age13;
make age14;
run;
dir \age12;
copy \work.orig\Print#1\ByGroup1#1\Print#1 to ^;
run;
dir \age13;
copy \work.orig\Print#1\ByGroup2#1\Print#1 to ^;
run;
dir \age14;
copy \work.orig\Print#1\ByGroup3#1\Print#1 to ^;
run;
obtitle1 \age12#1\Print#1 'Twas brillig';
obstitle1 \age12#1\Print#1 'New SubTitle';
obbnote1 \age12#1\Print#1 'New Before-Notes';
obanote1 \age12#1\Print#1 'New After-Notes';
obfootn1 \age12#1\Print#1 'New Footnote';
run;
obtitle1 \age13#1\Print#1 'Beware the Jabberwock';
obstitle1 \age13#1\Print#1 'Another SubTitle';
obbnote1 \age13#1\Print#1 'Another Before-Notes';
obanote1 \age13#1\Print#1 'Another After-Notes';
obfootn1 \age13#1\Print#1 'Another Footnote';
run;
obtitle1 \age14#1\Print#1 'Frumious Bandersnatch';
obstitle1 \age14#1\Print#1 'Some SubTitle';
obbnote1 \age14#1\Print#1 'Some Before-Notes';
obanote1 \age14#1\Print#1 'Some After-Notes';
obfootn1 \age14#1\Print#1 'Some Footnote';
run;
quit;
** Double check the levels in the new document store;
ods listing;
proc document name=work.mynewrep;
list / levels=all;
run;
quit;
** Replay the new document store;
ods listing close;
ods html file="c:\temp\new_report.html";
ods pdf file="C:\Temp\new_report.pdf" ;
proc document name=mynewrep;
replay ;
run;
quit;
ods _all_ close;
ods listing;
title;
Hi Cynthia,
Thanks for the suggestion.
When you look closely to the PROC PRINT based output, you will notice that some columns show the same value for all five observations in the by group. I want to move that information to some lines that precede the regular PROC PRINT lines. Compare it to editing the BY-line with some extra lines and parameter values.
In the mean time I am looking into the DATA step ODS Object as an alternative, studying the paper by Daniel O'Connor. (313-2009). I'll publish the result here when I have it.
Problem solved.
As already mentioned in response to Cynthia I planned to try to solve it with the DATA step ODSOUT object. This is still "pre-production in SAS 9.3 and it took some experimenting, but eventually it does exactly what I want.
You declare the ODSOUT object once, Then you start a table construction for each BY group and close the table at the end of the BY group. Cells can be formatted any way you like. This is how the output looks (some data fields covered for confidentiality reasons):
good looking result Erik!
will you make a presentation of the solution, or post the code here?
peterC
I'm not going to present it at SGF. Call for papers is closed! But, yes, I will gladly prepare a more elaborate description of what I have done here on the forum.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.