# Mathematical functions inside LaTeX tables

I have several tables where I have tables which may look like this:

-------------------------------------
| X | Y | X + Y | X - Y | (X + Y)/2 |
-------------------------------------
|   |   |       |       |           |
|   |   |       |       |           |
|   |   |       |       |           |
-------------------------------------


I mean X, Y are the data and columns 3, 4, 5 are derived from X and Y.

Typing in contents of column 3, 4, 5 are subject to human error and mistakes (can be embarrassing). I was looking to get an idea as to how you solve this problem in LaTeX tables. Is there a package capable of doing this?

When you copy-paste an Excel table, there is very little scope for such errors. Is something similar possible in LaTeX?

One way to do this would be to use pgfplotstable as in the example that follows. If you need to do more complex analysis, you can create a csv file that can be editted in excel and imported using pgfplotstable or datatool package. You will find quite a few examples of it under datatool and pgfplotstable tag.

\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}


The following example adds some more eye-candy and illustrates how to import data from a file.

\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}


• It would be nice if you could change the alignment in the last column. I am sure siunitx or dcolumn could help here but if it can be done with pgfplotstabble (only) then that'd be nicer. – user10274 Oct 13 '12 at 5:20
• @MarcvanDongen this can be done by adding dec sep align to corresponding column style. I have added an example to the answer. – mythealias Oct 13 '12 at 7:26

An example using the spreadtab package:

\documentclass{article}
\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{document}


• very nice, but would look even nicer if the headers for the last three columns were more centered over the column contents. – barbara beeton Oct 13 '12 at 12:25

This can also be accomplished using the collcell package which allows one to intercept each of the data elements from tabular/array for further processing.

## Notes:

• I used array below as the material was all math. This could just as easily have been tabular.

• I have used newtoggle from the etoolbox package as I prefer that syntax versus the \newif syntax. But if you don't want to include an additional package it should be pretty straightforward to adapt this to use \newif or some other conditional methods.

• The pgf package package was used for math processing but any method of computing the values you need would work. Note that pgf uses degrees for the trignometric functions by default. Apply the rad() function if that is not desired: sin(rad(<value>)).

## Code:

\documentclass{article}

\usepackage{amsmath}
\usepackage{etoolbox}% for toggles
\usepackage{collcell}
\usepackage{xifthen}
\usepackage{pgf}% for math

\newcommand{\ColumnXData}{}
\newcommand{\ColumnYData}{}
\newcommand*{\ComputeColumnA}[1]{}%

% Automatically reset this toggle at the end of the array
\let\OldEndArray\endarray

% 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]{%
\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}

• +1, I like the way you used collcell in combination with a “toggle”. But why do you use \ComputeColumn?{#1}? The \Compute* macros don't have an argument and in those columns #1 are empty anyway. In fact, you can remove {#1} entirely from those columns. For efficiency and clarity I'd use \ifcase: \ifcase\value{ColumnCount}\xdef\ColumnXData{#1}#1\or\xdef\ColumnYData{#1}#1\or\ComputeColumnU\or\ComputeColumnV\or\ComputeColumnW\setcounter{ColumnCount}{-1}\fi\stepcounter{ColumnCount} – Qrrbrbirlbel Nov 27 '12 at 1:25
• Thanks. Have updated solution to eliminate the unused #1. – Peter Grill Nov 27 '12 at 1:36