Roxygen和建议的包

17
我正在使用roxygen2开发一个包,其中包括一些基于lattice的可视化。虽然这些可视化很好看,但是并不是使用该包所必需的,因此将lattice列在DESCRIPTION文件的Suggests:部分而非Depends:部分。
然而,我还没有找到一种加载lattice以响应用户请求的方法,这种方法可以通过roxygenize()R CMD check的检查。下面两种方式都会使lattice看起来像是未声明的依赖项,并返回以下错误。
##' @import lattice
{}

##' Visualization
##'
##' @param x Data.
##' @param y More data.
##' @export
vizz <- function(x, y){
    xyplot(y ~ x)
}

##' Visualization
##'
##' @param x Data.
##' @param y More data.
##' @export
vizz <- function(x, y){
    library(lattice)
    xyplot(y ~ x)
}

两者都会产生相同的错误。

$ R CMD check dummy.roxygen

* using log directory ‘/###/dummy.roxygen.Rcheck’
* using R version 3.0.2 (2013-09-25)
* using platform: x86_64-pc-linux-gnu (64-bit)
* using session charset: UTF-8
* checking for file ‘dummy.roxygen/DESCRIPTION’ ... OK
* checking extension type ... Package
* this is package ‘dummy’ version ‘1.0-0’
* package encoding: UTF-8
* checking package namespace information ... OK
* checking package dependencies ... ERROR
Namespace dependencies not required: ‘lattice’

See the information on DESCRIPTION files in the chapter ‘Creating R
packages’ of the ‘Writing R Extensions’ manual.

因为在搜索词“roxygen”和“suggests”,“depends”和“imports”结合在一起时会返回大量无关的结果,我已经不成功地寻找答案很长时间了。同时,我仅将lattice和其他一些好用但非必要的软件包列为依赖项,但现在当我准备发布软件包时,我希望以正确的方式解决这个问题。


我现在已经做了,但是它还是给我同样的错误。 - Backlin
在包的roxygen化过程中,lattice仍然位于DESCRIPTION文件的suggests部分,但在NAMESPACE文件中被列为import(lattice)。因此,我得出结论,问题出在roxygenize()而不是R CMD check - Backlin
尝试手动将格点从“Suggests”移动到“Imports”中,也许可以? - juba
我觉得你可能有所发现!只需要给我一点时间来确认它是否按照我希望的方式工作。顺便问一下,如果我在“Imports”下列出“lattice”,你知道当有人安装我的软件包时它是否会自动安装吗? - Backlin
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/39484/discussion-between-backlin-and-juba - Backlin
显示剩余3条评论
2个回答

13

2013年我写这篇答案时的建议是在条件语句中使用require。现在在2016年,官方推荐使用::,并让R打印出没有名为X的包的错误信息:

##' Visualization
##'
##' @description Visualize the data. \pkg{\link{lattice}} package required.
##' @param x Data.
##' @param y More data.
##' @seealso \pkg{\link{lattice}}
##' @export
vizz <- function(x, y){
    lattice::xyplot(y ~ x)
}

只需在您的DESCRIPTION文件中保留Suggests: lattice(在NAMESPACE中不要包括import)。

如果您想自定义错误消息,现在可以在条件语句中使用requireNamespace(lattice),例如:

vizz <- function(x, y){
    if (! requireNamespace("lattice", quietly = TRUE)) {
        stop("Please install lattice: install.packages('lattice')")
    lattice::xyplot(y ~ x)
}

1
除了传统方法外,你知道使用 if(require(pkg)) stop(msg) 而不是 library(pkg) 的特定原因吗?后者将自动抛出手动指定的错误。 - Backlin
我认为没有理由,因为这两个函数显然做的是完全相同的事情。 - Calimo
那我可能会坚持我的答案,因为我和@while已经讨论过这个问题了。但是感谢你为了完整性而添加它! - Backlin
1
请注意,建议已更改,现在建议使用::。请参阅https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Suggested-packages。我会更新我的答案。 - Calimo

0

我不确定是什么导致了我的问题,但在@juba的帮助下进行了一些调试后,发现我已经在问题中提出了正确的解决方案。处理好但不是必需的软件包的正确方法是将它们列在DESCRIPTION文件的Suggests:部分中,并使用roxygen标记它们如下。

##' Visualization
##'
##' See \code{\link[lattice]{xyplot}} for details.
##'
##' @param x Data.
##' @param y More data.
##' @export
vizz <- function(x, y){
    library(lattice)
    xyplot(y ~ x)
}

这不会在安装/附加我的程序包时自动安装或附加lattice,但是当执行该函数时,它只会抛出一个错误,如果无法附加lattice


根据文档,你应该在函数中使用require而不是library,因为如果缺少包,它会发出警告而不是抛出错误。 - while
1
我也见过这种情况。然而,在我的情况下,如果包丢失,我想要抛出一个错误。否则,在下一行将会抛出关于未找到“xyplot”函数的错误,这对最终用户来说可能更加模糊不清。 - Backlin
好的,抱歉。在这种情况下,你应该使用library。只是想分享一下,以防你错过了,因为如果你也使用require,库应该会自动加载。如果你使用require,你还可以更灵活地处理结果,因为它将返回一个布尔值。 - while
是的,你说得对。最好的解决方案甚至可能是测试包是否可以通过require加载,如果没有找到,则询问用户是否应该自动安装它。 - Backlin
1
虽然讨论已经很晚了,但还有更多值得思考的问题:许多(大多数?)函数都是为了最小化副作用而编写的,但是任何调用libraryrequire的包代码都会改变整个R会话的搜索路径,即使函数退出后也是如此。这通常不是一个很大的问题,但随着命名空间冲突的增加(例如,在statsdplyr中的filter()),它确实会产生影响。我发现最好使用已经提到的::,或者如果需要返回,则使用requireNamespace后跟::-函数调用。搜索路径不会被改变。 - r2evans

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