knitr/Sweave 中的 If-Else 语句使用 R 变量作为条件(第 2 部分)
If-Else Statement in knitr/Sweave using R variable as conditional (Part 2)
我正在扩展我在此处 post 提出的问题:
我想在 LaTeX 中使用 if-else 语法,以便根据 R 变量(比如 x)的值,输出两个 LaTeX 文本段落之一。如果 x>0,则 LaTeX 段落有一个图形和一个 table。但是,如果 x<0,则 LaTeX 段落只有一个数字(没有 table)。
我有一个可以工作的 MWE,它基于之前 post 的检查答案:
\documentclass[12pt,english,nohyper]{tufte-handout}
\usepackage{tabularx}
\usepackage{longtable}
\begin{document}
<<setup, echo = FALSE>>=
library(knitr)
library(xtable)
library(ggplot2)
knit_patterns$set(header.begin = NULL)
@
<<echo=FALSE,results='asis'>>=
fname="myOutput.pdf"
pdf(fname,width=4,height=4)
print(qplot(mpg,cyl,data=mtcars))
{dev.off();invisible()}
cat(sprintf('\begin{marginfigure}
\includegraphics[width=0.98\linewidth]{%s}
\caption{\label{mar:dataMtcars}Comments about mtcar dataset.}
\end{marginfigure}',sub('\.pdf','',fname)))
@
<<echo=FALSE,results='asis'>>=
x<- rnorm(1)
if (x>0){
myDF = data.frame(a=rnorm(1:5),b=rnorm(1:5),c=rnorm(1:5))
print(xtable(myDF,caption='Data frame comments', label='tab:myDataFrame'),floating=FALSE, tabular.environment = "longtable",include.rownames=FALSE)
}
@
<<condition, echo=FALSE>>=
if(x>0){
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame."
}else{
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame."
}
@
Testing the code:
<<print, results='asis', echo=FALSE>>=
cat(text)
@
\end{document}
然后我将这个 MWE 保存为 testKnitr.Rnw 和 运行:
knit(input = "testKnitr.Rnw", output = "intermediate.Rnw")
knit2pdf(input = "intermediate.Rnw", output = "doc_final.tex")
我想知道我是否正在有效地创建此代码,特别是因为在我之前的 post 中有人向我指出 - 在仅使用 \Sexpr{} 的情况下 - 有更简单的解决方案。这里编织两次有点麻烦
是否有更简单的方法来合并我的 if/else 语句以显示包含变量值、数字、and/or tables 的两段之一,所有这些都基于值变量?谢谢。
类似于 动态生成 \Sexpr{}
并在这种情况下不需要第二次解析中间输出。
问题的代码中发生了很多事情,但这是关键块(其中 x
获取在前一个块中分配的随机值):
<<condition, echo=FALSE>>=
if (x > 0) {
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame."
} else {
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame."
}
@
直接替代 print
ing \Sexpr
\Sexpr{}
的直接替代方法是 paste
和 sprintf
(我在 if
分支中使用一个,在 else
分支中使用一个只是为了演示):
<<condition, echo=FALSE>>=
if (x > 0) {
text <- paste("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of", x, "was greater than 0. Table \ref{tab:myDataFrame} shows my data frame.")
} else {
text <- sprintf("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of %f was less than 0. We do not show a data frame.", x)
}
@
当有条件地显示的文本不太长时,这种方法很有效。否则,使用 LaTeX if
-statements 可能更方便。这样做的好处是不会在字符字符串/代码块中包含太多代码。然后,\Sexpr{}
可能再次有用。
使用 LaTeX 条件表达式
有many ways to write conditional expressions in LaTeX,但最简单的形式就足够了。
- 首先,定义一个新的
if
,我们称之为 ifPositive
:
\newif\ifPositive
。
- 二、用R插入
\Positivetrue
或者
\Positivefalse
写入文件。
三、使用\ifPositive … \else … \fi
.
\newif\ifPositive
<<condtion2, echo = FALSE, results = "asis">>=
if (x > 0) {
cat("\Positivetrue")
} else {
cat("\Positivefalse")
}
@
\ifPositive
Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame.
\else
Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame.
\fi
其他备注
问题中有一个块生成myOutput.pdf
。在那里,使用了 pdf()
和 dev.off()
。这不是什么好风格kills kittens。无需绕过 knitr
的生产情节机制;即使使用 marginfigure
而不是 figure
之类的自定义环境也不行。该块应替换为如下内容:
<<dataMtcars, echo=FALSE, fig.env = "marginfigure", out.width = "0.98\linewidth", fig.cap = "Comments about mtcar dataset.", fig.lp = "mar:">>=
print(qplot(mpg,cyl,data=mtcars))
@
fig.lp = "mar:"
只是为了生成与问题 mar:dataMtcars
中完全相同的标签所必需的。如果标签 fig:dataMtcars
也可以,则可以跳过。
文档
最后,这里是完整的文档:
\documentclass[12pt,english,nohyper]{tufte-handout}
\usepackage{tabularx}
\usepackage{longtable}
\begin{document}
<<setup, echo = FALSE>>=
library(knitr)
library(xtable)
library(ggplot2)
@
<<dataMtcars, echo=FALSE, fig.env = "marginfigure", out.width = "0.98\linewidth", fig.cap = "Comments about mtcar dataset.", fig.lp = "mar:">>=
print(qplot(mpg,cyl,data=mtcars))
@
<<echo=FALSE,results='asis'>>=
x <- rnorm(1)
if (x > 0) {
myDF <- data.frame(a = rnorm(1:5), b = rnorm(1:5), c = rnorm(1:5))
print(xtable(myDF, caption= 'Data frame comments', label='tab:myDataFrame'), floating = FALSE, tabular.environment = "longtable", include.rownames=FALSE)
}
@
<<condition, echo=FALSE>>=
if (x > 0) {
text <- paste("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of", x, "was greater than 0. Table \ref{tab:myDataFrame} shows my data frame.")
} else {
text <- sprintf("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of %f was less than 0. We do not show a data frame.", x)
}
@
Testing the code:
<<print, results='asis', echo=FALSE>>=
cat(text)
@
\paragraph{Alternative:}
\newif\ifPositive
<<condtion2, echo = FALSE, results = "asis">>=
if (x > 0) {
cat("\Positivetrue")
} else {
cat("\Positivefalse")
}
@
\ifPositive
Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame.
\else
Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame.
\fi
\end{document}
我正在扩展我在此处 post 提出的问题:
我想在 LaTeX 中使用 if-else 语法,以便根据 R 变量(比如 x)的值,输出两个 LaTeX 文本段落之一。如果 x>0,则 LaTeX 段落有一个图形和一个 table。但是,如果 x<0,则 LaTeX 段落只有一个数字(没有 table)。
我有一个可以工作的 MWE,它基于之前 post 的检查答案:
\documentclass[12pt,english,nohyper]{tufte-handout}
\usepackage{tabularx}
\usepackage{longtable}
\begin{document}
<<setup, echo = FALSE>>=
library(knitr)
library(xtable)
library(ggplot2)
knit_patterns$set(header.begin = NULL)
@
<<echo=FALSE,results='asis'>>=
fname="myOutput.pdf"
pdf(fname,width=4,height=4)
print(qplot(mpg,cyl,data=mtcars))
{dev.off();invisible()}
cat(sprintf('\begin{marginfigure}
\includegraphics[width=0.98\linewidth]{%s}
\caption{\label{mar:dataMtcars}Comments about mtcar dataset.}
\end{marginfigure}',sub('\.pdf','',fname)))
@
<<echo=FALSE,results='asis'>>=
x<- rnorm(1)
if (x>0){
myDF = data.frame(a=rnorm(1:5),b=rnorm(1:5),c=rnorm(1:5))
print(xtable(myDF,caption='Data frame comments', label='tab:myDataFrame'),floating=FALSE, tabular.environment = "longtable",include.rownames=FALSE)
}
@
<<condition, echo=FALSE>>=
if(x>0){
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame."
}else{
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame."
}
@
Testing the code:
<<print, results='asis', echo=FALSE>>=
cat(text)
@
\end{document}
然后我将这个 MWE 保存为 testKnitr.Rnw 和 运行:
knit(input = "testKnitr.Rnw", output = "intermediate.Rnw")
knit2pdf(input = "intermediate.Rnw", output = "doc_final.tex")
我想知道我是否正在有效地创建此代码,特别是因为在我之前的 post 中有人向我指出 - 在仅使用 \Sexpr{} 的情况下 - 有更简单的解决方案。这里编织两次有点麻烦
是否有更简单的方法来合并我的 if/else 语句以显示包含变量值、数字、and/or tables 的两段之一,所有这些都基于值变量?谢谢。
类似于 \Sexpr{}
并在这种情况下不需要第二次解析中间输出。
问题的代码中发生了很多事情,但这是关键块(其中 x
获取在前一个块中分配的随机值):
<<condition, echo=FALSE>>=
if (x > 0) {
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame."
} else {
text <- "Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame."
}
@
直接替代 print
ing \Sexpr
\Sexpr{}
的直接替代方法是 paste
和 sprintf
(我在 if
分支中使用一个,在 else
分支中使用一个只是为了演示):
<<condition, echo=FALSE>>=
if (x > 0) {
text <- paste("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of", x, "was greater than 0. Table \ref{tab:myDataFrame} shows my data frame.")
} else {
text <- sprintf("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of %f was less than 0. We do not show a data frame.", x)
}
@
当有条件地显示的文本不太长时,这种方法很有效。否则,使用 LaTeX if
-statements 可能更方便。这样做的好处是不会在字符字符串/代码块中包含太多代码。然后,\Sexpr{}
可能再次有用。
使用 LaTeX 条件表达式
有many ways to write conditional expressions in LaTeX,但最简单的形式就足够了。
- 首先,定义一个新的
if
,我们称之为ifPositive
:\newif\ifPositive
。 - 二、用R插入
\Positivetrue
或者\Positivefalse
写入文件。 三、使用
\ifPositive … \else … \fi
.\newif\ifPositive <<condtion2, echo = FALSE, results = "asis">>= if (x > 0) { cat("\Positivetrue") } else { cat("\Positivefalse") } @ \ifPositive Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame. \else Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame. \fi
其他备注
问题中有一个块生成myOutput.pdf
。在那里,使用了 pdf()
和 dev.off()
。这不是什么好风格kills kittens。无需绕过 knitr
的生产情节机制;即使使用 marginfigure
而不是 figure
之类的自定义环境也不行。该块应替换为如下内容:
<<dataMtcars, echo=FALSE, fig.env = "marginfigure", out.width = "0.98\linewidth", fig.cap = "Comments about mtcar dataset.", fig.lp = "mar:">>=
print(qplot(mpg,cyl,data=mtcars))
@
fig.lp = "mar:"
只是为了生成与问题 mar:dataMtcars
中完全相同的标签所必需的。如果标签 fig:dataMtcars
也可以,则可以跳过。
文档
最后,这里是完整的文档:
\documentclass[12pt,english,nohyper]{tufte-handout}
\usepackage{tabularx}
\usepackage{longtable}
\begin{document}
<<setup, echo = FALSE>>=
library(knitr)
library(xtable)
library(ggplot2)
@
<<dataMtcars, echo=FALSE, fig.env = "marginfigure", out.width = "0.98\linewidth", fig.cap = "Comments about mtcar dataset.", fig.lp = "mar:">>=
print(qplot(mpg,cyl,data=mtcars))
@
<<echo=FALSE,results='asis'>>=
x <- rnorm(1)
if (x > 0) {
myDF <- data.frame(a = rnorm(1:5), b = rnorm(1:5), c = rnorm(1:5))
print(xtable(myDF, caption= 'Data frame comments', label='tab:myDataFrame'), floating = FALSE, tabular.environment = "longtable", include.rownames=FALSE)
}
@
<<condition, echo=FALSE>>=
if (x > 0) {
text <- paste("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of", x, "was greater than 0. Table \ref{tab:myDataFrame} shows my data frame.")
} else {
text <- sprintf("Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of %f was less than 0. We do not show a data frame.", x)
}
@
Testing the code:
<<print, results='asis', echo=FALSE>>=
cat(text)
@
\paragraph{Alternative:}
\newif\ifPositive
<<condtion2, echo = FALSE, results = "asis">>=
if (x > 0) {
cat("\Positivetrue")
} else {
cat("\Positivefalse")
}
@
\ifPositive
Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was greater than 0. Table \ref{tab:myDataFrame} shows my data frame.
\else
Figure \ref{mar:dataMtcars} shows the mtcars data set. The x value of \Sexpr{x} was less than 0. We do not show a data frame.
\fi
\end{document}