1

In a previous question (How to force type X columns to wrap their contents when using \multicolumn command?), I asked for a code that allows me to use \multicolumn command that crosses type X columns. Zarko provided me with a code that solves the my issue

multicolumn{3}{>{\hsize=\dimexpr3\hsize+4\tabcolsep\relax}C}{% Time Needed With Our Approach \newline (Extended Brown's Method)}

Inspired by his answer, I wrote a custom command as follows

\newcommand{\multcolhsize}[1]{\dimexpr #1\hsize + #1\tabcolsep + \tabcolsep \relax}

Which allows for the concise application of the original code provided by Zarko

\multicolumn{n}{>{\hsize=\multcolhsize{n}\}X}{<text>}

However, right now, when using the code, it does not seem that the text is not properly justified when using \justifying\arraybackslash in the preamble of type X columns. Similarly, it does not seem to go exactly to the center when using \centering\arraybackslash

enter image description here

enter image description here

Clearly, the custom command might be improved further to guarantee that it goes exactly to the center or justifies properly for the specified columns.

\documentclass{book}

    \usepackage[a4paper]{geometry}

        \geometry{twoside=true, showframe=false}

        % Horizontal
        \geometry{inner=10mm, outer=10mm, includemp=true, bindingoffset=5mm, marginparsep=3.5mm, marginparwidth=15mm}

        % Vertical
        \geometry{top=20mm, vmarginratio=3:5, includehead=true, includefoot=true, headheight=8pt, headsep=14pt, footskip=5mm}

    \usepackage{ragged2e}
    \usepackage{tabularx}
        \def \tabularxcolumn#1{m{#1}}
        \newcolumntype{C}{>{\arraybackslash\Centering}X}

        \newcommand{\multcolhsize}[1]{\dimexpr #1\hsize + #1\tabcolsep + \tabcolsep \relax}

    \usepackage{booktabs}
    \usepackage{makecell}

    \usepackage{adjustbox}

\begin{document}

\begin{table*}[htp]

    \def \tabularxcolumn#1{p{#1}}

    \caption{Caption}

    \centering

    \begin{tabularx}{\textwidth}{r p{3cm} *{10}{C}}

        \toprule

        &
        &
        \multicolumn{10}{>{\hsize=\multcolhsize{10}\centering\arraybackslash}X}{Complexity}
        \\
        \cmidrule(l){3-12}

        &
        Description &
        \adjustbox{rotate=90}{Method 1} &
        \adjustbox{rotate=90}{Method 2} &
        \adjustbox{rotate=90}{Method 3} &
        \adjustbox{rotate=90}{Method 4} &
        \adjustbox{rotate=90}{Method 5} &
        \adjustbox{rotate=90}{Method 6} &
        \adjustbox{rotate=90}{Method 7} &
        \adjustbox{rotate=90}{Method 8} &
        \adjustbox{rotate=90}{Method 9} &
        \adjustbox{rotate=90}{Method 10}
        \\
        \cmidrule(r){2-2} \cmidrule(l){3-12}

        1. &
        Description A &
        VS &
        S &
        VS &
        S &
        VS &
        S &
        C &
        VC &
        C &
        VC
        \\
        \addlinespace[0.1cm]

        2. &
        Description B &
        S &
        C &
        S &
        C &
        S &
        C &
        S &
        C &
        S &
        C
        \\
        \addlinespace[0.1cm]

        3. &
        Description C &
        N &
        N &
        N &
        N &
        N &
        N &
        Y &
        VC &
        Y &
        VC
        \\
        \addlinespace[0.1cm]

        \bottomrule

    \end{tabularx}

\end{table*}

\end{document}

3 Answers 3

1

You need to change

\newcommand{\multcolhsize}[1]{\dimexpr #1\hsize + #1\tabcolsep + \tabcolsep \relax}

to

\newcommand{\multcolhsize}[2]{\dimexpr #1\hsize + #2\tabcolsep \relax}

Then, in the

\multicolumn{10}{>{\hsize=\multcolhsize{10}\centering\arraybackslash}X}{Complexity}

statement, you need to change

\hsize=\multcolhsize{10}

to

\hsize=\multcolhsize{10}{18}

However, since the column header -- "Complexity" -- is quite short, you'd be perfectly ok to write

\multicolumn{10}{c}{Complexity}

"Why the 18 in \multcolhsize{10}{18}?", you may ask. LaTeX by default automatically inserts whitespace in the amount of \tabcolsep on both sides any tabular-type column. The total amount of whitespace between two columns thus amounts 2\tabcolsep. To calculate the total usable width of the \multicolumn{10}{...}{...} column, one has to allow for both 10\hsize and 2*9=18\tabcolsep.


Addendum: Armed with this information, let's go back to @Zarko's answer, in which he wrote

\multicolumn{3}{>{\hsize=\dimexpr3\hsize+4\tabcolsep\relax}C}{...}

Since three columns are being spanned, 3\hsize must be right. But with three columns, there are two inter-column spaces to consider, each with width 2\tabcolsep. Hence, the total usable width indeed equals 3\hsize+4\tabcolsep.


Finally, here's the output of the adjusted form of your MWE.

enter image description here

\documentclass{book}
    \usepackage{geometry}
    \geometry{a4paper,twoside=true}
    % Horizontal
    \geometry{inner=10mm, outer=10mm, includemp=true, bindingoffset=5mm, 
              marginparsep=3.5mm, marginparwidth=15mm}
    % Vertical
    \geometry{top=20mm, vmarginratio=3:5, includehead=true, 
              includefoot=true, headheight=8pt, headsep=14pt, footskip=5mm}

    \usepackage{ragged2e}
    \usepackage{tabularx}
    \def\tabularxcolumn#1{m{#1}}
    \newcolumntype{C}{>{\arraybackslash\Centering}X}
    % Another way to define '\multcolhsize', with just 1 argument
    \newcommand{\multcolhsize}[1]{\dimexpr%   
         #1\hsize+#1\tabcolsep+#1\tabcolsep-2\tabcolsep\relax}

    \usepackage{booktabs}
    \usepackage{makecell}
    \usepackage{adjustbox}

\begin{document}

\begin{table}[htp]

    \def\tabularxcolumn#1{p{#1}}
    \caption{Caption}
    \centering

    \begin{tabularx}{\textwidth}{r p{3cm} *{10}{C}}
    \toprule
    & & \multicolumn{10}{>{\hsize=\multcolhsize{10}\Centering}X}{Complexity}
    \\
    \cmidrule(l){3-12}
    & Description &
        \adjustbox{rotate=90}{Method 1} &
        \adjustbox{rotate=90}{Method 2} &
        \adjustbox{rotate=90}{Method 3} &
        \adjustbox{rotate=90}{Method 4} &
        \adjustbox{rotate=90}{Method 5} &
        \adjustbox{rotate=90}{Method 6} &
        \adjustbox{rotate=90}{Method 7} &
        \adjustbox{rotate=90}{Method 8} &
        \adjustbox{rotate=90}{Method 9} &
        \adjustbox{rotate=90}{Method 10} \\
    \midrule
    1. & Description A & VS & S & VS & S & VS & S & C & VC & C & VC \\
    \addlinespace
    2. & Description B & S & C & S & C & S & C & S & C & S & C \\
    \addlinespace
    3. & Description C & N & N & N & N & N & N & Y & VC & Y & VC \\
    \bottomrule
    \end{tabularx}
\end{table}
\end{document}
4
  • Great answer. However, it might be too redundant to try calculating how much \tabcolsep to add. Is it possible to get a command with a single argument that automatically calculates the second value? Commented May 31, 2020 at 22:04
  • @Al-MotasemAldaoudeyeh - For the case at hand, surely \multicolumn{10}{c}{Complexity} must be the easiest way to go. The formula for the total usable width is n\hsize+2(n-1)\tabcolsep. I suppose there's nothing to stop you from writing \newcommand{\multcolhsize}[1]{\dimexpr#1\hsize+#1\tabcolsep+#1\tabcolsep-2\tabcolsep\relax}, is there?
    – Mico
    Commented May 31, 2020 at 22:12
  • Thank you very much for your help. The new definition works very well. Hopefully, I would like that you mention it explicitly by modifying your original answer. However, the numerical illustration you provided is also great, which helps others understand why I get the anomaly in my original code. Commented May 31, 2020 at 22:19
  • @Al-MotasemAldaoudeyeh - I've posted an further addendum, with your MWE adapted so that \multcolhsize takes just 1 argument.
    – Mico
    Commented May 31, 2020 at 22:33
1

It’s easy peasy with tblr environment of the new LaTeX3 package tabularray: multicolumn, X column and cell centering work as expected.

Note you need to put trim option l of \cmidrule command in the square brackets.

\documentclass{book}

\usepackage{geometry}
\geometry{a4paper,twoside=true}
% Horizontal
\geometry{inner=10mm, outer=10mm, includemp=true, bindingoffset=5mm, 
          marginparsep=3.5mm, marginparwidth=15mm}
% Vertical
\geometry{top=20mm, vmarginratio=3:5, includehead=true, 
          includefoot=true, headheight=8pt, headsep=14pt, footskip=5mm}

\usepackage{adjustbox}

\usepackage{tabularray}
\UseTblrLibrary{booktabs}

\begin{document}

\begin{table}[htp]
  \caption{Caption}
  \centering
  \begin{tblr}{r p{3cm} *{10}{X[c]}}
    \toprule
    & & \SetCell[c=10]{c} Complexity & & & & & & & & & 
    \\
    \cmidrule[l]{3-12}
    & Description &
        \adjustbox{rotate=90}{Method 1} &
        \adjustbox{rotate=90}{Method 2} &
        \adjustbox{rotate=90}{Method 3} &
        \adjustbox{rotate=90}{Method 4} &
        \adjustbox{rotate=90}{Method 5} &
        \adjustbox{rotate=90}{Method 6} &
        \adjustbox{rotate=90}{Method 7} &
        \adjustbox{rotate=90}{Method 8} &
        \adjustbox{rotate=90}{Method 9} &
        \adjustbox{rotate=90}{Method 10} \\
    \midrule
    1. & Description A & VS & S & VS & S & VS & S & C & VC & C & VC \\
    \addlinespace
    2. & Description B & S & C & S & C & S & C & S & C & S & C \\
    \addlinespace
    3. & Description C & N & N & N & N & N & N & Y & VC & Y & VC \\
    \bottomrule
  \end{tblr}
\end{table}

\end{document}

enter image description here

0

I'm not sure why using tabularx. This seems more a job for tabular*.

\documentclass{book}

\usepackage[a4paper]{geometry}
\usepackage{ragged2e}
\usepackage{booktabs}
\usepackage{makecell}
\usepackage{adjustbox}

\geometry{
  twoside=true,
  showframe=false,
  % Horizontal
  inner=10mm,
  outer=10mm,
  includemp=true,
  bindingoffset=5mm,
  marginparsep=3.5mm,
  marginparwidth=15mm,
  % Vertical
  top=20mm,
  vmarginratio=3:5,
  includehead=true,
  includefoot=true,
  headheight=8pt,
  headsep=14pt,
  footskip=5mm,
}


\begin{document}

\begin{table*}[htp]

\caption{Caption}

\centering

\begin{tabular*}{\textwidth}{r l @{\extracolsep{\fill}} *{10}{c}}
\toprule
&& \multicolumn{10}{c}{Complexity}
\\
\cmidrule(r){3-12}
&
Description &
\adjustbox{rotate=90}{Method 1} &
\adjustbox{rotate=90}{Method 2} &
\adjustbox{rotate=90}{Method 3} &
\adjustbox{rotate=90}{Method 4} &
\adjustbox{rotate=90}{Method 5} &
\adjustbox{rotate=90}{Method 6} &
\adjustbox{rotate=90}{Method 7} &
\adjustbox{rotate=90}{Method 8} &
\adjustbox{rotate=90}{Method 9} &
\adjustbox{rotate=90}{Method 10}
\\
\cmidrule(l){2-2} \cmidrule(r){3-12}

1. & Description A & VS & S & VS & S & VS & S & C & VC & C & VC \\
\addlinespace[0.1cm]

2. & Description B & S & C & S & C & S & C & S & C & S & C \\
\addlinespace[0.1cm]

3. & Description C & N & N & N & N & N & N & Y & VC & Y & VC \\
\addlinespace[0.1cm]

\bottomrule
\end{tabular*}

\end{table*}

\end{document}

enter image description here

I'd avoid the rotated headers, though.

\begin{tabular*}{\textwidth}{r l @{\extracolsep{\fill}} *{10}{c}}
\toprule
& Description & \multicolumn{10}{c}{Complexity methods} \\
\cmidrule(r){3-12}
&& 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 \\
\midrule

1. & Description A & VS & S & VS & S & VS & S & C & VC & C & VC \\
\addlinespace[0.1cm]

2. & Description B & S & C & S & C & S & C & S & C & S & C \\
\addlinespace[0.1cm]

3. & Description C & N & N & N & N & N & N & Y & VC & Y & VC \\
\addlinespace[0.1cm]

\bottomrule
\end{tabular*}

enter image description here

5
  • I usually use tabularx because it accepts type X columns, which might be systematically determined. For instance, I might need to specify that a column be twice the size of another column, while the entire width must be equal to the text or column width. Meeting such criteria simultaneously is easier with tabularx Commented May 31, 2020 at 22:12
  • @Al-MotasemAldaoudeyeh This doesn't seem the case here. You can use a screwdriver for opening a bottle of orange juice, but a bottle opener is better.
    – egreg
    Commented May 31, 2020 at 22:14
  • 1
    I suppose a purposeful reason for using a tabularx environment in the table at hand, which features 10 data columns, is to assure that 10 data columns all have the exact same width. If one looks closely at the screenshots you posted (generated with the help of tabular*, one notices that data columns 2, 4, 4, 7 and 9 are ever so slightly narrower than the other five. Not a huge distraction, though, for sure. But if for some reason it's necessary for all 10 data columns to have the exact same width, tabularx is the way to go.
    – Mico
    Commented May 31, 2020 at 22:20
  • @egreg The original tables I use in the paper are tabularx which look more professional when they extend along the entire text width. I just want to verify that any proposed solution works well with I typically use Commented May 31, 2020 at 22:24
  • @Mico That can be cured in several ways, the last of which to try is tabularx.
    – egreg
    Commented May 31, 2020 at 22:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .