我有几个表格,其中的表格可能如下所示:
-------------------------------------
| X | Y | X + Y | X - Y | (X + Y)/2 |
-------------------------------------
| | | | | |
| | | | | |
| | | | | |
-------------------------------------
我的意思是 X、Y 是数据,第 3、4、5 列来自 X 和 Y。
输入第 3、4、5 列的内容可能会出现人为错误和失误(可能会很尴尬)。我想知道如何在 LaTeX 表格中解决这个问题。有没有可以做到这一点的软件包?
当您复制粘贴 Excel 表格时,出现此类错误的可能性很小。在 LaTeX 中是否也会出现类似情况?
答案1
一种方法是使用pgfplotstable
下面的示例。如果您需要进行更复杂的分析,您可以创建一个 csv 文件,该文件可以在 excel 中编辑并使用pgfplotstable
或datatool
包导入。您将在下面找到很多示例datatool
和pgfplotstable
标签。
\documentclass{article}
\usepackage{pgfplotstable}
\begin{document}
\pgfplotstableread[col sep = comma]{
x,y,
1,6,
2,4,
3,5,
4,7,
5,8,
} \data
\begin{table}
\pgfplotstableset{create on use/a/.style={create col/expr={\thisrow{x}+\thisrow{y}}}}
\pgfplotstableset{create on use/b/.style={create col/expr={\thisrow{x}-\thisrow{y}}}}
\pgfplotstableset{create on use/c/.style={create col/expr={(\thisrow{x}+\thisrow{y})/2}}}
\pgfplotstabletypeset[columns={x,y,a,b,c},
columns/x/.style={column name={$x$}, column type={c}, },
columns/y/.style={column name={$y$}, column type={c}, },
columns/a/.style={column name={$x+y$}, column type={c}, },
columns/b/.style={column name={$x-y$}, column type={c}, },
columns/c/.style={column name={$(x+y)/2$}, column type={c}, },
]{\data}
\end{table}
\end{document}
下面的示例更加引人注目,并说明了如何从文件导入数据。
\documentclass{article}
\usepackage{pgfplotstable} % Typeset table and manipulate column entries
\usepackage{booktabs} % Nicer horizontal rules for tables
%\usepackage{array} % To align column entries by decimal separator
\usepackage{filecontents} % To illustrate importing data from external file
\begin{filecontents*}{data.csv} % Sample contents of data.csv file
x, y,
1, 6,
2, 4,
3, 5,
4, 7,
5, 8,
4.4, 7,
512, 81,
\end{filecontents*}
\pgfplotstableread[col sep = comma]{data.csv}\data
\begin{document}
\begin{table}[h]
\pgfplotstableset{create on use/a/.style={create col/expr={ \thisrow{x}+\thisrow{y}}}}
\pgfplotstableset{create on use/b/.style={create col/expr={ \thisrow{x}-\thisrow{y}}}}
\pgfplotstableset{create on use/c/.style={create col/expr={(\thisrow{x}+\thisrow{y})/2}}}
\pgfplotstabletypeset%
[columns={x,y,a,b,c},
every head row/.style={before row=\toprule, after row=\midrule},
every nth row={5}{before row=\midrule},
every last row/.style={after row=\bottomrule},
columns/x/.style={column name={$x$}, dec sep align},
columns/y/.style={column name={$y$}, dec sep align},
columns/a/.style={column name={$x+y$}, dec sep align},
columns/b/.style={column name={$x-y$}, dec sep align},
columns/c/.style={column name={$\frac{x+y}{2}$}, dec sep align},
]{\data}
\end{table}
\end{document}
答案2
使用的示例spreadtab
包裹:
\documentclass{article}
\usepackage{spreadtab}
\usepackage{array}
\usepackage{booktabs}
\usepackage{amsmath}
\begin{document}
\noindent\begin{spreadtab}{{tabular}{*{5}{>{$}r<{$}}}}
\toprule
@x & @y & @x+y & @x-y & @\dfrac{x+y}{2}\\
\midrule
1 & 2 & \STcopy{>1,v4}{!a2+b2} & \STcopy{>1,v4}{!a2-b2} & \STcopy{>1,v4}{!(a2+b2)/2} \\
3 & 2 & & & \\
-3 & -6 & & & \\
9 & -2 & & & \\
10 & 5 & & & \\
\bottomrule
\end{spreadtab}
\end{document}
答案3
这也可以使用包裹collcell
它允许人们拦截来自tabular
/的每个数据元素array
以进行进一步处理。
笔记:
我使用了
array
以下方法,因为材料都是数学。这也可以很容易地实现tabular
。我已经使用
newtoggle
过包裹etoolbox
因为我更喜欢那个语法而不是\newif
语法。但如果你不想包含额外的包,那么调整它以使用\newif
或其他一些条件方法。包裹
pgf
包用于数学处理,但任何计算所需值的方法都可以。请注意,pgf
默认情况下,使用度作为三角函数。rad()
如果不需要,请应用函数:sin(rad(<value>))
。
代码:
\documentclass{article}
\usepackage{amsmath}
\usepackage{etoolbox}% for toggles
\usepackage{collcell}
\usepackage{xifthen}
\usepackage{pgf}% for math
\newcommand{\ColumnXData}{}
\newcommand{\ColumnYData}{}
\newcommand*{\ComputeColumnA}[1]{}%
\newtoggle{DoneWithHeader}
\togglefalse{DoneWithHeader}
\newcommand{\DoneWithHeader}{\global\toggletrue{DoneWithHeader}}
% Automatically reset this toggle at the end of the array
\let\OldEndArray\endarray
\def\endArray{\global\togglefalse{DoneWithHeader}\OldEndArray}
% Define the operations for the various columns.
\newcommand*{\FormatNumber}[2][]{\pgfmathprintnumber[precision=5,#1]{#2}}
\newcommand*{\ComputeColumnU}{%
\pgfmathparse{\ColumnXData + \ColumnYData}%
\FormatNumber{\pgfmathresult}%
}%
\newcommand*{\ComputeColumnV}{
\pgfmathparse{(\ColumnXData)^2 + 3*(\ColumnYData)}%
\FormatNumber{\pgfmathresult}%
}%
\newcommand*{\ComputeColumnW}{%
\pgfmathparse{sin(\ColumnXData + \ColumnYData)}%
\FormatNumber{\pgfmathresult}%
}%
\newcounter{ColumnCount}
\newcommand*{\SetColumnData}[1]{%
\iftoggle{DoneWithHeader}{%
\stepcounter{ColumnCount}
% This could clearly be made more efficient but is easier to read this way
\ifthenelse{\arabic{ColumnCount}=1}{\xdef\ColumnXData{#1}#1}{}
\ifthenelse{\arabic{ColumnCount}=2}{\xdef\ColumnYData{#1}#1}{}
\ifthenelse{\arabic{ColumnCount}=3}{\ComputeColumnU}{}
\ifthenelse{\arabic{ColumnCount}=4}{\ComputeColumnV}{}
\ifthenelse{\arabic{ColumnCount}=5}{\ComputeColumnW\setcounter{ColumnCount}{0}}{}
% Note that in the above we wsed the fact that column `W` is last
% to reset the column counter so that for the next row we know
% which are the data columns. If this won't always be the case
% you could manually \setcounter{ColumnCount}{0} at the end of each row.
}{%
#1%
}%
}%
\newcolumntype{C}{>{\collectcell\SetColumnData}{c}<{\endcollectcell}}
\newcolumntype{L}{>{\collectcell\SetColumnData}{l}<{\endcollectcell}}
\newcolumntype{R}{>{\collectcell\SetColumnData}{r}<{\endcollectcell}}
\begin{document}
$
\begin{array}{C C C C L}
x & y & x + y & x^2+3y & \sin (x+y) \DoneWithHeader \\
10 & 20 & & & \\
20 & 40 & & & \\
\end{array}
$
\end{document}