【问题标题】:Load R packages when writing report with Knitr and LaTex使用 Knitr 和 LaTex 编写报告时加载 R 包
【发布时间】:2015-09-08 18:27:36
【问题描述】:

我有以下组合系统,用于使用 Knitr 和 LaTeX 编写报告,

  1. Rstudio 版本 0.99.473 和 R 版本 3.2.2
  2. Knitr_1.11
  3. MiKTeX 2.9
  4. Windows 7

一个示例 .Rnw 代码如下所示,我的问题是在“图 1:测试”下方创建了一个文本字符串“latticeknitrstatsgraphicsgrDevicesutilsdatasetsmethodsbase”。我想知道如何摆脱它。

\documentclass[letterpaper]{article}
\title{An example}
\author{Me}
\date{\today{}}

<<setup, include=FALSE, cache=FALSE>>=
knit_hooks$set(myPackage = function(before, options, envir){
  if(before)
    library(lattice)  else NULL
})
@

\begin{document}
\maketitle
\newpage
\section{My section 1}
\begin{figure}
\caption{Test}\label{fig:GofBase}
<<myPackage=TRUE, echo=FALSE, results='asis', cache=TRUE, fig.show='hold', fig.align='center', warning=FALSE>>=
xyplot(rnorm(100)~rnorm(100))
@
\end{figure}

\end{document}

【问题讨论】:

  • 有趣,如果从钩子外部加载格子,这会很好。

标签: r latex knitr


【解决方案1】:

由于问题表述的不是很清楚,最小的例子也不是绝对的“最小”,这里有一个改进的版本:

问题

为什么下面的最小示例会在输出中添加类似latticeknitrstatsgraphicsgrDevicesutilsdatasetsmethodsbase 的字符串?

\documentclass{article}

<<setup>>=
knit_hooks$set(myPackage = function(before, options, envir){

    if(before) library(lattice)
})
@

\begin{document}
<<myPackage=TRUE>>=
xyplot(rnorm(100)~rnorm(100))
@
\end{document}

回答

这与lattice 无关,也不是knitr 块挂钩的特殊功能。

会发生什么?

当一个块挂钩返回一个字符值时,这个值包含在输出中:

在 knitr 中,也可以使用钩子将文本插入到输出中。为此,钩子函数必须返回一个字符结果。 [knitr: hooks]

在这种情况下,钩子没有明确的返回值。因此返回if()的返回值。 if() 依次返回 library 返回的值:

if 返回评估的表达式的值,或者 NULL 如果没有则不可见(如果没有 else 则可能发生)。 [见?"if"]

最后:

library(不可见地)返回附加包列表[见?libray]

如何避免?

首先,这个例子不是很好。没有理由使用块挂钩加载包。如果需要lattice,则应将其加载到setup 块中。

但在某些情况下,类似的块挂钩很有用。那么,解决办法就是显式返回NULL

knit_hooks$set(myPackage = function(before, options, envir){

    if(before) library(lattice)
    return(NULL)
  })

【讨论】:

  • 我想证明为什么我使用块挂钩加载了一个包。例如,如果latticesetup块中加载了cache=TRUE,并且xyplot函数在随后的块中使用,但是在这个块中带有cache=FALSE并且没有调用library(lattice),那么PDF可以成功第一次编译,但如果要第二次执行相同的.Rnw文件,会弹出错误消息抱怨`Error in eval(expr, envir, enclos): could not find function "xyplot"` .我想在link_里有解释...完全可以加载..._
  • 嗯 ...我会说你根本不应该缓存 setup 块。
  • 我同意你的观点,即在 &lt;&lt;setup, cache=FALSE&gt;&gt; 的块中预先加载包允许后续块使用早期加载的所有包中的函数,但我会说在某些情况下我需要加载特定块的一些特定库,以及不同块的另一堆库,在这种情况下,块挂钩可能是一种选择......哦,我可能在这里做得过火了。
  • 是的,这是可行的,您可能会争辩说,将库和使用这些库的代码保持在一起有一些好处。另一方面,这增加了代码的复杂性,我不希望有任何性能优势。但是,如果您的方法适合您,请坚持下去。 ;)
【解决方案2】:

这是一个“为我工作”的最小改动版本(也来自 RStudio)

\documentclass[letterpaper]{article}
\title{An example}
\author{Me}
\date{\today{}}

<<setup, include=FALSE, cache=FALSE, echo=FALSE>>=
knit_hooks$set(myPackage = function(before, options, envir){
  if(before)
    library(lattice)  else NULL
})
@

\begin{document}
%\SweaveOpts{concordance=TRUE}
\maketitle
\newpage
\section{My section 1}
\begin{figure}
\caption{Test}\label{fig:GofBase}
<<myPackage=TRUE, echo=FALSE, cache=FALSE, fig.show='hold', fig.align='center', warning=FALSE>>=
print(xyplot(rnorm(100)~rnorm(100)))
@
\end{figure}

\end{document}

我在第一个块中添加了echo=FALSE,并从第二个块中删除了results='asis'

【讨论】:

  • Dirk,我将您的确切代码复制到我的系统中,但在“图 1:测试”下方仍然得到相同的文本字符串。
  • 我没有。您的代码生成了一个四页的 pdf。我的 2 页。在任何情况下,您都已经有很多花里胡哨的东西了。让它越来越小,直到你了解每个组件的作用。例如,library(lattice) 周围的舞蹈毫无意义。
  • 我必须确认@Yaming 写的内容。问题中的代码和您的答案中的代码生成完全相同的 PDF。
  • 好的,再看看。尝试在第二个示例中设置 cache=FALSE。我会编辑我的答案。对不起,不准确。 (我还将第一块更改为只做library(lattice),但这无关紧要......)
  • 对不起,还是一样。不过,我认为问题已经解决了。
猜你喜欢
  • 2016-08-29
  • 1970-01-01
  • 2023-03-17
  • 2019-04-14
  • 1970-01-01
  • 2014-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多