[Tex/LaTex] How to cross out a column of Tabular

tables

I know that there is a way to cross out a row of a Tabular, by using \hline. Is there an easy to cross out a column of a Tabular?enter image description here

The picture below is a Tabular, where some of the rows are crossed out. I would love to cross out column.

Best Answer

I once used something like the following code. Because perpendicular lines don't work well in this example I have added different styles to cross out columns.

It can also cross out rows but there I have not implemented different styles.

table-strikethrough.tex:

% ========== settings ==========
\newcommand{\strikethroughcolor}{black!50}
\newcommand{\strikethroughwidth}{.25pt}

\newcommand{\strikethroughCrossWidth}{3em}


% ========== styles ==========
\makeatletter
\newcommand{\strikethroughColumnStylePerpendicular}{\let\@markcol@start=\@markcol@start@perpendicular}
\newcommand{\strikethroughColumnStyleDiagonal}{\let\@markcol@start=\@markcol@start@diagonal}
\newcommand{\strikethroughColumnStyleCounterdiagonal}{\let\@markcol@start=\@markcol@start@counterdiagonal}
\newcommand{\strikethroughColumnStyleCross}{\let\@markcol@start=\@markcol@start@cross}


% ========== preparation ==========
\usepackage{array}
\newcounter{tabularidcounter}
\newif\if@firstcol
% -----  rows -----
\newcounter{tabularlinecounter}
\newcommand*{\setLinesToCross}[1]{%
    \gdef\@lines{#1}%
    \setcounter{tabularlinecounter}{-1}%
    \stepcounter{tabularidcounter}%
}
\newcolumntype{A}{>{%
    \setcounter{tabularcolcounter}{0}%
    \typeout{reset col counter: \thetabularcolcounter}%
    \stepcounter{tabularlinecounter}%
    \@expandtwoargs\in@{,\thetabularlinecounter,}{,\@lines,}%
    \ifin@
        \@marklines@start
    \fi
    \@firstcoltrue
}}
\newcolumntype{Z}{<{%
    \@expandtwoargs\in@{,\thetabularlinecounter,}{,\@lines,}%
    \ifin@
        \@marklines@end
    \fi
}}

% -----  cols -----
\newcounter{tabularcolcounter}
\newcommand*{\setColsToCross}[1]{%
    \gdef\@cols{#1}%
    \stepcounter{tabularidcounter}%
}
\newcommand{\coltop}{%
    \stepcounter{tabularcolcounter}%
    \if@firstcol
        \@marklines@savexleft
    \fi
    \hfill
    \@expandtwoargs\in@{,\thetabularcolcounter,}{,\@cols,}%
    \ifin@
        \@markcol@start
    \fi
    \hfill
    \@marklines@savexright
}
\newcommand{\colbottom}{%
    \stepcounter{tabularcolcounter}%
    \typeout{step col counter: \thetabularcolcounter}%
    \@expandtwoargs\in@{,\thetabularcolcounter,}{,\@cols,}%
    \ifin@
        \@markcol@end
    \fi
}


% ========== implementation ==========
\usepackage{tikz}
\usetikzlibrary{tikzmark}
% -----  rows -----
\newcommand*\@marklines@savexleft{%
    \pgfmark{tab\thetabularidcounter-rowstart-x}%
}
\newcommand*\@marklines@savexright{%
    \pgfmark{tab\thetabularidcounter-rowend-x}%
}
\newcommand*\@marklines@start{%
    \tikz[remember picture,overlay]
        \draw[yshift=.65ex, draw=\strikethroughcolor, line width=\strikethroughwidth] ({pic cs:tab\thetabularidcounter-rowstart-x} |- 0, 0) -- 
            ({pic cs:tab\thetabularidcounter-rowend-\thetabularlinecounter} -| {pic cs:tab\thetabularidcounter-rowend-x});%
}
\newcommand*\@marklines@end{%
    \pgfmark{tab\thetabularidcounter-rowend-\thetabularlinecounter}%
}

% -----  cols -----
\newcommand*\@markcol@start@perpendicular{%
    \tikz[remember picture,overlay]
        \draw[draw=\strikethroughcolor, line width=\strikethroughwidth] (0, .6em) -- ([yshift=-.2em] pic cs:tab\thetabularidcounter-colend-\thetabularcolcounter);%
}
\newcommand*\@markcol@start@diagonal{%
    \tikz[remember picture,overlay]
        \draw[draw=\strikethroughcolor, line width=\strikethroughwidth] (-\strikethroughCrossWidth/2, .6em) -- ([yshift=-.2em, xshift=\strikethroughCrossWidth/2] pic cs:tab\thetabularidcounter-colend-\thetabularcolcounter);%
}
\newcommand*\@markcol@start@counterdiagonal{%
    \tikz[remember picture,overlay]
        \draw[draw=\strikethroughcolor, line width=\strikethroughwidth] (\strikethroughCrossWidth/2, .6em) -- ([yshift=-.2em, xshift=-\strikethroughCrossWidth/2] pic cs:tab\thetabularidcounter-colend-\thetabularcolcounter);%
}
\newcommand*\@markcol@start@cross{%
    \begin{tikzpicture}[remember picture,overlay]
        \draw[draw=\strikethroughcolor, line width=\strikethroughwidth] (-\strikethroughCrossWidth/2, .6em) -- ([yshift=-.2em, xshift=\strikethroughCrossWidth/2] pic cs:tab\thetabularidcounter-colend-\thetabularcolcounter);%
        \draw[draw=\strikethroughcolor, line width=\strikethroughwidth] (\strikethroughCrossWidth/2, .6em) -- ([yshift=-.2em, xshift=-\strikethroughCrossWidth/2] pic cs:tab\thetabularidcounter-colend-\thetabularcolcounter);%
    \end{tikzpicture}%
}
\newcommand*\@markcol@end{%
    \pgfmark{tab\thetabularidcounter-colend-\thetabularcolcounter}%
}


% ========== first row & last row ==========
\usepackage{booktabs}
\usepackage{multido}
\usepackage{etoolbox}

\newcommand{\stTableStart}[1]{%
    \def\tmp@tmprow{}%
    % I can't use pgffor's \foreach here because there each iteration is executed in a different group.
    \Multido{}{\number\numexpr #1-1\relax}{%
        \appto\tmp@tmprow{{\coltop} &}%
    }%
    \appto\tmp@tmprow{{\coltop}}%
    \tmp@tmprow \\[-1.2em]
    \toprule
}
\newcommand{\stTableEnd}[1]{%
    \\[-2.4em]%
    \def\tmp@tmprow{}%
    \Multido{}{\number\numexpr #1-1\relax}{%
        \appto\tmp@tmprow{{\colbottom} &}%
    }%
    \appto\tmp@tmprow{{\colbottom}}%
    \tmp@tmprow \\
    \bottomrule
}
%TODO: retrieve number of columns, then the parameter is not needed anymore
\newenvironment{strikethroughtable}[3][c]{% [#1: align], #2: col spec, #3: num cols
    \edef\strikethroughtable@numberofcolumns{#3}%
    \begin{tabular}[#1]{A #2 Z}%
        \stTableStart{\strikethroughtable@numberofcolumns}%
}{%
        \stTableEnd{\strikethroughtable@numberofcolumns}%
    \end{tabular}%
    \setLinesToCross{}%
    \setColsToCross{}%
}
\makeatother


% ========== init ==========
\strikethroughColumnStylePerpendicular
\setLinesToCross{}
\setColsToCross{}

main.tex:

\documentclass{article}

\input{table-strikethrough}
\usepackage{siunitx}

\usepackage{tikz}

\newcolumntype{m}[1]{ >{$} #1 <{$}}
\newcolumntype{~}{!{\quad}}

\begin{document}
\setColsToCross{5,7}
\strikethroughColumnStyleDiagonal
\begin{strikethroughtable}{mr @{} S[table-format=3.0]  *6{S[table-format=2.0]}}{8}
    \multicolumn{2}{c}{} & \multicolumn{1}{c}{$m_1=75$} & \multicolumn{1}{c}{$m_2=100$} & \multicolumn{1}{c}{$m_3=50$} & \multicolumn{1}{c}{$m_4=125$} & \multicolumn{1}{c}{$m_5=85$} & \multicolumn{1}{c}{$m_6=145$} \\
    \midrule
    a_1={} & 85 &   0 &  0 & 0 & 10 &  0 & 25 \\
    a_2={} & 95 &   0 &  0 & 0 & 20 &  0 & 35 \\
    a_3={} &100 &   0 &  0 & 0 & 25 &  0 & 40 \\
    a_4={} &150 &  25 & 50 & 0 & 75 & 35 & 90 \\
    a_5={} &140 &  15 & 40 & 0 & 65 & 25 & 80 \\
    a_6={} & 60 &   0 &  0 & 0 &  0 &  0 &  0 \\
\end{strikethroughtable}
\end{document}

The two files should be located in the same directory.

enter image description here

I have formatted the table in compliance with the recommendations from the booktabs package (section 2 The layout of formal tables, page 3):

You will not go far wrong if you remember two simple guidelines at all times:

  1. Never, ever use vertical rules.
  2. Never use double rules.

Also I have used siunitx' S column type to align the numbers.

You can customize the visual appearance by redefining the following commands:

  • \strikethroughcolor
  • \strikethroughwidth
  • \strikethroughCrossWidth

or calling the following commands:

  • \strikethroughColumnStylePerpendicular
  • \strikethroughColumnStyleDiagonal
  • \strikethroughColumnStyleCounterdiagonal
  • \strikethroughColumnStyleCross

I have seen your comment that you just want to cross out the column $m_3=50$ but I have crossed out one more just to show how easy it would be to cross out more.

Please note that I have splitted up the first column in two to align the numbers therefore the column indices differ from what one might expect at first glance.

Adding something visual to every row (like with \newcolumntype{=}{@{${}={}$}} which would have been great here) would not deliver the desired output because I am adding an invisible row above and below where it would then appear, too.

Related Question