I'm trying to print a set of reports which have many bivariate tables in PDF, with various column variables with different number of categories. I'd like the column categories to have a fixed width (say, 1cm wide for each statistic) and the row category (header) to fill the remainder of the space on the table.
I can get this to work in HTML, but not in PDF.
Details: I am doing this in 9.4 TS1M6, Windows, and generating an Accessible PDF.
Here's a sample of what works for HTML, but for PDF It doesn't work:
ods pdf startpage=never ;
proc tabulate data=sashelp.class;
class sex age;
keyword n/style={width=1cm};
keyword pctn/style={width=1cm};
tables sex, age*(n pctn)/style={width=7in};
run;
proc tabulate data=sashelp.class ;
class age sex;
keyword n/style={width=1cm};
keyword pctn/style={width=1cm};
tables age, sex*(n pctn)/style={width=7in} ;
run;
ods pdf close;
In HTML it properly fills the width with the row header, but in PDF it looks very messy and the row headers don't attempt to fill the available space. How can I get that to work with PDF? I've tried ROW=FLOAT, CLASSLEV width instead of keyword widths or in addition to, but neither seem to help the messiness in PDF. If I leave off the widths entirely except for the table width, it does produce a table that fills the space (more or less), but the row headers are too small and inconsistent.
Thanks!
Hi:
When I run your code both with and without the KEYWORD controls, the font size for the column headers is the same. The width is determined in PDF by a combination of the width you originally specified in the KEYWORD style override and the overall table width. In PDF, when you over-control the widths like this, PDF makes the cells the exact width you specify and then stretches the table to the table width. This leaves gaps of whitespace. Unlike HTML, which will "fill in" the table border lines, PDF does not do that.
However, you said that without the 1cm, the row headers were "too small" and inconsistent. This is not what I observe. I observe the SAME font size being used both with and without the 1 cm width for the keywords N and PCTN as shown below:
The bottom line is that in the top TABULATE, you have 13 columns in the report -- 1 row header and 12 columns. In the lower TABULATE you have 5 columns -- 1 row header and 4 columns. If you want the row header to be bigger so the N and PCTN are smaller in the second output, then you need a different type of style override just for N and PCTN, as shown below:
I think this alternate approach will get you closer. In my use of TABULATE, I find it better to either do all my controlling in the TABLE, CLASS and CLASSLEV statements OR at the overall TABLE level, but not both places. In your original code, you had controls on KEYWORD and on the overall TABLE and this usage overcontrolled the TABLE and allowed PDF to draw the table with too much white space.
Cynthia
Hi:
When I run your code both with and without the KEYWORD controls, the font size for the column headers is the same. The width is determined in PDF by a combination of the width you originally specified in the KEYWORD style override and the overall table width. In PDF, when you over-control the widths like this, PDF makes the cells the exact width you specify and then stretches the table to the table width. This leaves gaps of whitespace. Unlike HTML, which will "fill in" the table border lines, PDF does not do that.
However, you said that without the 1cm, the row headers were "too small" and inconsistent. This is not what I observe. I observe the SAME font size being used both with and without the 1 cm width for the keywords N and PCTN as shown below:
The bottom line is that in the top TABULATE, you have 13 columns in the report -- 1 row header and 12 columns. In the lower TABULATE you have 5 columns -- 1 row header and 4 columns. If you want the row header to be bigger so the N and PCTN are smaller in the second output, then you need a different type of style override just for N and PCTN, as shown below:
I think this alternate approach will get you closer. In my use of TABULATE, I find it better to either do all my controlling in the TABLE, CLASS and CLASSLEV statements OR at the overall TABLE level, but not both places. In your original code, you had controls on KEYWORD and on the overall TABLE and this usage overcontrolled the TABLE and allowed PDF to draw the table with too much white space.
Cynthia
Thanks, Cynthia. What I meant by "too small" is too small relative to what I was hoping, not too small to fit the text.
What you show in the second example certainly works, but I'm trying to write this as a macro that creates a bunch of different tables. I'd rather avoid having to look at how many class levels every category variable has if possible (as that's what I'd have to do in order to specify the CLASSLEV width for age, if I understand properly), but it sounds like you're saying that's my only choice?
Thanks!
(Macro like this:)
%macro tabulate(data=, rowvar=, colvar=);
proc tabulate data=&data;
class &rowvar &colvar;
tables &rowvar, &colvar*(n pctn)/style={width=7in};
run;
%mend tabulate;
ods pdf startpage=never;
%tabulate(data=sashelp.class, rowvar=age, colvar=sex);
%tabulate(data=sashelp.class, rowvar=sex, colvar=age);
ods pdf close;
So here I'd have to pre-calculate the number of categories of the COLVAR in here and do math to figure out how long to make the classlev &rowvar cell, if I interpret this correctly.
No, that's not what I'm saying. Your general method WILL work, as shown below:
But then you can't "over-control" by adding style overrides for N and PCTN at the KEYWORD level, as you originally showed. The method I sent was an alternative if you feel you need to control the row header explicitly.
Also, you don't show your margin system options, but you will need to be sure that the right margin and left margin settings leave you with a width of 7in. Or, as an alternate style override, you could do
style={width=100%} -- instead of a specific IN size.
Cynthia
And, as another bit of into to tuck away for future reference. It doesn't make sense to mix units of measure (such as 1 CM and 7 inches) -- PDF is going to convert all units of measure to printer's points I believe, so you're just causing extra work for PDF by mixing units as you originally showed. Just like RTF will translate every unit to TWIPS (twentieths of a printers point). So it's much better to keep all your units the same so there's only 1 conversion going on.
Hope this helps,
Cynthia
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: