Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to achieve the following: I want to access a number from a table in the main text and make some calculations with it. For example, if there is a value 1.85 in the table I want to store it under a variable name and be able to call it in the main text which then generates 1.85.

The MWE below shows some code kindly provided by egreg that stores a value from a table under a command name. This works quite well if I "hard code" the label manually into the table. The problem is that tables are automatically generated so I can't write \setvalue{\ValueA}{20} in the table because it would disappear the next time the table is generated.

The layout of the table hardly ever changes, only the numbers change. So what I would need is some "grid search" that takes the value from a cell that I have manually specified and wraps it automatically into egregs code, e.g. The value is \setvalue\ValueC{mytable.tex}{2}{7} would access column 2, row 7 of mytable. Is something like that possible, or are there better solutions?

Another issue is that I can't access values before the table has been included (see the first commented line). I guess one possible solution would be to put all tables into an insivible box at the beginning of the document, but maybe there a better ways.

The MWE below shows how tables generated by Stata's estout typically look like. mytable.tex only contains the bare content of the table which is then wrapped into the table environment by the \estauto command.

\documentclass{scrartcl}

\usepackage{booktabs,filecontents,lmodern,calculator,siunitx}

\sisetup{round-mode=places,round-precision=2}

\makeatletter
\newcommand{\setvalue}[2]{%
  \@ifdefinable{#1}{\gdef#1{#2}}#2
}
\makeatother

\DeclareRobustCommand{\estauto}[3]{%
 \vspace{.75ex}{%
 \begin{tabular}{l*{#2}{#3}}%
 \toprule%
 #1%
 \bottomrule%
 \addlinespace[.75ex]%
 \end{tabular}%
 }
}

\begin{filecontents}{mytable.tex}
                          & \multicolumn{1}{c}{(1)}   & \multicolumn{1}{c}{(2)}   & \multicolumn{1}{c}{(3)}   \\
\midrule
\emph{First Control Set}  &                           &                           &                           \\
Variable 1                & \setvalue{\ValueA}{1.85}  & \setvalue{\ValueB}{0.92}  & 1.11                      \\
                          & (0.34)                    & (0.24)                    & (0.14)                    \\
Variable 2                & 0.07                      & 0.07                      & 0.07                      \\
                          & (0.01)                    & (0.02)                    & (0.01)                    \\
Variable 3                & -0.02                     & -0.01                     & -0.01                     \\
                          & (0.01)                    & (0.00)                    & (0.00)                    \\
\end{filecontents}

\begin{document}
% This does not work because it calls the value before the table is included (\ValueA).

\begin{table}\centering\footnotesize
    \caption{Consumer Credit Portfolios for Borrowers}
    \label{tab:portfolio}
    \estauto{\input{mytable.tex}}{3}{c}
\end{table}

This does work and the value is of Variable 1 in (1) is \ValueA{} and in
(2) \ValueB{}. %The spacing is not correct after the values are called.

Let's try some maths: The difference of (1) and (2) of Variable 1 is
\SUBTRACT{\ValueA}{\ValueB}\DiffAB \num{\DiffAB}
% package calculator also has a round option, but I don't really understand the syntax

\end{document}

enter image description here

share|improve this question
4  
Our first egreg tag... –  Werner Nov 28 '12 at 17:17
    
@Jörg: now you should find something appropriate for the tag summary... ;) –  Claudio Fiandrino Nov 28 '12 at 17:21
    
Considering Stack Overflow doesn't even have a Jon Skeet tag, I'm not sure we should have an egreg one ..? –  doncherry Nov 28 '12 at 18:20
    
@doncherry, StefanKottwitz: I agree. The janitorial staff have spoken... –  Werner Nov 28 '12 at 20:21
    
This begs for pgfplotstable :) –  percusse Nov 28 '12 at 22:07
add comment

2 Answers 2

up vote 7 down vote accepted

I don't have the calculator package but this defines expandable macros with each of the cell contents.

enter image description here

\documentclass{scrartcl}

\usepackage{array,booktabs,filecontents,lmodern,siunitx}

\sisetup{round-mode=places,round-precision=2}

\makeatletter
\newcommand{\setvalue}[2]{%
  \@ifdefinable{#1}{\gdef#1{#2}}#2
}

\newcount\rowc
\newcount\colc
\def\xsavedata{%
}

\long\def\savedata#1{%
\setbox0\vbox\bgroup
\let\\\cr
\tracingall
\let\midrule\@empty
\let\multicolumn\@gobbletwo
\everyeof{\noexpand}%
\halign\bgroup
\global\colc\z@
\global\advance\rowc\@ne\@gobble{##}&&%
\global\advance\colc\@ne
\expandafter\xdef\csname data-#1(\the\rowc,\the\colc)\endcsname
{\zap@space## \@empty}\cr
\@@input #1 
\crcr\egroup\egroup}

\def\usedata#1#2{%
\csname data-#1(#2)\endcsname}

\makeatother


\DeclareRobustCommand{\estauto}[3]{%
 \vspace{.75ex}{%
 \begin{tabular}{l*{#2}{#3}}%
 \toprule%
 #1%
 \bottomrule%
 \addlinespace[.75ex]%
 \end{tabular}%
 }
}

\begin{filecontents}{mytable.tex}
                          & \multicolumn{1}{c}{(1)}   & \multicolumn{1}{c}{(2)}   & \multicolumn{1}{c}{(3)}   \\
\midrule
\emph{First Control Set}  &                           &                           &                           \\
Variable 1                &  1.85                     & 0.92                      & 1.11                      \\
                          & (0.34)                    & (0.24)                    & (0.14)                    \\
Variable 2                & 0.07                      & 0.07                      & 0.07                      \\
                          & (0.01)                    & (0.02)                    & (0.01)                    \\
Variable 3                & -0.02                     & -0.01                     & -0.01                     \\
                          & (0.01)                    & (0.00)                    & (0.00)                    \\
\end{filecontents}

\begin{document}
%
\savedata{mytable.tex}


 This does not work because it calls the value before the table is included (\usedata{mytable.tex}{3,3}).

\begin{table}\centering\footnotesize
    \caption{Consumer Credit Portfolios for Borrowers}
    \label{tab:portfolio}
    \estauto{\input{mytable.tex}}{3}{c}
\end{table}

This does work and the value is of Variable 1 in (1) is \usedata{mytable.tex}{3,3} and in
(2) \usedata{mytable.tex}{5,3}. %The spacing is not correct after the values are called.

Let's try some maths: The difference of (1) and (2) of Variable 1 is
%\SUBTRACT{\usedata{mytable.tex}{3,3}}{\usedata{mytable.tex}{5,3}}\DiffAB \num{\DiffAB}
% package calculator also has a round option, but I don't really understand the syntax

\end{document}
share|improve this answer
    
So I should include every table that uses usedata at \begin{document} with savedata? –  Jörg Nov 28 '12 at 21:12
    
That would be the plan here yes. –  David Carlisle Nov 28 '12 at 21:14
    
Just a small correction: for the calculator package to work you need to specify .tex at the end, so \SUBTRACT{\usedata{mytable.tex}{3,3}}{\usedata{mytable.tex}{5,3}}\DiffAB works fine. Don't know why that is though. –  Jörg Nov 28 '12 at 21:24
    
Oh that's just because that line was commented out so untested. The values are stored in macros with names based on the argument to \savedata and the coordinates of the cell, so if you omit the .tex from the savedata call you need to omit it from all the usedata ones. (tex will add the .tex while looking for the file but the macro layer doesn't know about that) –  David Carlisle Nov 28 '12 at 21:42
    
There is a problem, unfortunately: I use the following (from egreg) to force line breaks in a column of a table \newcommand{\specialcell}[2][c]{\begin{tabular}[#1]{@{}c@{}}#2\end{tabular}} But savedata really doesn't like a table where I have a column with \specialcell{Long Column \\ Title –  Jörg Nov 29 '12 at 11:15
show 4 more comments

Here's an option that uses LuaTeX. There are three macros:

  • \myarray{name}{table} stores the table.
  • \usearray{name} returns the table.
  • \arrayitem{name}{row}{column} returns the item in position [row,column] of the table stored as name.

I don't have calculator either, so I made a small evaluation function just for example using expl3.


enter image description here


\documentclass{article}
\usepackage{luacode}
\usepackage{xparse}

\begin{luacode*}
myarrays = {}
function myarray(name,s)
    myarrays[name] = {}
    myarrays[name] = string.explode(s,"\\+")
    for i = 1,#myarrays[name] do
        myarrays[name][i] = string.explode(myarrays[name][i],"&")
    end
    myarrays[name].table = s
end
\end{luacode*}

\def\myarray#1#2{\directlua{myarray("#1","\luatexluaescapestring{\unexpanded{#2}}")}}
\def\usearray#1{\directlua{tex.sprint(myarrays.#1.table)}}
\def\arrayitem#1#2#3{\directlua{tex.sprint(myarrays.#1[#2][#3])}}

\ExplSyntaxOn
\NewDocumentCommand{\evaluate}{ m }
    {
        \fp_eval:n {#1}
    }
\ExplSyntaxOff
\begin{document}

Define table "tab1" \verb=\myarray{tab1}{1&2&3\\4&5&6\\}=.\par\medskip
\myarray{tab1}{1&2&3\\4&5&6\\}

Define table "tab2" \verb=\myarray{fish}{10&11&12\\-1&-2&-3\\}=\par\medskip
\myarray{tab2}{10&11&12\\-1&-2&-3\\}

The table "tab1" is:
\[
\begin{array}{ccc}
    \usearray{tab1}
\end{array}
\]

The table "tab2" is: 
\[
\begin{array}{ccc}
    \usearray{tab2}
\end{array}
\]

The product of entry [2,2] in "tab1" and [2,2] in "tab2" is \evaluate{\arrayitem{tab1}{2}{2}*\arrayitem{tab2}{2}{2}}

\end{document}
share|improve this answer
    
Thanks, that is a good answer using Lua, but I use PdfLaTeX. –  Jörg Nov 30 '12 at 15:28
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.