Here is a possible solution to your similar-width panel in tables by means of the tabularx
package. It provides the environment tabularx
that takes an argument specifying the width of the tabularx
. That allows one to typeset the two panels as two separate tables but still maintain the same width across both tables. To stretch it across the entire width of the text, I used \linewidth
. A new column type Y
was defined as a right-aligned (\raggedleft
) version of the stretchable X
column type provided by tabularx
. Also, the booktabs
package was loaded in order to improve the table layout.
\documentclass{article}
\usepackage[margin=2cm]{geometry}% http://ctan.org/pkg/geometry
\usepackage{tabularx}% http://ctan.org/pkg/tabularx
\usepackage{booktabs}% http://ctan.org/pkg/booktabs
\newcolumntype{Y}{>{\raggedleft\arraybackslash}X}% raggedleft column X
\begin{document}
\begin{table}[htb]
\caption{Descriptive Statistics and Correlations for Variables}
\label{tbl:stats-and-correlations}
\begin{tabularx}{\linewidth}{l*{6}{Y}}
\toprule
\multicolumn{7}{l}{\textbf{Panel A: Descriptive Statistics}} \\
\midrule
& Mean & Median & St.\ Dev. & IQR & 25$^{\textrm{th}}$ & 75$^{\textrm{th}}$ \\[0pt]
& & & & & Percentile & Percentile \\
Variable 1 & 12.3 & 45.6 & 7.89 & 5 & 12.0 & 0.22 \\
Variable 2 & 8.3 & 1.0 & 0.01 & 12 & 99.9 & 10.0 \\
\ldots & & & & & &
\end{tabularx}
\begin{tabularx}{\linewidth}{l*{7}{Y}}
\toprule
\multicolumn{7}{l}{\textbf{Panel B: Correlations}} \\
\midrule
& Var.\ 1 & Var.\ 2 & Var.\ 3 & Var.\ 4 & Var.\ 5 & Var.\ 6 & Var.\ 7 \\
Variable~1 & 0.78 & 0.37 & 0.48 & 0.10 & 0.13 & 0.58 & 0.41 \\
Variable~2 & 0.46 & 0.86 & 0.96 & 0.44 & 0.15 & 0.56 & 0.31 \\
Variable~3 & 0.03 & 0.75 & 0.11 & 0.44 & 0.71 & 0.06 & 0.26 \\
Variable~4 & 0.21 & 0.25 & 0.38 & 0.88 & 0.24 & 0.52 & 0.46 \\
Variable~5 & 0.20 & 0.93 & 0.54 & 0.96 & 0.55 & 0.82 & 0.62 \\
Variable~6 & 0.67 & 0.85 & 0.74 & 0.99 & 0.27 & 0.48 & 0.85 \\
Variable~7 & 0.82 & 0.89 & 0.68 & 0.06 & 0.02 & 0.30 & 0.10 \\
\bottomrule
\end{tabularx}
[1]\ Footnote 1: Variable~1 is calculated as\ldots \endgraf
[2]\ Correlations are Pearson.
\end{table}
\end{document}
Minor adjustments to the column alignment, spacing and typesetting is possible.
I think I found an acceptable solution.
Assume that the statistical table is schematically as follows:
Short label Very long description Three letter label
1 1 5 9
2 2 6 10
3 3 7 11
4 4 8 12
LaTeX code to be generated to make every column large as the longest word of its label is:
\documentclass{article}
\usepackage{varwidth, calc}
\begin{document}
%% LaTeX vars
\def\colDef{}
\newlength{\temp}
%% Column 1
\setlength{\temp}{\widthof{\mbox{\begin{varwidth}{\textwidth}
Short\\label
\end{varwidth}}}}
\edef\colDef{\colDef p{\the\temp}}
%% Column 2
\setlength{\temp}{\widthof{\mbox{\begin{varwidth}{\textwidth}
Very\\long\\description
\end{varwidth}}}}
\edef\colDef{\colDef p{\the\temp}}
%% Column 3
\setlength{\temp}{\widthof{\mbox{\begin{varwidth}{\textwidth}
Three\\letter\\label
\end{varwidth}}}}
\edef\colDef{\colDef p{\the\temp}}
\edef\colDef{{\colDef}}
%% Table Macro
\newcommand{\maketab}[2]{%
\begin{tabular}{#1}
#2
\end{tabular}
}
%% Table Body
\newcommand{\tableBody}{
Short label & Very long description & Three letter label \\
\hline
1 & 5 & 9 \\
2 & 6 & 10 \\
3 & 7 & 11 \\
4 & 8 & 12 \\
\hline
}
%% and...
\expandafter\maketab\colDef{\tableBody}
\end{document}
Latexing one gets the intended results for labels:
Short Very long Three
label description letter
label
-----------------------------
1 5 9
2 6 10
3 7 11
4 8 12
-----------------------------
The R/knitr side
As there are both the knitr
and xtable
tags on tex.stackexchange, I assume the R code to generate the above LaTeX might be of interest to someone.
The Rnw document to "knit" is:
\documentclass{article}
\usepackage{varwidth, calc}
\begin{document}
<<label=ididit, results='asis', echo=FALSE>>=
library(xtable)
## Generate sample 4x3 table, with long labels
## -------------------------------------------
tab=data.frame(matrix(1:12, ncol=3))
names(tab) = c("Short label", "Very long description", "Three letter label")
## Generate LaTeX code: every \ needs to be doubled (escaped)
## -----------------------------------------------------------
## Print LaTeX vars
cat("
\\def\\colDef{}
\\newlength{\\temp}
")
## Dynamic text
text1="\\setlength{\\temp}{\\widthof{\\mbox{\\begin{varwidth}{\\textwidth}"
# Labels here separated by //
text2="\\end{varwidth}}}}
\\edef\\colDef{\\colDef p{\\the\\temp}}
"
## Separate labels with \\\\
lab= strsplit(names(tab), " ")
lab= sapply(lab, function(x) paste(x, collapse='\\\\'))
## Replace dynamic text with labels and print it
text=paste(text1, lab, text2, sep="\n", collapse="\n")
cat(text)
cat("\n\\edef\\colDef{{\\colDef}}")
## Setup main table macro
cat("
\\newcommand{\\maketab}[2]{%
\\begin{tabular}{#1}
#2
\\end{tabular}
}
")
## Table body obtained via xtable module
cat("\\newcommand{\\tableBody}{\n")
print.xtable(xtable(tab), only.contents=T, include.rownames=F)
cat("}\n")
### eventually...
cat("\\expandafter\\maketab\\colDef{\\tableBody}")
@
\end{document}
If this document is named table.rnw
, knitting it, that is, executing in R:
knitr("table.rnw")
will generate a table.tex
like the LaTeX code shown in the first listing above (plus some some knitr macro embellishment for graphics) to be compiled in LaTeX in order to get the desired table output.
Comments on solution
Note that the proposed solution requires one step in R + one step in LaTeX, as the generated LaTeX contains both the code to measure lengths and to use them in the tabular environment. xtable
is used only to produce the formatted list of the table inner cells, so one can easily customise the tabular environment with something fancier and/or anyway set more formatting parameters for the table.
Avoiding extra round trip from R to LaTeX means speed, anyway do suggest any path to further improve it.
Best Answer
some combination of these might work....