如何获取在knitr .Rnw文档中使用的软件包列表?

10

使用RStudio --> CompilePDF

在一个要用pdflatex处理的.Rnw文档中,我想获取加载在文档中的所有用户(即我自己)通过library()或require()加载的包的列表。我尝试使用sessionInfo(),例如:

   \AtEndDocument{
   \medskip
   \textbf{Packages used}: \Sexpr{names(sessionInfo()$loadedOnly)}.
   }

然而,它所打印的只是knitr本身使用的软件包列表,

所用软件包:digest、evaluate、formatR、highr、stringr、tools。

而不是我明确引用的那些。我认为这是因为knitr在内部环境中运行代码块,但我不知道如何访问它。

我知道使用cache=TRUE会创建文件缓存/__packages;有没有办法在不缓存的情况下自动生成它?

4个回答

10

没有缓存 (cache = FALSE),你想要的基本上就是

unique(c(.packages(), loadedNamespaces()))

启用缓存后,情况会稍微复杂一些,因为软件包名称也被缓存了;第二次编译文档时,除非你使缓存失效,否则这些软件包不会被加载。在这种情况下,正如你所注意到的那样,有一个名为cache/__packages的文件,你可以在那里读取软件包的名称,因此

unique(c(.packages(), loadedNamespaces(), readLines('cache/__packages')))

你可能希望让代码更加健壮(例如,首先检查cache/__packages是否存在),并从列表中排除某些软件包(例如knitr及其相关软件包),正如@sebastian-c所指出的那样。


1

所以你想要的是除了基本包和knitr之外加载的所有软件包。如果我列出所有软件包并排除它们,你就能得到你想要的:

p <- setdiff(.packages(), 
        c("knitr", "stats", "graphics", "grDevices", "utils", "datasets", 
          "methods", "base"))
p

如果您正在使用knitr制作文档,或者想要显式加载基本程序包,则需要进行一些例外处理。


1
这种方法的问题在于,在导言部分的 \AtEndDocument{} 块内部的 \Sexpr{} 在编织时(.Rnw 文件开头)就被计算了,因此返回一个空列表。在生成的 .tex 文件中,它显示为:
\AtEndDocument{
\medskip
\textbf{Packages used}: .
}

唯一的方法是在.Rnw文件的末尾显式包含生成此文本的代码(在我的情况下,这是一个子文档,例如,

...
\bibliography{graphics,statistics}

Inside child document:
\textbf{Packages used}: \Sexpr{setdiff(.packages(), 
        c("knitr", "stats", "graphics", "grDevices", "utils", "datasets", 
          "methods", "base"))}.

你不应该将LaTeX编程与R编程混合使用。R/knitr不了解LaTeX语法。如果你想避免重复文档的这一部分,可以将其放在子文档中,这样它就可以被所有文档重用。 - Yihui Xie

0

这是一种略有不同、或许更加明确和详细的方法,对之前给出的答案进行了扩展。这将出现在书籍的\backmatter中。变量nColOut表示包含所使用软件包列表的打印表格的列数。

\cleardoublepage
\printindex

\cleardoublepage

\chapter*{Packages}

<<packages, cache = FALSE, echo = FALSE, warning = FALSE, results = "asis">>=
nColOut = 7
packsAll <- unique(c(.packages(), loadedNamespaces(), readLines('cache/__packages')))
packsReduced <- setdiff(packsAll,
  c("knitr", "stats", "graphics", "grDevices", "utils", "datasets", "methods", "base"))
howManyPacks <- packsReduced %>%
  length()
numLines <-
  tibble(numPacks = howManyPacks + 0:(nColOut - 1),
    n = numPacks %% nColOut)
howManyToAdd <- numLines %>%
  filter(n == 0) %>%
  mutate(diff = numPacks - howManyPacks) %>%
  pull(diff)
packsReduced %>%
  sort() %>%
  as_tibble() %>%
  add_row(value = rep('', howManyToAdd)) %>%
  mutate(id = rep(1:(length(value) / nColOut), nColOut),
    col =  rep(letters[1 : nColOut], each = length(value) / nColOut)) %>%
  pivot_wider(names_from = col, values_from = value) %>%
  select(-id) %>%
  kable("latex", booktabs = TRUE, longtable = TRUE) %>%
  kable_styling(latex_options = "repeat_header") %>%
  row_spec(0, align = "c")
@

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接