0

I have been always wondering if there were an optimal way to perform this task in papers. So for example, in my field it is normal to present an output table from R (like linear regression) showing the estimated Betas, Variances... Normally, I refer to the raw numbers several times in the paper, for example, saying that the estimated Beta was equal to 0.2. It is unconvenient to be writting those numbers all the time, and even more annoying than that, is when I update the table with different estimates due to a small correction. So I have to be looking along all the pages where I wrote those numbers, and change them manually... I am sure there is an optimal way to do that, like for example, \ref{tab:output}[row=1,column=3] would show the content of the row 1, column 3 on that table.

Moreover, I want to know if is it possible, for example, I would like to show in the paper exp(\ref{tab:output}[row=1,column=3]), it will automatically calculate and display the exponential of this referenced number.

Thanks

2 Answers2

1

Referencing R outputs? You are asking to know how to do literary programming using the knitr R package.

An example: If you change the values of lines 10 and 11 of the next code, all the text of the PDF document will be updated accordingly when compiled. Important: name the file example.Rnw or whatever.Rnw for compile it in R, Rstudio or VS Code, but in Overleaf name it example.Rtex (disclaimer: not tested).

\documentclass[twocolumn]{article}
\usepackage{booktabs,parskip}
\usepackage[colorlinks]{hyperref}
\begin{document}

<<yourdata,include=FALSE>>=

Change the data as you want,

(but lenght of x and y must be equal)

x = c(1,1,2,2,12,3,15,5,4,6,1,7,9,8,1) y = c(1,4,1,2,2,2,3,5,8,7,12,77,45,97,1) df <- data.frame(x,y)

@

So, you constructed a data frame $df$ with the variables $x$, with values \Sexpr{knitr::combine_words(x)}, while the variable $y$ have values of \Sexpr{y[1:4]}, etc.

Now, you can show the whole data frame in \LaTeX, without typing yourself the table \ref{tbla}.

<<tbla,echo=F,results='asis'>>= library(kableExtra) kable(df, caption="Your data frame \label{tbla}", label="tbla", booktabs = T) @

\newpage

Or show in text that the 4th value of $x$ is \Sexpr{df$x[4]} and the 1st value of $y$ is \Sexpr{df$y[1]}, or that $x=1$ and $y=1$ happen \Sexpr{table(df)[1,1]} times whereas when $x=1$ but $y=4$ or $y=5$ was \Sexpr{combine_words(table(df)[1,4:5])} times, respectively .

<<,include=F>>= model <- lm(x~y) pval <- cor.test(x,y)$p.value sig <- if (pval<0.05){""} else "{\bfseries not }" @

Or that the correlation between $x$ and $y$ is \Sexpr{sig}significant (p=\Sexpr{round(pval,3)}).

The linear regression model of $x$ and $y$ have an intercept of approximately
\Sexpr{round(model$coefficients[1],2)} with a
$R^2=\Sexpr{round(summary(model)$r.squared,2)}$. More details in table \ref{tblb}.

<<,echo=F,results='asis'>>= print(xtable::xtable(summary(model), , label="tblb", caption= "The regression model summary."),caption.placement ="top", booktabs = T, size ="\footnotesize" ) @

\end{document}

mwe

Fran
  • 80,769
  • Definetely I should learn knitr, but the learning curve is so steep... Also I do not like to run R code inside a Latex document, but sometimes it may be benefitial... Thanks! – Javier Moreno Sepena May 27 '22 at 17:44
  • @JavierMorenoSepena What steeeep learning curve? It is quite simple start R code with a <<>>= line, and optionally a label and/or a few options like echo and results, and end with @, or put some short R code in a \Sexpr{} and even more simple in R markdown. Reference a cell table typed manually in LaTeX in not too difficult, but you are still dependent of manual editing outputs, whereas knitr will update every table, figure and in text data editing only the source data (that could be in external files). – Fran May 28 '22 at 15:31
0

With the readarray package from Steven B. Segletes the implementation is much easier:

\documentclass{article}
\usepackage{readarray}% at least version 3.0

% configure \typesetarray % from the readarray manual \renewcommand\typesetplanesepchar{\\hline} \renewcommand\typesetrowsepchar{\\hline} \renewcommand\typesetcolsepchar{&}

% specify table data % you can read the data also from a separate txt file % e.g. \readrecordarray{data.txt}\tableOne % => see readarray manual \newcommand\tableOne{% 1.1 2.1 3.1 4.1 1.2 2.2 3.2 4.2 1.3 2.3 3.3 4.3 1.4 2.4 3.4 4.4 1.5 2.5 3.5 4.5 } \readarray\tableOne\dataTableOne[-,4]% 4 columns

