# Alignment in tabularx environment

I want to generate a table that looks approximately as follows:

I want to use tabularx to have equidistant cells for the cells that are below the second row and right of the first column.

Here is my Latex code:

\documentclass{article}

\usepackage{tabularx}
\usepackage{booktabs}

\begin{document}

\begin{tabularx}{.5\textwidth}{l *{6}{X} }
\toprule
& \multicolumn{2}{c}{first} & \multicolumn{2}{c}{second} & \multicolumn{2}{c}{third} \\
\multicolumn{1}{c}{data set} & foo & bar & foo & bar & foo & bar \\
\midrule
d1 & 28.4 & 4.4 & 25.9 & 8.9 & -3.7 & 33.3 \\
d2 & 2.8 & 3.7 & 5.1 & 16.3 & 47.0 & 0.1 \\
d3 & 32.1 & 4.2 & 31.5 & 4.0 & 23.0 & 3.3 \\
\bottomrule
\end{tabularx}

\end{document}


This is generated by pdflatex:

I need tabularx since I want to give the total width of the table and let tabularx (or a similar package) do the length calculation. All numers should be aligned to the right and a number should not wrap between the minus and the letters.

-
no you really don't want to use tabularx for numeric data, more or less everything it does is unsuitable for that case:-) It is designed to change the line breaking width for paragraphs of text. –  David Carlisle Jul 22 '14 at 9:59
What do I want to use then? :) –  Manuel Jul 22 '14 at 10:00
Please read section 4.2 of the tabularx documentation. –  Martin Schröder Jul 22 '14 at 10:04

Don't use tabularx on numeric data:-)

\documentclass{article}

\usepackage{dcolumn}
\usepackage{booktabs}

\begin{document}

\begin{center}
\begin{tabular}{l *{6}{D..{3.1}}}
\toprule
& \multicolumn{2}{c}{first} & \multicolumn{2}{c}{second} & \multicolumn{2}{c}{third} \\
\multicolumn{1}{c}{data set} &
\multicolumn{1}{c}{foo} &
\multicolumn{1}{c}{bar} &
\multicolumn{1}{c}{foo} &
\multicolumn{1}{c}{bar} &
\multicolumn{1}{c}{foo} &
\multicolumn{1}{c}{bar} \\
\midrule
d1 & 28.4 & 4.4 & 25.9 & 8.9 & -3.7 & 33.3 \\
d2 & 2.8 & 3.7 & 5.1 & 16.3 & 47.0 & 0.1 \\
d3 & 32.1 & 4.2 & 31.5 & 4.0 & 23.0 & 3.3 \\
\bottomrule
\end{tabular}
\end{center}

\end{document}

-
it is perfectly reasonably to use it for numeric data, just don't use X columns for data ;-) I tend to use X columns for hspace. –  daleif Jul 22 '14 at 10:34

