How to use row headers with vertical text inside a table?

I'm trying to insert a header for some rows of my table. Unfortunately, the result looks weird and the text is not well aligned to the rest of the table. In details my problems are:

1. How do I properly insert a row header with vertical text?
2. How do I prevent the text from falling out of a cell if it is too long?

Here is my current code:

\documentclass[journal]{IEEEtran}

\usepackage{array, caption, floatrow, tabularx, makecell, booktabs}
\usepackage{multirow}  % span text across multiple rows
\usepackage{rotating}  % to write text vertically in a cell

\begin{document}

\begin{table*}[t]
\centering
\begin{tabular}{c cl c|c|c|c|c}

& & & \multicolumn{5}{c}{Dataset} \\ \cmidrule(lr){4-8}
& & \multicolumn{1}{|l}{Results} & D1 & D2 & D3 & D4 & D5 \\
\cmidrule(lr){2-8}

\multirow{7}{*}{\multicolumn{1}{c|}{
\begin{turn}{90}\makecell{Test Type}\end{turn}}}

& \multirow{4}{*}{
\begin{turn}{90}\makecell{Type 1}\end{turn}}
& \multicolumn{1}{|l}{test 1} & -- & -- & -- & -- & --  \\

&& \multicolumn{1}{|l}{test 2} & -- & -- & -- & -- & --  \\
&& \multicolumn{1}{|l}{test 3} & -- & -- & -- & -- & --  \\
&& \multicolumn{1}{|l}{test 4} & -- & -- & -- & -- & --  \\

\cmidrule(lr){2-8}

& \multirow{2}{*}{
\begin{turn}{90}\makecell{Type 2}\end{turn}}
& \multicolumn{1}{|l}{test ver 1} & -- & -- & -- & -- & --  \\
&& \multicolumn{1}{|l}{test ver 2} & -- & -- & -- & -- & -- \\
\cmidrule(lr){2-8}
\end{tabular}
\caption{Some caption.}
\end{table*}

\end{document}


...the error:

Misplaced \omit.

\multispan ->\omit

@multispan l.18 ...{turn}{90}\makecell{Test Type}\end{turn}}}

I expect to see \omit only after tab marks or the \cr of an alignment. Proceed, and I'll ignore this case

...and what the result looks like:

As you can see, there are two problems:

1. The line under the text "Test Type" (on the leftmost column) should span across rows similarly to the line under "Dataset" (top right). This means it should cover both the headers "Type 1" and "Type 2".
2. The text "Type 2" is too long and falls out of the cell.

Thank you for the help!

G.

• Please make your code compilable by adding the documentclass as well as the relevant package. Where is the turn environment defined? Do you get any error messages from your code? If so, which? Apr 1 '20 at 10:48
• I would not combine horizontal lines from the booktabs package with vertical lines as they are incompatible (see the small white gaps at the intersections). Apr 1 '20 at 10:52
• @leandriis Thank you for the suggestion. I've just updated the question. Could you help me with a solution, please?
– gab
Apr 1 '20 at 11:04
• Your example is not complete, tehre is no document class. And as leandriss says drop the vertical lines. They make the table harder to read anyway. Apr 1 '20 at 11:13
• @daleif I updated the question
– gab
Apr 1 '20 at 11:29

Probably the following is closer to what you wanted to achieve:

\documentclass[journal]{IEEEtran}
\usepackage{multirow}
\usepackage{makecell}
\usepackage{booktabs}
\usepackage{rotating}

\setcellgapes{\tabcolsep}
\begin{document}

\begin{table*}[t]
\centering
\makegapedcells
\caption{Some caption.}
\begin{tabular}{c| cl c|c|c|c|c}

\multicolumn{1}{l}{}& & & \multicolumn{5}{c}{Dataset} \\ \cline{4-8}
\multicolumn{1}{l}{}& & \multicolumn{1}{|l}{Results} & D1 & D2 & D3 & D4 & D5 \\
\cline{2-8}

\multirow{9}{*}{\rotatebox[origin=c]{90}{Test Type}}

& \multirow{6}{*}{\rotatebox[origin=c]{90}{Type 1}}
& \multicolumn{1}{|l}{test 1} & -- & -- & -- & -- & --  \\

&& \multicolumn{1}{|l}{test 2} & -- & -- & -- & -- & --  \\
&& \multicolumn{1}{|l}{test 3} & -- & -- & -- & -- & --  \\
&& \multicolumn{1}{|l}{test 4} & -- & -- & -- & -- & --  \\