% Lua \usepackage{luacode} \begin{luacode} function computeExponential2 (value) tex.print(string.format("%.5f", math.exp(value))) end \end{luacode}

\newcommand\computeExp[1]{\luadirect{tex.print(math.exp(#1))}} \newcommand\computeExpTwo[1]{\luadirect{computeExponential2(#1)}}

\begin{document} \begin{table} \centering \begin{tabular}{|c|c|c|c|} \hline \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} & \textbf{Column 4}\ \hline \typesetarray\dataTableOne\ \hline \end{tabular} \caption{Example table with some data.} \end{table}

\noindent Table One (row 2, column 2): \dataTableOne[2,2]\ Table One (row 4, column 1): $e^{\dataTableOne[4,1]} = \computeExp{\dataTableOne[4,1]}$\ Table One (row 4, column 1): $e^{\dataTableOne[4,1]} = \computeExpTwo{\dataTableOne[4,1]}$ \end{document}


First attempt:

\documentclass{article}
\usepackage{pgffor}   % foreach
\usepackage{ifthen}   % ifthenelse
\usepackage{etoolbox} % other hacks

% table data via foreach % based on: https://tex.stackexchange.com/a/165153 \makeatletter \newtoks@tabtoks \newcommand\addtabtoks[1]{\global@tabtoks\expandafter{\the@tabtoks#1}} \newcommand\eaddtabtoks[1]{\edef\mytmp{#1}\expandafter\addtabtoks\expandafter{\mytmp}} \newcommand\resettabtoks{\global@tabtoks{}} \newcommand\printtabtoks{\the@tabtoks} \makeatother

% specify table data \newcommand\tableOne{{% % entryOne/entryTwo/entryFour/entryFive {1.1,2.1,3.1,4.1},% {1.2,2.2,3.2,4.2},% {1.3,2.3,3.3,4.3},% {1.4,2.4,3.4,4.4},% {1.5,2.5,3.5,4.5}% }} % specify number of rows and columns of the table % (Perhaps this can also be determined automatically. But I do not know how. \newcommand\tableOneNumRows{5} \newcommand\tableOneNumColumns{4}

% Lua \usepackage{luacode} \begin{luacode*} function computeExponential (value) tex.print(math.exp(value)) end

function computeExponential2 (value)
    tex.print(string.format(&quot;%.5f&quot;, math.exp(value)))
end

\end{luacode*}

\begin{document} \resettabtoks% \pgfmathtruncatemacro{\numRows}{\tableOneNumRows-1}% \pgfmathtruncatemacro{\numColumns}{\tableOneNumColumns-1}% \foreach \row in {0,...,\numRows} {% \foreach \column in {0,...,\numColumns} {% \pgfmathsetmacro{\value}{\tableOne[\row][\column]}% \eaddtabtoks{\value}% \ifthenelse{\column < \numColumns} {% \addtabtoks{&}% }{% \addtabtoks{\\hline}% }% }% }% \begin{table} \centering \begin{tabular}{|c|c|c|c|} \hline \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} & \textbf{Column 4}\ \hline \printtabtoks \end{tabular} \caption{Example table with some data.} \end{table}

\noindent Table One (row 2, column 2): \pgfmathparse{\tableOne[1][1]}\pgfmathresult{}\ Table One (row 4, column 1): $e^{\pgfmathparse{\tableOne[3][0]}\pgfmathresult{}} = \pgfmathparse{exp(\tableOne[3][0])}\pgfmathresult{}$\ % For higher accuracy, we can use Lua, for example. % Generation with LuaLaTex is necessary! Table One (row 4, column 1): $e^{\pgfmathparse{\tableOne[3][0]}\pgfmathresult{}} = \pgfmathparse{\tableOne[3][0]}\luadirect{computeExponential("\pgfmathresult")}$\ Table One (row 4, column 1): $e^{\pgfmathparse{\tableOne[3][0]}\pgfmathresult{}} = \pgfmathparse{\tableOne[3][0]}\luadirect{computeExponential2("\pgfmathresult")}$ \end{document}

Output

Unknown
  • 822
  • That was a nice start! I think more automation is needed, so in the end a small command as the one I proposed will be enough. But it can be one of the best features of Latex if implemented!! Thanks your your solution – Javier Moreno Sepena May 27 '22 at 17:45
  • @JavierMorenoSepena I added a simpler version. – Unknown May 27 '22 at 21:24