You want siunitx; if you really want to spread out the table (don't, please respect your readers ;-)), use tabular*:

\documentclass{article}

\usepackage{siunitx}
\usepackage{booktabs}

\begin{document}

\begin{center}
\begin{tabular}{
l
S[table-format=2.1]
S[table-format=1.1]
S[table-format=2.1]
S[table-format=2.1]
S[table-format=-1.1]% the minus covers the second digit
S[table-format=2.1]
}
\toprule
& \multicolumn{2}{c}{first} & \multicolumn{2}{c}{second} & \multicolumn{2}{c}{third} \\
data set & {foo} & {bar} & {foo} & {bar} & {foo} & {bar} \\
\midrule
d1 & 28.4 & 4.4 & 25.9 & 8.9 & -3.7 & 33.3 \\
d2 & 2.8 & 3.7 & 5.1 & 16.3 & 47.0 & 0.1 \\
d3 & 32.1 & 4.2 & 31.5 & 4.0 & 23.0 & 3.3 \\
\bottomrule
\end{tabular}
\end{center}

\begin{center}
\begin{tabular*}{\textwidth}{
l@{\extracolsep{\fill}}
S[table-format=2.1]@{\extracolsep{2\tabcolsep}}
S[table-format=1.1]@{\extracolsep{\fill}}
S[table-format=2.1]@{\extracolsep{2\tabcolsep}}
S[table-format=2.1]@{\extracolsep{\fill}}
S[table-format=-1.1]@{\extracolsep{2\tabcolsep}}
S[table-format=2.1]
}
\toprule
& \multicolumn{2}{c}{first} & \multicolumn{2}{c}{second} & \multicolumn{2}{c}{third} \\
data set & {foo} & {bar} & {foo} & {bar} & {foo} & {bar} \\
\midrule
d1 & 28.4 & 4.4 & 25.9 & 8.9 & -3.7 & 33.3 \\
d2 & 2.8 & 3.7 & 5.1 & 16.3 & 47.0 & 0.1 \\
d3 & 32.1 & 4.2 & 31.5 & 4.0 & 23.0 & 3.3 \\
\bottomrule
\end{tabular*}
\end{center}

\end{document}


-
One disadvantage of this is when you add a \cmidrule{2-3} the padding is gone. –  daleif Jul 22 '14 at 10:38
@daleif What do you mean? For the first table, \cmidrule(lr){2-3} should be used. For the (unrecommended) second, \cmidrule{2-3} is OK. –  egreg Jul 22 '14 at 10:43
Add \cmidrule{2-3} to both tables. It is much longer in the non-stretched version (I think that looks better). –  daleif Jul 22 '14 at 11:06
I tend to use @{}X@{} columns to add space columns between columns. However this also eats up the padding. I usually prefer @{}X@{} over X for space columns, as the can shrink. –  daleif Jul 22 '14 at 11:13
@daleif I wouldn't recommend @{}X@{} for spacing columns: \extracolsep works, as you can see, and has no impact on \cmidrule; it requires a bit more work, but is no hack. Actually I wouldn't recommend tables spread to the text width in the first place. –  egreg Jul 22 '14 at 11:39

However, using tabularx is a simple way to have equal width columns with a prescribed total width, which may be desirable for numeric data. As for the alignment on the deimal dot, it's easy to get it here, since data have to be right-aligned, and all have the sae number of decimal digits:

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{array, tabularx}
\usepackage{booktabs}
\usepackage{ragged2e}
\newcolumntype{Y}{ >{\hsize=1.75\hsize}X}
\newcolumntype{Z}{ >{\hsize=.875\hsize\RaggedLeft}X}
\setlength\extrarowheight{1.5pt}

\begin{document}

\sffamily
\begin{tabularx}{.75\textwidth}{@{\,\,}Y *{6}{Z}@{\,\,}}
\toprule
& \multicolumn{2}{c}{first} & \multicolumn{2}{c}{second} & \multicolumn{2}{c}{third} \\
data set  & \multicolumn{1}{c}{foo} & \multicolumn{1}{c}{bar} & \multicolumn{1}{c}{foo} & \multicolumn{1}{c}{bar} & \multicolumn{1}{c}{foo} & \multicolumn{1}{c}{bar} \\
\cmidrule(l{0.25em}r{0.25em}){1-7}
d1 & 28.4 & 4.4 & 25.9 & 8.9 & $-$3.7 & 33.3 \\
d2 & 2.8 & 3.7 & 5.1 & 16.3 & 47.0 & 0.1 \\
d3 & 32.1 & 4.2 & 31.5 & 4.0 & 23.0 & 3.3 \\
\bottomrule
\end{tabularx}

\end{document}


-

This is just a longer comment to @egreg's answer using his tabular table, rewritten as tabularx

When space permits I tend to rewrite like this using tabularx. I use the X columns to add the space between columns, not for the data columns (I also recomment siunitx for that). I double the number of columns, and then adjust the space columns accordingly. Note that the a type is for inside a group and should be followed by @{\hspace{some space}} or similar, here I used !{\quad} to specify the true distance between the columns in a group. Outside the group an X is used (under a different name), note that where a remove any padding, A does not. This gives us padding under the \cmidrule which I think looks better.

\documentclass{article}
\usepackage{siunitx}
\usepackage{booktabs,tabularx,array}
\newcolumntype{A}{X}
\newcolumntype{a}{@{}l@{}}
\begin{document}

\begin{center}
\begin{tabularx}{0.9\textwidth}{
l
A
S[table-format=2.1]
S[table-format=1.1]
A
S[table-format=2.1]
S[table-format=2.1]
A
S[table-format=-1.1]% the minus covers the second digit
S[table-format=2.1]
}
\toprule
&& \multicolumn{3}{c}{first} && \multicolumn{3}{c}{second} &&
\multicolumn{3}{c}{third} \\
\cmidrule{3-5}
\cmidrule{7-9}
\cmidrule{11-13}
data set && {foo} && {bar} && {foo} && {bar} && {foo} && {bar} \\
\midrule
d1 && 28.4 && 4.4 && 25.9 && 8.9 && -3.7 && 33.3 \\
d2 && 2.8 && 3.7 && 5.1 && 16.3 && 47.0 && 0.1 \\
d3 && 32.1 && 4.2 && 31.5 && 4.0 && 23.0 && 3.3 \\
\bottomrule
\end{tabularx}
\end{center}

\end{document}


-