\cline{2-8}

& \multirow{2}{*}{
\begin{turn}{90}\makecell{Type 2}\end{turn}}
& \multicolumn{1}{|l}{test ver 1} & -- & -- & -- & -- & --  \\
&& \multicolumn{1}{|l}{test ver 2} & -- & -- & -- & -- & -- \\
\cline{2-8}
\end{tabular}
\end{table*}

\end{document}


Personally I would prefer a different layout:

\documentclass[journal]{IEEEtran}
\usepackage{multirow}
\usepackage{booktabs}
\begin{document}

\begin{table*}[t]
\centering
\caption{Some caption.}
\begin{tabular}{cl ccccc}
& & \multicolumn{5}{c}{Dataset} \\ \cmidrule{3-7}
Test Type & Results & D1 & D2 & D3 & D4 & D5 \\
\midrule
\multirow{4}{*}{Type 1}
& test 1 & -- & -- & -- & -- & --  \\
& test 2 & -- & -- & -- & -- & --  \\
& test 3 & -- & -- & -- & -- & --  \\
& test 4 & -- & -- & -- & -- & --  \\
\midrule
\multirow{2}{*}{Type 2}& test ver 1 & -- & -- & -- & -- & --  \\
& test ver 2 & -- & -- & -- & -- & -- \\
\bottomrule
\end{tabular}
\end{table*}

\end{document}

• thanks for the help :) what "\setcellgapes{\tabcolsep}" and "\makegapedcells" do exactly?
– gab
Apr 1 '20 at 13:25
• Since booktabs horizontal lines are incompatible with vertical lines and you explicitly stated you wanted to keep the latter, I have replaced the former with \hline and \cline. To add some vertical white space around the cells, I have added the \makegapedcells command from the makecell package. With the help of the \setcellgapes command you can set the amount of white space that is added. Currently, the amount of vertical white space is equal to \tabcolsep which is the amount of horizontal white space between the end of the text in a cell and the adjacent vertical line. Apr 1 '20 at 13:32

Here is what I would do. IMO you are making things much too complicated for yourself. As mentioned in the comments no-one used vertical lines anymore

\documentclass[journal]{IEEEtran}

\usepackage{array, caption, floatrow, tabularx, makecell, booktabs}
\usepackage{multirow}  % span text across multiple rows
\usepackage{rotating}  % to write text vertically in a cell

\begin{document}

\begin{table*}[t]
\centering
\begin{tabular}{cl ccccc}
\toprule
&            & \multicolumn{5}{c}{Dataset} \\
\cmidrule{3-7}
& Results    & D1 & D2 & D3 & D4 & D5      \\
\midrule
Type 1 & test 1     & -- & -- & -- & -- & --      \\
& test 2     & -- & -- & -- & -- & --      \\
& test 3     & -- & -- & -- & -- & --      \\
& test 4     & -- & -- & -- & -- & --      \\
\midrule
Type 2 & test ver 1 & -- & -- & -- & -- & --      \\
& test ver 2 & -- & -- & -- & -- & --      \\
\bottomrule
\end{tabular}
\caption{Some caption.}
\end{table*}

\end{document}


• thanks for the help. However, I would need something closer to what I have in my example because of space constraints. In fact, the actual table is more complicated than it is in my example: instead of columns, the vertical lines under "Dataset" separate out subgroups of three columns :)
– gab
Apr 1 '20 at 13:09

With {NiceTabular} of nicematrix.

\documentclass{article}
\usepackage{nicematrix,tikz}

\begin{document}

\renewcommand{\arraystretch}{1.4}
\begin{NiceTabular}{@{}cc|lc|c|c|c|c}
\Block{1-3}{}
&                             &            & \Block[borders=bottom]{1-*}{Dataset} \\
&                             & Results    & D1 & D2 & D3 & D4 & D5 \\
\Block{*-1}{\rotate Test Type}
& \Block{4-1}{\rotate Type 1} & test 1     & -  & -  & -  & -  & -  \\
&                             & test 2     & -  & -  & -  & -  & -  \\
&                             & test 3     & -  & -  & -  & -  & -  \\
&                             & test 4     & -  & -  & -  & -  & -  \\
\Hline
& \Block{2-1}{\rotate Type 2} & test ver 1 & -  & -  & -  & -  & -  \\
&                             & test ver 2 & -  & -  & -  & -  & -  \\
\CodeAfter \tikz \draw (3-|last) -| (last-|2) -- (last-|last) ;
\end{NiceTabular}

\end{document}