2

In my research, I do my analysis in R and write the paper in LaTeX. To avoid updating values in the paper when my analysis change, I update the values in the paper directly from R.

Assume in R I have the variable foo <- bar.

Right now, I have a placeholder in LaTeX with a set of brackets for foo's value and then a label so that R can find the correct brackets to put the values in.

One example with foo <- bar could be:

Lorem ipsum dolor sit amet {}\label{R.foo}, consectetur adipiscing elit.

So R finds a predefined label (in this case, R.foo), and then replaces whatever is inside the first brackets with foo's value (here: bar). So after R runs, we'll have:

Lorem ipsum dolor sit amet {bar}\label{R.foo}, consectetur adipiscing elit.

The problem is that we'll get multiply defined labels (since there are multiple \label{R.foo} locations still left within the file after R processing is complete), which my LaTeX editor warns me about. Hence, I try to create an alternative that has no LaTeX functionality whatsoever—it should just be something R can search for.

4 Answers 4

3

I would have R create a different file values.tex with the content

\newcommand{\Rfoo}{bar}

and then your main file would have

\input{values}
%\providecommand{\Rfoo}{} % avoid an error if \Rfoo wasn't defined
...
Lorem ipsum dolor sit amet \Rfoo, consectetur adipiscing elit.
3

Approach 1:

As suggested by Fran use knitr. Have knitr create the .tex-file for you from an .Rnw-file or .Rtex-file where R-code-chunks and TeX-code are merged and where at the time of creating the .tex-file the results of carrying out R-code-chunks are placed into the .tex-file. (knitr works out of the box with the online-TeX-platform overleaf if the file to compile does not have the extension ".tex" but does have the extension ".Rtex".)

With the following knitr-example, which must be saved with filename-extension ".Rtex" the R-code-chunks calculate Pythagorean triples:

<<templates, include=FALSE, cache=FALSE, echo=FALSE, results='asis'>>=
knitr::opts_template$set(
  JustResult = list(include=TRUE, cache=FALSE, echo=FALSE, results='asis')
)
PrintTriple <- function(k, s, t) {
    return(cat(
      "With \\(k=", k, "\\) and \\(s=", s, "\\) and \\(t=", t, "\\) you get \\(a=", (k*2*s*t), "\\), \\(b=", (k*((s*s)-(t*t))),
      "\\) and \\(c=", (k*((s*s)+(t*t))), "\\) and \\mbox{\\(a^2+b^2=c^2\\leftrightarrow(",
      (k*2*s*t),")^2+(",(k*((s*s)-(t*t))),")^2=(",(k*((s*s)+(t*t))),")^2","\\)}."
      , sep="", fill=FALSE
    ))
}
@

\documentclass{article}
\usepackage{amsmath, amssymb}
\DeclareMathOperator{\ggd}{ggd}

\parindent=0ex
\parskip=\medskipamount

\begin{document}

