通过“网格搜索”访问表中的值

通过“网格搜索”访问表中的值

我正在尝试实现以下目标:我想从主文本中的表格中访问数字并使用它进行一些计算。例如,如果1.85表中有一个值,我想将其存储在变量名下,并能够在主文本中调用它,然后生成1.85

下面的 MWE 显示了 egreg 提供的一些代码,它将表中的值存储在命令名称下。如果我将标签手动“硬编码”到表中,这种方法效果很好。问题是表是自动生成的,所以我无法\setvalue{\ValueA}{20}在表中写入内容,因为下次生成表时它会消失。

表格的布局几乎不会改变,只有数字会改变。所以我需要的是一些“网格搜索”,它从我手动指定的单元格中获取值并将其自动包装到 egregs 代码中,例如The value is \setvalue\ValueC{mytable.tex}{2}{7}将访问 mytable 的第 2 列、第 7 行。这样的事情可能吗,或者有更好的解决方案吗?

另一个问题是,在表格被包含之前我无法访问值(参见第一行注释)。我猜一个可能的解决方案是将所有表格放入文档开头的一个不可见的框中,但也许有更好的方法。

下面的 MWE 显示了 Stata 生成的表格的estout通常外观。mytable.tex仅包含表格的裸内容,然后由命令将其包装到表格环境中\estauto

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

在此处输入图片描述

答案1

我没有计算器包,但是它定义了每个单元格内容的可扩展宏。

在此处输入图片描述

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

答案2

这是一个使用 LuaTeX 的选项。有三个宏:

  • \myarray{name}{table}存储表。
  • \usearray{name}返回表。
  • \arrayitem{name}{row}{column}[row,column]返回表中存储位置的项目name

我也没有计算器,所以我做了一个小评估函数,仅用于举例expl3


在此处输入图片描述


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

相关内容