3

I am trying to transpose a table. I have tried the example given in this answer and it works. However, when I try more than 5 rows (which when transposed become columns), it throws an error as follows: "Package datatool Error: Can't assign \Gg : there is no key G in data base TransposedTabularDB." Here is the MWE:

\documentclass{article}
\usepackage{collcell}
\usepackage{xstring}
\usepackage{datatool}
\usepackage{booktabs}
\usepackage{environ}
%\usepackage{showframe}

\def\Midrule{\midrule[\heavyrulewidth]}

\newcounter{CurrentRow}% = column of transposed table \newcounter{CurrentColumn} \setcounter{CurrentColumn}{0} \newtoggle{DoneWithFirstRow}

\newlength{\WidthAdjustment} \newcommand{\FirstColumn}[1]{% \IfEq{\arabic{CurrentColumn}}{0}{% % This is the start of the very first data entry in first row. \global\togglefalse{DoneWithFirstRow}% \setcounter{CurrentRow}{1}% initial value }{% % We have already completed a row. Now starting a new row. \global\toggletrue{DoneWithFirstRow}% \stepcounter{CurrentRow}% }% \setcounter{CurrentColumn}{0}% \NewData{#1}% } \newcommand{\NewData}[1]{% \dtlexpandnewvalue% \stepcounter{CurrentColumn}% \iftoggle{DoneWithFirstRow}{% \dtlgetrow{TransposedTabularDB}{\arabic{CurrentColumn}}% \dtlappendentrytocurrentrow{\Alph{CurrentRow}}{#1}% \dtlrecombine% }{% \DTLnewrow{TransposedTabularDB}% \DTLnewdbentry{TransposedTabularDB}{\Alph{CurrentRow}}{#1}% }% }%

\newcolumntype{F}{>{\collectcell\FirstColumn}c<{\endcollectcell}} \newcolumntype{C}{>{\collectcell\NewData}{c}<{\endcollectcell}}

%% No longer needed since we switched to NewEnviron %% https://tex.stackexchange.com/questions/12234/how-do-i-expand-a-macro-into-a-tabular-head %\newcommand{\SaveColumnSpecificationAsZ}[1]{\newcolumntype{Z}{#1}}

\newtoggle{EncounteredDataRow}

\newsavebox{\TempBox} \DTLnewdb{TransposedTabularDB}

\NewEnviron{Ttabular}[1]{% %\SaveColumnSpecificationAsZ{#1}% % Initialize in case of multiple uses \setcounter{CurrentColumn}{0}% \global\togglefalse{EncounteredDataRow}% \savebox{\TempBox}{% \begin{tabular}{FCCCCCC}% over speced tabular \BODY% \end{tabular}% }% \begin{tabular}{#1}\toprule% % This could be made smarter to detect number of columns \DTLforeach*{TransposedTabularDB}{\Aa=A, \Ba=B, \Ca=C, \Dd=D, \Ee=E, \Ff = F}{% \DTLiffirstrow{}{\\midrule}%
\Aa & \Ba & \Ca & \Dd & \Ee & \Ff% }\\bottomrule% \end{tabular}% }%

\begin{document} \noindent \begin{Ttabular}{cccccc} \bfseries Name & Alice & Bob & Chuck & Dave & Eve\ \bfseries Sex & Female & Male & Male & Male & Female\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \end{Ttabular}

\bigskip\noindent Which I want to look like \bigskip

\noindent \begin{tabular}{*3c}\toprule \bfseries Name & \bfseries Sex & \bfseries Age\\Midrule Alice & Female & 18\\midrule Bob & Male & 19\\midrule Chuck & Male & 20\\midrule Dave & Male & 21\\midrule Eve & Female & 22\\bottomrule \end{tabular} \end{document}

Could please help me input more than 5 rows in the input when transposing the table? Thanks.

honeybadger
  • 165
  • 4

2 Answers2

2

You have extra spaces in \Ff = F that need removal. Should be \Ff=F.

\documentclass{article}
\usepackage{collcell}
\usepackage{xstring}
\usepackage{datatool}
\usepackage{booktabs}
\usepackage{environ}
%\usepackage{showframe}

\def\Midrule{\midrule[\heavyrulewidth]}

\newcounter{CurrentRow}% = column of transposed table \newcounter{CurrentColumn} \setcounter{CurrentColumn}{0} \newtoggle{DoneWithFirstRow}

\newlength{\WidthAdjustment} \newcommand{\FirstColumn}[1]{% \IfEq{\arabic{CurrentColumn}}{0}{% % This is the start of the very first data entry in first row. \global\togglefalse{DoneWithFirstRow}% \setcounter{CurrentRow}{1}% initial value }{% % We have already completed a row. Now starting a new row. \global\toggletrue{DoneWithFirstRow}% \stepcounter{CurrentRow}% }% \setcounter{CurrentColumn}{0}% \NewData{#1}% } \newcommand{\NewData}[1]{% \dtlexpandnewvalue% \stepcounter{CurrentColumn}% \iftoggle{DoneWithFirstRow}{% \dtlgetrow{TransposedTabularDB}{\arabic{CurrentColumn}}% \dtlappendentrytocurrentrow{\Alph{CurrentRow}}{#1}% \dtlrecombine% }{% \DTLnewrow{TransposedTabularDB}% \DTLnewdbentry{TransposedTabularDB}{\Alph{CurrentRow}}{#1}% }% }%

\newcolumntype{F}{>{\collectcell\FirstColumn}c<{\endcollectcell}} \newcolumntype{C}{>{\collectcell\NewData}{c}<{\endcollectcell}}

%% No longer needed since we switched to NewEnviron %% https://tex.stackexchange.com/questions/12234/how-do-i-expand-a-macro-into-a-tabular-head %\newcommand{\SaveColumnSpecificationAsZ}[1]{\newcolumntype{Z}{#1}}

\newtoggle{EncounteredDataRow}

\newsavebox{\TempBox} \DTLnewdb{TransposedTabularDB}

\NewEnviron{Ttabular}[1]{% %\SaveColumnSpecificationAsZ{#1}% % Initialize in case of multiple uses \setcounter{CurrentColumn}{0}% \global\togglefalse{EncounteredDataRow}% \savebox{\TempBox}{% \begin{tabular}{FCCCCCC}% over speced tabular \BODY% \end{tabular}% }% \begin{tabular}{#1}\toprule% % This could be made smarter to detect number of columns \DTLforeach*{TransposedTabularDB}{\Aa=A, \Ba=B, \Ca=C, \Dd=D, \Ee=E, \Ff=F}{% \DTLiffirstrow{}{\\midrule}%
\Aa & \Ba & \Ca & \Dd & \Ee & \Ff% }\\bottomrule% \end{tabular}% }%

\begin{document} \noindent \begin{Ttabular}{cccccc} \bfseries Name & Alice & Bob & Chuck & Dave & Eve\ \bfseries Sex & Female & Male & Male & Male & Female\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \bfseries Age & 18 & 19 & 20 & 21 & 22\ \end{Ttabular}

\bigskip\noindent Which I want to look like \bigskip

\noindent \begin{tabular}{*3c}\toprule \bfseries Name & \bfseries Sex & \bfseries Age\\Midrule Alice & Female & 18\\midrule Bob & Male & 19\\midrule Chuck & Male & 20\\midrule Dave & Male & 21\\midrule Eve & Female & 22\\bottomrule \end{tabular} \end{document}

enter image description here

1

Use the package pgfplotstable for this type of transformation, much simpler.

texdoc pgfplotstable 

to read the manual (see page 63)

Short example below:

\documentclass{article}
\usepackage{pgfplotstable}
\begin{filecontents*}{example3.dat}
a b c d
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
16 17 18 19
20 21 22 23
\end{filecontents*}
\begin{document}
\pgfplotstabletypeset[string type]{example3.dat}

\pgfplotstabletranspose\loadedtable{example3.dat} \pgfplotstabletypeset[string type]\loadedtable \end{document}

yannisl
  • 117,160