I have some tables coming from the statistical package R that I want to export in LaTeX markup.
I would like to make every column large as the longest word of its label (assuming for simplicity the related tabular values are shorter).
If the labels are like such:
Short label
Very long description
Three letter label
then the desired output (including some example values) is:
Short Very long Three
label description letter
label
-----------------------------
1 5 9
2 6 10
3 7 11
4 8 12
-----------------------------
One can do every sort of trickery on table label/values in R, but outside LaTeX, R itself can only count characters of table labels, without knowing the actual space used when they are typeset by the LaTeX engine.
Main idea
The main the idea is to generate, from an R script, the LaTeX code able to measure the words and use the lengths calculated in LaTeX to setup the actual tabular environment. A scratch of the LaTeX measuring document is:
...
\usepackage{varwidth, calc}
...
\newlength{\temp}
%% Column 1
\setlength{\temp}{\widthof{\fbox{\begin{varwidth}{\textwidth}
Short\\ label
\end{varwidth}}}}
\the\temp
%% Column 2
\setlength{\temp}{\widthof{\fbox{\begin{varwidth}{\textwidth}
Very \\ long \\ description
\end{varwidth}}}}
\the\temp
%% Column 3
\setlength{\temp}{\widthof{\fbox{\begin{varwidth}{\textwidth}
Three \\ letter \\ label
\end{varwidth}}}}
\the\temp
Latexing it, I get this output:
30.71672pt
54.6612pt
32.38335pt
Now I could parse this output in R and produce the following LaTeX code:
\usepackage{array}
...
\def\tabcol{p{30.71672pt}p{54.6612pt}p{32.38335pt}}
\expandafter\tabular\expandafter{\tabcol}
\hline
Short label & Very long description & Three letter label \\\hline
1 & 2 & 3
\endtabular
Desired solution
Instead of parsing the output of the first code snippet in R, I wonder if I can reduce this step and do it straight in LaTeX, that is: can I capture the lengths \temp
and store them in a sort of "string variable", so that I can use it in the \tabcol
macro?
EDIT
A number of comments are asking why I am not using knitr/Sweave or the like. I didn't enter into these details to avoid being flagged as off topic. Now I suppose more insights are needed by readers.
First I use Rnw
+knitr
+xtable
. R-NoWeb documents are LaTeX docs interspersed with the special markup blocks, denoted "code chunks":
<<...>>
...
@
where the dots represent R code or options. knitr
executes the R code inside the code chunks and replaces it the its generated output formatted in LaTeX (if the code produces a figure, knitr will automatically place an \includegraphics...
pointing to the figure file, unless you opt for a manual control of the LaTeX output). As the knitr parsed file is an "ordinary" LaTeX file, you latex it and your report is done.
As for the tables, the module xtable
can convert R data objects in LaTeX, using several cool LaTeX environments (booktabs
, tabularx
etc.). To the best of my knowledge no one can automatically resize table as I am trying to do. tabularx
does it, but with a different algorithm.
Anyway in R it is easy to arrange table data by column and generate for each column a LaTeX output similar to:
%% Column 1
\setlength{\temp}{\widthof{\fbox{\begin{varwidth}{\textwidth}
Short\\ label
\end{varwidth}}}}
\the\temp
As observed above, by compiling these lines (duly repeated for each column) I get the desired sizes. To capture temp
length I might use:
\immediate\openout\tempfile=lengths.tex
\immediate\write\tempfile{\the\temp}
\immediate\closeout\tempfile
So the actual R-generated file, say table.tex
, should be similar to:
\usepackage{varwidth, calc}
\usepackage{array}
...
\newlength{\temp}
\immediate\openout\tempfile=lengths.tex
...
%% Column 1
\setlength{\temp}{\widthof{\fbox{\begin{varwidth}{\textwidth}
Short\\ label
\end{varwidth}}}}
%\the\temp
\immediate\write\tempfile{\the\temp}
%% Column 2
...
%% Column n
...
\immediate\closeout\tempfile
...
After compiling in LaTeX table.tex
, lengths.tex
is produced. lengths.tex
can be reparsed in R in order to read column values inside. A new table.tex
can be produced
\usepackage{array}
...
\def\tabcol{p{...pt}p{...pt}...}
\expand\tabular\expandafter{\tabcol}
\endtabular
p{...pt}
's are those obtained from lengths.tex
.
The new table.tex
can be relatexed to get the final result, but, as told above, I would like to parse the first table.tex
(or the first pass output lengths.tex
) straight in LaTeX and automatically (without going back and forth from R to LaTeX).
tabular
head?sweave
/knitr
? (I do not know more than the names.)xtable
function and thelatex
function from theHmisc
R package can produce LaTeX tables directly.