Dav*_*son 6 r rstudio knitr dplyr
当我使用Knit HTML按钮渲染在RStudio中使用缓存块的Rmd markdown文件时,我发现加载包的顺序不会从块到块记住.当我需要以特定顺序加载包以避免命名空间冲突时,这会导致问题.
对于可重现的示例(需要安装plyr,dplyr和pryr软件包,请参见下文),我首先创建一个knitr Rmd文档,加载plyr然后加载dplyr(它们都导出一个summarise函数),然后使用pryr来确定总结了功能.我用RStudio的"Knit HTML"按钮编织了这个:
```{r}
library(knitr)
opts_chunk$set(cache = TRUE, message = FALSE)
```
```{r test1}
library(plyr)
library(dplyr)
```
```{r test2, dependson = "test1"}
attr(pryr::where("summarise"), "name")
```
Run Code Online (Sandbox Code Playgroud)
按照这里的建议,我在dplyr之前加载plyr,这样dplyr的函数应该首先出现在搜索路径中.正如所料,输出md文件显示该summarise函数来自dplyr:
attr(pryr::where("summarise"), "name")
## [1] "package:dplyr"
Run Code Online (Sandbox Code Playgroud)
但是,如果我在test2块中做了一些小改动:
```{r test2, dependson = "test1"}
attr(pryr::where("summarise"), "name") # this is a change
```
Run Code Online (Sandbox Code Playgroud)
导致它被重新编译,它现在以错误的顺序加载包,并summarise在plyr中找到:
attr(pryr::where("summarise"), "name") # this is a change
## [1] "package:plyr"
Run Code Online (Sandbox Code Playgroud)
请注意,如果knit从R命令行运行,则不会发生此问题,但这只是因为它保持环境中的plyr和dplyr软件包加载(如果我重新启动R,则会出现同样的问题).
我知道我可以参考函数dplyr::summarise以避免冗余,但这是相当麻烦的.根本不加载plyr不是一个选项,因为几个包无意中将它添加到命名空间.如何确保按所需顺序加载包?
我使用的是最新版本的RStudio(0.98.1079),我的sessionInfo如下:
## R version 3.1.1 (2014-07-10)
## Platform: x86_64-apple-darwin13.1.0 (64-bit)
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] plyr_1.8.1 dplyr_0.3.0.2 knitr_1.7
##
## loaded via a namespace (and not attached):
## [1] assertthat_0.1 codetools_0.2-8 DBI_0.3.0 digest_0.6.4
## [5] evaluate_0.5.5 formatR_1.0 htmltools_0.2.4 magrittr_1.0.0
## [9] parallel_3.1.1 pryr_0.1.0.9000 Rcpp_0.11.2 rmarkdown_0.3.10
## [13] rstudioapi_0.1 stringr_0.6.2 tools_3.1.1
Run Code Online (Sandbox Code Playgroud)
请注意,如有必要,您可以使用以下方法为此可重现示例设置必要的包:
```{r}
install.packages(c("devtools", "plyr", "dplyr"))
devtools::install_github("hadley/pryr")
```
Run Code Online (Sandbox Code Playgroud)
我对knitr的拉取请求通过保留__packages文件中搜索路径的顺序来解决此问题.相关代码是:
x = rev(.packages())
if (file.exists(path))
x = setdiff(c(readLines(path), x), .base.pkgs)
writeLines(x, path)
Run Code Online (Sandbox Code Playgroud)
@Yihui在此提交时合并了请求,并且可能在CRAN 中的knitr v1.8中提供(或者立即从GitHub或RForge获得).
当程序包加载到不依赖于彼此的不同块时,仍然可能存在问题,但这确实解决了上述问题和我尝试过的其他应用程序中的示例.