我正在尝试转置一个表格。我尝试过这个答案G
并且它有效。但是,当我尝试超过 5 行(转置后变为列)时,它会抛出以下错误:“Package datatool 错误:无法分配 \Gg:数据库中没有密钥TransposedTabularDB
。”这是 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}
转置表格时,能否帮我输入超过 5 行的内容?谢谢。
答案1
有多余的空格\Ff = F
需要删除。应该是\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}
答案2
使用包pgfplotstable对于这种类型的转换,要简单得多。
texdoc pgfplotstable
阅读手册(参见第 63 页)
以下是简短的示例:
\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}