Use the following recipe to calculate triples
\((a, b, c)\) where the condition \(((a^2+b^2=c^2)\land(\{a,b,c\}\subset\mathbb{N})\land((a\equiv0\pmod{2}))\) is fulfilled---such triples are called \textbf{Pythagorean triples}:

Choose natural numbers \(k,s,t\); \(s>t\) and set:

\begin{equation*}
\begin{aligned}
a &\longleftarrow k2st\\
b &\longleftarrow k(s^2-t^2)\\
c &\longleftarrow k(s^2+t^2)
\end{aligned}
\end{equation*}

(If and only if \((k=1)\land(\gcd(s,t) = 1)\land(s\not\equiv t \pmod{2})\), then \((a, b, c)\) is called a \textbf{primitive} Pythagorean triple.)

\noindent
<<, opts.label='JustResult' >>=
PrintTriple(2, 4, 3)
@

\noindent
<<, opts.label='JustResult' >>=
PrintTriple(2, 3, 1)
@

\noindent
<<, opts.label='JustResult' >>=
K=1
S=2
T=1
PrintTriple(K, S, T)
@

\noindent
<<, opts.label='JustResult' >>=
K=3*K
S=2
T=1
PrintTriple(K, S, T)
@

\noindent
<<, opts.label='JustResult' >>=
S=3*S
T=3*T
PrintTriple(K, S, T)
@

\end{document}

enter image description here


Approach 2:

Probably your R-program could write a .tex-file ValuesCalculatedByR.tex with content like

cathetus1={3,3},
cathetus2={4,4},
hypotenuse={5,5},

, i.e., a comma-separated list of pattern ⟨identificator⟩={⟨calculated value⟩}.

(The curly braces surrounding the ⟨calculated value⟩s can be omitted if the ⟨calculated value⟩s themselves do not contain commata and if you don't mind spaces that surround ⟨calculated value⟩s being removed.)

And the .tex-file could make an expl3-property-list from it and define a command so that \command{<identificator>} yields <calculated value>:

% I don't have R available right now for creating the file, thus I let the filecontents*-
% environment do that for me:
\begin{filecontents*}{ValuesCalculatedByR.tex}
cathetus1={3,3},
cathetus2={4,4},
hypotenuse={5,5},
FirstTokenIsExpandable=\LaTeX\space is funny and the value is defined.,
\end{filecontents*}
% The <value> "\LaTeX\space is funny and the value is defined."
% of the <identificator> "FirstTokenIsExpandable" does not
% contain comma, thus surrounding curly braces can be omitted.

\ExplSyntaxOn
% -------------------------------------------------------------------------------------------------------
% \ImportIDValueList{<.tex-input-file containing list of pattern <identificator>={<calculated value>} >}
%                   {<command for retrieving <calculated value> associated to <identifictor> >}
% -------------------------------------------------------------------------------------------------------
\cs_new_protected:Npn \ImportIDValueList #1#2 {
  % #1 = name of .tex-input-file created by the program R
  % #2 = to-be-defined command for retrieving calculated value
  \exp_args:Nno \use:n 
                { \exp_args:Nno \use:n { \__Christian_ImportIDValueList:nn{#1} } } 
                { \cs_to_str:N #2 }
}
\cs_new:Nn \__Christian_ImportIDValueList:nn{
  % #1 = name of .tex-input-file created by the program R
  % #2 = name of to-be-defined command for retrieving calculated value
  \cs_new_protected:cpn { #2 } ##1 { 
    \exp:w \__Christian_ImportValue_GetValue:nnnn { #1 } { Christian_ImportValue_#2_prop } {##1} {
      \msg_error:nnnnn { Christian_ImportValue } { not-available } { #1 } { ##1 }
      \mbox{\textsf{?##1?}}
    } 
  }
  \cs_new:cpn { #2Expandable } ##1 ##2 { 
    \exp:w \__Christian_ImportValue_GetValue:nnnn { #1 } { Christian_ImportValue_#2_prop } {##1} { ##2 } 
  }
  \file_get:nnN {#1} {} {\l_tmpa_tl}
  \prop_gclear_new:c { Christian_ImportValue_#2_prop }
  % Can't use \prop_gset_from_keyval:Nn  because ~ needs to be before each <value> as 
  % - unlike unexpandable x-expansion of \prop_item:cn - expandable f-expansion of \prop_item:cn 
  % won't stop when \prop_item:cn has delivered the result and therefore
  % must be stopped by a ~ that gets gobbled by the f-expansion-
  % routine, which, I guess, is s.th. like "\romannumeral-`a"
  % so that expansion during parsing the <number>-quantity
  % continues until it is clear whether a to-be-discarded <optional
  % space> follows the tokens "-`a" denoting the negative number -97
  % while \romannumeral silently removes tokens denoting TeX-
  % <number>-quantities denoting non-positive values without
  % returning any tokens at all.
  \exp_args:NnV \use:n {
    \keyval_parse:nnn 
      { \__Christian_ImportValue_pass_iii_ii_to_i {\__Christian_ImportValue_propset:nnn { Christian_ImportValue_#2_prop }}{} }
      { \__Christian_ImportValue_propset:nnn { Christian_ImportValue_#2_prop } } 
  } { \l_tmpa_tl }
}
\cs_new:Nn \__Christian_ImportValue_pass_iii_ii_to_i:nnn { #1 {#3} {#2} }
\cs_new:Nn \__Christian_ImportValue_propset:nnn {
  \prop_gput:cnn {#1} {#2} {~#3}
}
\cs_new:Nn \__Christian_ImportValue_GetValue:nnnn {
  % #1 = name of .tex-input-file created by the program R
  % #2 = name of property list
  % #3 = value to be retrieved from of property list
  % #4 = tokens in case property is undefined
  \prop_if_in:cnTF { #2 } { #3 }
                   { \exp_args:Nnf \use:nn {\exp_end:} { \prop_item:cn { #2 }{ #3 } } }
                   { \exp_end: #4 }
}
\msg_new:nnnn { Christian_ImportValue } { not-available }
 { Value~for~identifier~"#2"~could~not~be~retrieved }
 { Seems~the~file~"#1"~does~not~have~"#2=...,"}
% -------------------------------------------------------------------------------------------------------
\ExplSyntaxOff

\documentclass{article}

\ImportIDValueList{ValuesCalculatedByR.tex}{\GetRValue}%
% The above 
% - makes a property-list of name "Christian_ImportValue_GetRValue_prop"
%   from the content of the file ValuesCalculatedByR.tex  and 
% - defines a command  \GetRValue{<property>} to check if <property> is defined
%   in the property-list "Christian_ImportValue_GetRValue_prop".
%   If so, the value of that property is delivered.
%   If not so, an error-message is raised and ?<name of property>? is delivered.
%   The command is not expandable but protected.
% - defines a command  \GetRValueExpandable{<property>}{<tokens if <property> is undefined>} 
%   to check if <property> is defined in the property-list "Christian_ImportValue_GetRValue_prop".
%   If so, the value of that property is delivered.
%   If not so, <tokens if <property> is not available> is delivered.
%   The command is expandable.
%   The result is delivered by triggering two expansion-steps.
%   This might be important in case you need to "lay hands" on the result for
%   further examination. E.g., you may wish to have LaTeX examine the value
%   and fork the way of typesetting the value depending on whether the value does 
%   or does not contain a decimal separator. Or whatever.

\begin{document}

\noindent Unexpandable commands:\medskip

\noindent Test 1)\medskip

\[ (\GetRValue{cathetus1})^2+(\GetRValue{cathetus2})^2=(\GetRValue{hypotenuse})^2 \]

%% This yields an error-message and ?undefined value?:
% \GetRValue{undefined value}

\medskip\hrule\medskip\hrule\medskip

\noindent Expandable commands:\medskip

\noindent Test a)\medskip

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\Mytempa
\expandafter\expandafter\expandafter{\GetRValueExpandable{cathetus1}{n/a}}%

\texttt{\string\Mytempa=\meaning\Mytempa}

\(\Mytempa\)

\medskip\hrule\medskip

\noindent Test b)\medskip

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\Mytempb
\expandafter\expandafter\expandafter{\GetRValueExpandable{cathetus2}{n/a}}

\texttt{\string\Mytempb=\meaning\Mytempb}

\(\Mytempb\)

\medskip\hrule\medskip

\noindent Test c)\medskip

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\Mytempc
\expandafter\expandafter\expandafter{\GetRValueExpandable{hypotenuse}{n/a}}

\texttt{\string\Mytempc=\meaning\Mytempc}

\(\Mytempc\)

\medskip\hrule\medskip

\[ (\Mytempa)^2+(\Mytempb)^2=(\Mytempc)^2 \]

\medskip\hrule\medskip

\noindent Test d)\medskip

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\Mytempd
\expandafter\expandafter\expandafter{\GetRValueExpandable
                                        {undefined value}%
                                        {\LaTeX\space is funny but the value
                                         ``undefined value'' is undefined.}%
                                    }

\texttt{\string\Mytempd=\meaning\Mytempd}

\Mytempd

\medskip\hrule\medskip

\noindent Test e)\medskip

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\Mytempe
\expandafter\expandafter\expandafter{\GetRValueExpandable{FirstTokenIsExpandable}{n/a}}

\texttt{\string\Mytempe=\meaning\Mytempe}

\Mytempe

\end{document}

enter image description here

This way the R-program would not need to do replacements in the .tex-file containing the document.
It would just need to create an additional text file containing a comma-separated ⟨identificator⟩={⟨calculated value⟩}-list which then is loaded by LaTeX via

\ImportIDValueList{⟨file⟩}%
                  {⟨to‑be‑defined macro for retrieving a
                   ⟨calculated value⟩ stored in ⟨file⟩
                   by specifying an ⟨identificator⟩
                   in the argument⟩}%
.


Approach 3:

Have your R-program create a database in terms of a comma-separated-value-list stored as .csv-file, with fields "identificator" and "value" and use the package datatool for importing that database and retrieving values:

% With older LaTeX-kernels you need to activate/uncomment the following line:
%\RequirePackage{filecontents}

% I don't have R available right now for creating the file, thus I let the filecontents*-
% environment do that for me:
\begin{filecontents*}{ValuesCalculatedByR.csv}
cathetus1,"3,3"
cathetus2,"4,4"
hypotenuse,"5,5"
\end{filecontents*}

\documentclass[a4paper]{article}

\usepackage{datatool}

\DTLloaddb[noheader,keys={identificator,value}]{ValuesCalculatedByR}{ValuesCalculatedByR.csv}

\newif\ifvaluenotfound
\newcommand\resultscratch{}%

\newcommand{\GetRValue}[1]{%
   \global\valuenotfoundtrue
   \DTLforeach*[\DTLiseq{\identificator}{#1}]%
               {ValuesCalculatedByR}%
               {\identificator=identificator,\value=value}%
               {\global\valuenotfoundfalse\global\let\resultscratch=\value}%
   \ifvaluenotfound
     % Some error or warning-message could be here but I am too lazy at the moment.
     \textsf{?#1?}%
   \else
     \resultscratch
   \fi
}%


    
\begin{document}

\[ (\GetRValue{cathetus1})^2+(\GetRValue{cathetus2})^2=(\GetRValue{hypotenuse})^2 \]

%\GetRValue{Undefined}

\end{document}

enter image description here

2

It is not clear to me what are you trying to do exactly, but I think that is a unnecessarily messed approach. Consider use knitr to use \Sexpr{} to insert small R outputs (like a number or a vector) or R chunks (code between the <<>>= and @ lines) for more complex code (tables, plots, etc). Note that you can change the value of foo in any moment and \Sexpr{foo} will be updated accordingly:

\documentclass{article}
\begin{document}
<<Rchunkcode,echo=FALSE>>=
foo <- "bar" 
@
Lorem ipsum dolor sit amet \Sexpr{foo}, consectetur adipiscing elit.
<<AnotherRchunkcode,echo=FALSE>>=
foo <- "baz" 
@
Lorem ipsum dolor sit amet \Sexpr{foo}, consectetur adipiscing elit.
\end{document}
4
  • It seems the program R is used for doing statistical calculations. That program calculates values and in a .tex-file, which is a template, replaces identifiers by these values. It seems our fellow questioner is after a handy mechanism for bringing the calculated values and the .tex-file together. Commented Jan 10, 2022 at 18:00
  • 1
    @UlrichDiez The R package knitr exists just to avoid that tangled workflow. For nothing you need to have a R session to save statistical results in some files and then retrieve in a LaTeX template . Just a single source and just pressing a single button file can make all the R calculations, generate dynamically the LaTeX report, an produce the PDF, all at once.
    – Fran
    Commented Jan 10, 2022 at 21:37
  • Is knitr something like sweave? Where R-code is mixed with LaTeX-code and where a .tex-file gets derived from the file with the LaTeX/R-code-mix where R-code is replaced by TeX-code representing the result of the R-code? I didn't realize this and therefore misinterpreted your remark "It is not clear to me what are you trying to do exactly". Please accept my apologies. I should have realized this when seeing the <<...,echo=FALSE>...@-thingies. I don't know what I was thinking. Commented Jan 11, 2022 at 17:30
  • 1
    @UlrichDiez Right, knitr was inspired by Sweave and use a similar syntax in .Rnw files, but it is much more advanced package. It have syntax highlight of R code, it can run several languages as Python, allow a lot of options for R chunks, have a built-in cache, it can be use in Rmarkdown (with another syntax) , etc.
    – Fran
    Commented Jan 11, 2022 at 18:31
1

While I wrote the question, I identified the simple solution for it. Before \begin{document}—if I call the new function R—add \newcommand{\R}[1]{}.

Example:

Lorem ipsum dolor sit amet {bar}\R{R.foo}, consectetur adipiscing elit.
2
  • One way around your current workflow is to consider knitr. You'd write a mixture of markdown and R code and compile the output into a PDF (which uses LaTeX).
    – Werner
    Commented Jan 10, 2022 at 18:01
  • 1
    If you're able to find-and-replace {}\label{R.foo} with {bar}\label{R.foo}, why not just replace it with {bar}? That way you don't have to now replace it with {bar}\R{R.foo} and set \newcommand{\R}[1]{}...?
    – Werner
    Commented Jan 10, 2022 at 18:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .