# Combine column types defined in dcolumn with tabularx, part 2

This is a follow-up on another question I asked. I am trying to combine the dcolumn package with tabularx (or tabular*for that matter) so the table spans the width I specify, columns are evenly spaced, and cells are aligned by the decimal point.

Here's what I have now

The trick suggested in an answer from that other question was to use the 'D' column in the tabularx environment, and then an 'X' column inside \multicolumns in the first rows of the table. That worked fine in the example given on that question. But now I have a long text in this \multicolumn. The 'X' column seems to "ignore" the number of columns the \multicolumn is meant to span. Changing the 'X' by a 'c' prevents the cell to break, like so:

I suppose one solution is to use a 'p' column. But specifying the column width defeats the purpose IMHO, unless there is an automatic way of doing that -- I tried to get some inspiration from the answer to this question here but didn't go very far.

Any thoughts on how to get the text to span the two columns?

EDIT: here's the basic idea of what I think would be ideal. By declaring \tracingtabularx, tabularx will print the optimal column widths. So I just used the 'X' column in a first go, saw the what tabularx echoed in my log file, multiplied that by 2 and changed the X column by a 'p' column with the calculated width. Of course, it makes no sense to actually do this by hand. What I want is to get tabularx to do it for me.

Here's the code to generate the tables above:

\documentclass{report}

\usepackage{array}
\usepackage{tabularx}
\usepackage{dcolumn}
\usepackage{booktabs}

\newcommand{\mc}{\multicolumn} % handy shortcut macro
\newcolumntype{Z}{>{\centering\arraybackslash}X} % handy shortcut macro
\newcolumntype{d}[1]{D{.}{\cdot}{#1}} % and yet another handy shortcut macro

\begin{document}

% TABLE 1
\noindent
The width of the text block is indicated by this horizontal rule:
\hrule

\begin{table}[h]
\centering
\caption{ multicolumn\{2\}\{X\}\{text\} }
\begin{tabularx}{\textwidth}{l*{3}{d{-2}}}

\toprule
& \mc{1}{X}{}       & \mc{2}{X}{A very long text that should span two columns, not one. 'X' doesn't do the trick.}  \\ \cmidrule{3-4}
& \mc{1}{Z}{(1)}    & \mc{1}{Z}{(2)} & \mc{1}{Z}{(3)}   \\ \cmidrule(r){2-2} \cmidrule(lr){3-3} \cmidrule(l){4-4}
& \mc{1}{Z}{Median} & \mc{1}{Z}{Low} & \mc{1}{Z}{High}  \\ \midrule
bla bla bla      &      2.74         &        31.0    &   1.2            \\
ble ble ble ble  &     31.81         &         1.14   &  11.10           \\

\bottomrule
\end{tabularx}
\end{table}

% TABLE 2
\noindent
The width of the text block is indicated by this horizontal rule:
\hrule

\begin{table}[h]
\centering
\caption{ multicolumn\{2\}\{c\}\{text\} }
\begin{tabularx}{\textwidth}{l*{3}{d{-2}}}

\toprule
& \mc{1}{X}{}       & \mc{2}{c}{A very long text that should be wrapped. 'p' would defeat the purpose.}  \\ \cmidrule{3-4}
& \mc{1}{Z}{(1)}    & \mc{1}{Z}{(2)} & \mc{1}{Z}{(3)}   \\ \cmidrule(r){2-2} \cmidrule(lr){3-3} \cmidrule(l){4-4}
& \mc{1}{Z}{Median} & \mc{1}{Z}{Low} & \mc{1}{Z}{High}  \\ \midrule
bla bla bla      &      2.74         &        31.0    &   1.2            \\
ble ble ble ble  &     31.81         &         1.14   &  11.10           \\

\bottomrule
\end{tabularx}
\end{table}

\end{document}


You can do it by giving a little help to tabularx; since you want to span two equally wide columns, you tell LaTeX that the natural width is twice the reserved width, plus twice the \tabcolsep.

\documentclass{report}

\usepackage{array}
\usepackage{tabularx}
\usepackage{dcolumn}
\usepackage{booktabs}

\newcommand{\mc}{\multicolumn} % handy shortcut macro
\newcolumntype{Z}{>{\centering\arraybackslash}X} % handy shortcut macro
\newcolumntype{d}[1]{D{.}{\cdot}{#1}} % and yet another handy shortcut macro

\begin{document}

% TABLE 1
\noindent
The width of the text block is indicated by this horizontal rule:
\hrule

\begin{table}[htp]
\centering
\caption{multicolumn\{2\}\{X\}\{text\} }
\begin{tabularx}{\textwidth}{l*{3}{d{-2}}}

\toprule
& \mc{1}{X}{}       &
\mc{2}{>{\hsize=\dimexpr2\hsize+2\tabcolsep}X}{%
A very long text that should span two columns, not one.
X' does the trick, with a little help.} \\
\cmidrule{3-4}
& \mc{1}{Z}{(1)}    & \mc{1}{Z}{(2)} & \mc{1}{Z}{(3)}   \\
\cmidrule(r){2-2} \cmidrule(lr){3-3} \cmidrule(l){4-4}
& \mc{1}{Z}{Median} & \mc{1}{Z}{Low} & \mc{1}{Z}{High}  \\
\midrule
bla bla bla      &      2.74         &        31.0    &   1.2            \\
ble ble ble ble  &     31.81         &         1.14   &  11.10           \\

\bottomrule
\end{tabularx}
\end{table}

\end{document}


• I guess that's what I was looking for. – djas Nov 2 '13 at 21:36

Putting the long line in a \parbox works for me

\documentclass{report}

\usepackage{array}
\usepackage{tabularx}
\usepackage{dcolumn}
\usepackage{booktabs}

\newcommand{\mc}{\multicolumn} % handy shortcut macro
\newcolumntype{Z}{>{\centering\arraybackslash}X} % handy shortcut macro
\newcolumntype{d}[1]{D{.}{\cdot}{#1}} % and yet another handy shortcut macro

\begin{document}

% TABLE 1
\noindent
The width of the text block is indicated by this horizontal rule:
\hrule

\begin{table}[h]
\centering
\caption{ multicolumn\{2\}\{c\}\{text\} }
\begin{tabularx}{\textwidth}{l*{3}{d{-2}}}

\toprule
& \mc{1}{X}{}       & \mc{2}{c}{\parbox{.5\columnwidth}{A very long text that should be wrapped. 'p' would defeat the purpose.}}  \\ \cmidrule{3-4}
& \mc{1}{Z}{(1)}    & \mc{1}{Z}{(2)} & \mc{1}{Z}{(3)}   \\ \cmidrule(r){2-2} \cmidrule(lr){3-3} \cmidrule(l){4-4}
& \mc{1}{Z}{Median} & \mc{1}{Z}{Low} & \mc{1}{Z}{High}  \\ \midrule
bla bla bla      &      2.74         &        31.0    &   1.2            \\
\bottomrule
\end{tabularx}
\end{table}

\end{document}
`
• That's sort of equivalent to using the 'p' column; unless there is some way of automatically calculating the width of those two columns, that's something I'd avoid if possible. – djas Nov 2 '13 at 20:21