# Control order of columns in table

Is there maybe a way to define the order of columns oneself?

Say I have

\begin{tabular}{ l l l }
A1 & C1 & B1 \\
A2 & C2 & B2 \\
A3 & C3 & B3 \\
\end{tabular}


but really want

\begin{tabular}{ l l l }
A1 & B1 & C1 \\
A2 & B2 & C2 \\
A3 & B3 & C3 \\
\end{tabular}


and would like to avoid having to move all the content.

-
If this is a sometime thing, it's probably fastest to do this in a spreadsheet and then paste it back into your document. If it's a more general thing, then maybe you need something more like the datatool which manipulate CSV data. –  Alan Munn Mar 20 '11 at 0:09

Using @MartinScharrer's rather new collcell package, we can collect the body of each cell and save it with a given label, then typeset the cells in a different order, calling each label. Namely, the code below defines two column types: s{<label>} (for save) and o{<label>} (for output).

One drawback is that you need to put a whole bunch of & at the end of each line to allow typesetting to occur (as many & as you have columns). This can also be used to e.g. double one column, or remove one column.

\documentclass{article}
\usepackage{collcell}
\usepackage{array}

\newcommand{\newcelltoksifnew}[1]{%
\expandafter\ifx\csname cell@toks@#1\endcsname\relax
\expandafter\newtoks\csname cell@toks@#1\endcsname
\fi}
\newcolumntype{s}[1]{%
>{\unskip\newcelltoksifnew{#1}%
\collectcell{\global\csname cell@toks@#1\endcsname}}%
c%
<{\endcollectcell}%
@{}%
}
\newcolumntype{o}[1]{%
>{\the\csname cell@toks@#1\endcsname}%
c%
}

\begin{document}
\begin{table}\centering
\begin{tabular}{|c|c|c|}
a  &  c  &  b  \\
AAAAA&CCCCC&BBBBB
\end{tabular}

\begin{tabular}{s{A}s{B}s{C}|o{A}|o{C}|o{B}|}
a  &  b  &  c  &&&\\
AAAAA&BBBBB&CCCCC&&&
\end{tabular}
\caption{Comparing two tables to see that the spacing is not affected.}
\end{table}

\end{document}

-
Nice idea and implementation! However with simple cells saveboxes could also be used to transfer the content. This would be more efficient then using collcell. –  Martin Scharrer Mar 20 '11 at 11:57
Very interesting! I wonder why \newcommand{\as}{&&&} cannot be used to create the many &s at the end of each row... –  Frank Seifert Mar 20 '11 at 15:56
@Frank: because collcell would think that \as is part of the content of the cell that it needs to grab. It should be possible to use \newcomand{\amps}{&&} and then &\amps at the end of each line, but that does not seem very nice. –  Bruno Le Floch Mar 20 '11 at 21:31
@Martin: you are probably right on using savebox, but I have no experience with boxes, so I wouldn't think about that. –  Bruno Le Floch Mar 20 '11 at 21:32
FYI, didn't have luck with &\amps –  Frank Seifert Mar 21 '11 at 1:16

Using the idea from the first solution, but without using collcell:

\def\CollectArg#1\EndCollectArg{\def\StoredContent{#1}}
\newcolumntype{s}[1]{>{\unskip\CollectArg}c%
<{\EndCollectArg\expandafter\global\expandafter\let\csname StoredColumn#1\endcsname\StoredContent}%
@{}}
\newcolumntype{o}[1]{>{\csname StoredColumn#1\endcsname}c}


(of course, this requires package array, otherwise newcolumntype is not defined). Typesetting itself is the same as in the first solution.

-

Another method would be to swap to column using a string manipulation package, let's say xstring ;). Of course, swapping 2 columns is not reorder all of them!

The \swapcol command must be written at the begining of every row in which you want to swap the content of 2 cells. The last row must be ended with a \\.

Here is the tricky code:

\documentclass[a4paper]{article}
\usepackage{xstring}
\usepackage{array}
\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
#1\expandafter\expandafter\expandafter{\expandafter#1#2}}
\def\swapcol#1#2#3\\{%
\ifnum#1>#2 \def\colinf{#2}\def\colsup{#1}%
\else \def\colinf{#1}\def\colsup{#2}\fi
\noexpandarg \let\swaprow\empty \iffalse{\fi\ifnum0=}\fi
\expandafter\StrBefore\expandafter[\number\numexpr\colinf-1]{#3&}&[\beforecol]%
\StrBehind[\colinf]{&#3&}&[\aftercol]%
\expandafter\StrBefore\expandafter{\aftercol}&[\colA]%
\expandafter\StrBehind\expandafter{\aftercol}&[\aftercol]%
\expandafter\StrBefore\expandafter[\number\numexpr\colsup-\colinf-1\expandafter]\expandafter{\aftercol}&[\intercol]%
\StrBehind[\colsup]{&#3}&[\aftercol]%
\expandafter\StrBefore\expandafter{\aftercol&}&[\colB]%
\expandafter\StrBehind\expandafter{\aftercol}&[\aftercol]%
\ifnum0={\fi\iffalse}\fi \swaprow}

\begin{document}
\begin{tabular}{ccccc}
1 & 2 & 3 & 4 & 5 \\
1 & 2 & 3 & 4 & 5 \\
1 & 2 & 3 & 4 & 5 \\
\end{tabular}
\begin{tabular}{ccccc}
\swapcol{2}{5}1 & 2 & 3 & 4 & 5 \\
\swapcol{2}{5}1 & 2 & 3 & 4 & 5 \\
\swapcol{2}{5}1 & 2 & 3 & 4 & 5 \\
\end{tabular}

\begin{tabular}{|c|c|c|}
a  &  c  &  b  \\
AAAAA&CCCCC&BBBBB
\end{tabular}