knitr/Sweave 中的 If-Else 语句使用 R 变量作为条件
If-Else Statement in knitr/Sweave using R variable as conditional
我目前在 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"
在回答这个问题之前,我想先看一下这个是否应该的元问题。
我们应该这样做吗?
我不这么认为。我们在这里基本上做的是使用 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}
我目前在 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"
在回答这个问题之前,我想先看一下这个是否应该的元问题。
我们应该这样做吗?
我不这么认为。我们在这里基本上做的是使用 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}