I want to print many tables, arranged in 3 columns. To control the layout, I'm using ODS LAYOUT GRIDDED. The data for the tables are in one dataset, so I'm only calling PROC REPORT once with a BY statement. My issue is how to customize the title of each table. If I let SAS handle the titles for me, then everything's fine:
* Example 1: Let SAS handle the by-group titles, and it works great;
title;
ods layout gridded columns=3 advance=bygroup;
proc report data=sashelp.iris;
by species;
columns sepal:;
define sepal: / mean;
run;
ods layout end;
You see that each little table is correctly labeled with its by-group. The problem arises when I try to customize the titles using the #BYVAL syntax -- then only the first table (from the first by-group) is given a title:
* Example 2: Customize the by-group titles, and it fails;
title;
options nobyline;
ods layout gridded columns=3 advance=bygroup;
proc report data=sashelp.iris;
title 'Species: #byval1';
by species;
columns sepal:;
define sepal: / mean;
run;
ods layout end;
options byline;
How can I title all the tables? If you comment out the ODS LAYOUT lines from my "Example 2" code above, you'd see that my custom titles work fine. So the problem is specifically in the interaction between using ODS LAYOUT and #BYVAL.
Note that a very similar question has already been asked (https://communities.sas.com/t5/ODS-and-Base-Reporting/How-to-automatically-specify-a-different-title...), but in that case the solution was to change some settings in SAS Enterprise Guide. I'm using PC SAS 9.4 (TS1M8), so I think that solution is not relevant for me.
I also know there are workarounds, e.g., I could wrap PROC REPORT in a macro and then use CALL EXECUTE to call the macro for each by-group. Then I could customize the by-group titles without using #BYVAL:
* Example 3: Workaround using CALL EXECUTE -- gives me exactly what I want;
%macro print(species);
proc report data=sashelp.iris;
title "Species: &species";
where species = "&species";
columns sepal:;
define sepal: / mean;
run;
%mend;
title;
ods layout gridded columns=3 advance=table;
data _null_;
set sashelp.iris;
by species;
if first.species then call execute('%print(' || trim(species) || ')');
run;
ods layout end;
So the workaround works, and that's fine if necessary. But, is there a simpler way, i.e., a simple modification to my "Example 2" code?
Make the "title" part of the report.
* Example 2: Customize the by-group titles, and it fails;
title;
options nobyline;
ods layout gridded columns=3 advance=bygroup;
proc report data=sashelp.iris;
by species;
columns species sepal:;
define species / group noprint;
define sepal: / mean;
break after species / page;
compute before _page_ ;
line 'Species: ' species $20.;
endcomp;
run;
ods layout end;
options byline;
Make the "title" part of the report.
* Example 2: Customize the by-group titles, and it fails;
title;
options nobyline;
ods layout gridded columns=3 advance=bygroup;
proc report data=sashelp.iris;
by species;
columns species sepal:;
define species / group noprint;
define sepal: / mean;
break after species / page;
compute before _page_ ;
line 'Species: ' species $20.;
endcomp;
run;
ods layout end;
options byline;
Great idea, Tom! I like your solution and will accept it, though I still wonder (mostly out of curiosity) if there's a way to make this work using a TITLE statement.
I like the idea proposed by Tom, using 'compute before _page_'+'line ' to replace title statment,
to make line statement look more like title, try this one :
title;
options nobyline;
ods layout gridded columns=3 advance=bygroup;
proc report data=sashelp.iris nowd style(report)={frame=void}
style(column header)={borderwidth=2px bordertopwidth=2px};
by species;
columns species sepal:;
define species / group noprint;
define sepal: / mean;
break after species / page;
compute before _page_/style={bordercolor=cxFAFBFE borderwidth=2px fontweight=bold} ;
line 'Species: ' species $20.;
endcomp;
run;
ods layout end;
options byline;
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.