【问题标题】:If-Else Statement in knitr/Sweave using R variable as conditionalknitr/Sweave 中的 If-Else 语句使用 R 变量作为条件
【发布时间】:2015-09-10 03:29:07
【问题描述】:

我目前在 R 和 RStudio 中使用 knitr 来生成 LaTeX 输出。我的代码是一个 .Rnw 文件(例如,称为 testKnitr.Rnw),它被编译成一个 pdf 文件:

knit("testKnitr.Rnw") // in RStudio
pdflatex testKnitr.tex // in terminal

我想在 LaTeX 中使用 if-else 语法,以便根据 R 变量的值,输出两个 LaTeX 文本段落之一。在这些 LaTeX 段落中,我想使用 \Sexpr{} 和 \ref 之类的表达式。

我有一个基于此处发布的类似问题的第二个答案的最小工作示例:

How to write an if-then statement in LaTeX using the value of an R variable in knitr/Sweave

这是 MWE:

\documentclass{article}

\begin{document}

<<include=FALSE>>=
library(knitr)
opts_chunk$set(
concordance=TRUE
)
@

<<condition, include=FALSE, echo=FALSE>>=
x<- rnorm(1)
if(x>0){
  text <- "This means x value of \Sexpr{x} was greater than 0"
  }else{
  text <- "This means x value of \Sexpr{x} was less than 0"
  }
@

Testing the code: 

<<print, results='asis', echo=FALSE>>=
cat(text)
@

\end{document}

理想情况下,上述 MWE 的预期输出应该是一份报告,其中一行包含以下内容:

"This means x value of 0.87 was greater than 0"

"This means x value of -0.87 was less than 0"

【问题讨论】:

  • 您可以使用text &lt;- paste("This means x value of", x, "was greater than 0") 在输出中包含该值。这在您的非最小情况下不起作用吗?
  • 谢谢@DavidRobinson。我可能必须创造一个更好的 MWE!因为,我试图在文本中加入像 \Sexpr{} 和 \ref{} 这样的 LaTeX 语法。因此,我认为您的解决方案不适用于 \ref{}。

标签: r if-statement knitr sweave


【解决方案1】:

在回答这个问题之前,我想先看看这个应该是否应该做的元问题。

我们应该这样做吗?

我不这么认为。我们这里基本上是使用knitr\Sexpr{x} 插入到文档中,然后解释\Sexpr{x}。没有(明显的)理由让我们绕道而不是将x 的值直接插入到文档中。

怎么做?

以下最小示例显示了无论如何可以做到这一点:

\documentclass{article}

\begin{document}

<<setup, echo = FALSE>>=
library(knitr)
knit_patterns$set(header.begin = NULL)
@

<<condition, echo=FALSE>>=
x <- rnorm(1)
if (x > 0) {
  text <- "This means x value of \\Sexpr{x} was greater than 0"
  } else {
    text <- "This means x value of \\Sexpr{x} was less than 0"
  }
@

Testing the code:

<<print, results='asis', echo=FALSE>>=
cat(text)
@

\end{document}

这里有两点很重要:

  • 我们需要对\Sexpr 中的反斜杠进行转义,得到\Sexpr
  • 我们需要设置knit_patterns$set(header.begin = NULL)

编译文档:

  • 另存为doc.Rnw
  • 然后执行:

    knitEnv <- new.env()
    knit(input = "doc.Rnw", output = "intermediate.Rnw", envir = knitEnv)
    knit2pdf(input = "intermediate.Rnw", output = "doc_final.tex", envir = knitEnv)
    

会发生什么?

第一次调用knit会生成intermediate.Rnw,内容如下:

\documentclass{article}

\begin{document}

Testing the code:

This means x value of \Sexpr{x} was less than 0

\end{document}

您应该注意knitr 没有像往常一样包含任何定义、命令等 LaTeX 代码。这是由于设置了header.begin = NULL 和记录的here。我们需要这种行为,因为我们想在第二步中再次编织生成的文档,而当相同的东西被定义两次时,LaTeX 不喜欢它。

创建新环境knitEnv 并将其设置为envir 是可选的。如果我们跳过这一步,变量x 将在全局环境中创建。

在第二步中,我们使用knit2pdf 编织intermediate.Rnw,然后立即生成PDF。如果在第一步中使用了envir,我们这里也需要使用它。这就是x 和它的价值从第一个编织步骤传递到第二个编织步骤的方式。

这次包含了所有血腥的 LaTeX 内容,我们得到 doc_final.tex 和:

\documentclass{article}\usepackage[]{graphicx}\usepackage[]{color}
%% maxwidth is the original width if it is less than linewidth
%% otherwise use linewidth (to make sure the graphics do not exceed the margin)
\makeatletter
\def\maxwidth{ %
  \ifdim\Gin@nat@width>\linewidth
    \linewidth
  \else
    \Gin@nat@width
  \fi
}
\makeatother

%% more gory stuff %%


\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\begin{document}

Testing the code:

This means x value of \ensuremath{-0.294859} was less than 0

\end{document}

【讨论】:

  • 感谢@user2706569 的详细帖子!有时,当我创建 MWE 时,为了删除多余的信息,我无意中删除了重要信息。在这种情况下,我相信我删除了关于为什么我们应该这样做的信息。真的,我不仅在做 \Sexpr{},而且还在做 \ref{}。这就是为什么(我相信)我不能只打印 \Sexpr{} 中的变量值,因为它不能解决 \ref{}。
  • 我不认为 \Sexpr 和 \ref 具有可比性。 \ref 是一个 LaTeX 命令,在编译过程中被解析 (TEX --> PDF)。
  • 谢谢@user2706569。我一直很难弄清楚何时编译某些语法,但我很欣赏你的解释。我在这里(stackoverflow.com/questions/32505959/…)发布了一个类似的问题,以防有人感兴趣。我在那里同时使用了 \Sexpr 和 \ref 的 MWE,希望不会过度简化我试图以最有效的方式做的事情。再次感谢。
  • 关于语法:通常\command{} 的所有内容都是 LaTeX。 \Sexpr 是一个令人讨厌的例外。稍后我会看看另一个问题。
  • 谢谢。我曾认为 \command{} 通常是 LaTeX,并且很困惑地得知 \Sexpr 不是。很高兴知道这是一个例外!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
  • 2014-09-06
  • 2016-10-13
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
相关资源
最近更新 更多