正确使用可选包功能和依赖项
Proper use of optional package features and dependencies
我正在尝试为包 可选 提供一些方便的功能 foo
但我很难解决依赖项的依赖性问题。
具体来说,我想使用已安装的 bioconductor KEGGgraph
-package if 中的一些功能。 KEGGgraph
本身依赖于 graph
-包。
根据我的阅读(虽然不清楚)是按照建议包括 KEGGgraph
(和 graph
?)。
从 the documentation 我看到现在鼓励 requireNamespace
与在函数内部使用 ::
而不是 require
一起使用。事实上,如果使用 require
,包裹检查也会报错。但是,当我使用 requireNamespace
和 ::
时,找不到 KEGGgraph
的依赖项。
考虑以下最小的可重现示例。
安装 KEGGgraph
和全新的 R-session。
下面的函数在 graph
-package:
中找不到函数
# If KEGGgraph is not installed:
#source("http://bioconductor.org/biocLite.R")
#biocLite("KEGGgraph")
convenientFunction <- function() {
if (requireNamespace("KEGGgraph")) {
tmp.file <- paste0(tempfile(), ".kgml")
kgml <- KEGGgraph::retrieveKGML("hsa:04115", organism = "hsa",
destfile = tmp.file, method = "internal")
return(KEGGgraph::parseKGML2DataFrame(tmp.file))
} else {
stop("This function needs KEGGgraph and its dependencies")
}
}
convenientFunction()
#Loading required namespace: KEGGgraph
#trying URL 'http://www.genome.jp/kegg-bin/download?entry=hsa04115&format=kgml'
#Content type 'text/xml' length unknown
#opened URL
#.......... .......... ......
#downloaded 26 KB
#
# Error in nodeDataDefaults(gR, "KEGGNode") <- env.node :
# could not find function "nodeDataDefaults<-"
就好像requireNamespace
什么也没做一样。错误重现 运行:
# In a new R-session...
requireNamespace("KEGGgraph") # With and without this line
tmp.file <- paste0(tempfile(), ".kgml")
kgml <- KEGGgraph::retrieveKGML("hsa:04115", organism = "hsa",
destfile = tmp.file, method = "internal")
KEGGgraph::parseKGML2DataFrame(tmp.file)
如果调用了 require("KEGGgraph")
,它工作正常:
require("KEGGgraph")
res <- convenientFunction()
用户真的有必要手动require
这个可选包吗?
在函数定义的 if
条件中添加 && requireNamespace("graph")
似乎没有帮助。
这是 KEGGgraph 的问题 -- 它使用但不导入 graph::nodeDataDefaults<-。解决方案是联系 maintainer("KEGGgraph")
并要求他们更新他们的 NAMESPACE
KEGGgraph$ svn diff
Index: NAMESPACE
===================================================================
--- NAMESPACE (revision 104133)
+++ NAMESPACE (working copy)
@@ -2,7 +2,7 @@
importFrom(XML, "xmlAttrs", "xmlChildren", "xmlName", "xmlRoot", "xmlTreeParse")
-importFrom(graph, "edges", "nodes<-", "nodes", "edgeData")
+importFrom(graph, "edges", "nodes<-", "nodes", "edgeData", "nodeDataDefaults<-")
exportPattern("^[^\.]")
exportMethods("getDisplayName",
似乎还有其他缺失的导入,严厉的解决方案是简单地 import(graph)
;一个更轻但不完美的触摸是使用 codetoolsBioC::writeNamespaceImports()
来生成导入(这个函数是错误的,所以不能 100% 依赖)。
一个解决方法是在你的包中写上 library(graph)
或 Depends: graph
;这会将图形放在 search()
路径上,并且 KEGGgraph 会在那里找到丢失的导入(这就是 KEGGgraph 本身工作的原因——它取决于:在图形上,因此在搜索路径上找到丢失的导入;当你 requireNamespace()
,你没有将 KEGGgraph 的 Depends: packages 添加到搜索路径,所以 nodeDataDefaults<
- 没有找到。
我是 KEGGgraph 的维护者。我确认了问题并更新了包。在 Bioconductor subversion 存储库修订版 103436 中,该问题已得到解决并有望得到解决。
解决方案几乎与 Martin 所建议的一样,从 graph 包中显式导入函数。我也借此机会更改了 KEGGgraph 的依赖策略,以便从中导入 graph 包而不是依赖它。希望这能让 KEGGgraph 对上述用例更加友好。
感谢您报告问题,并感谢 Martin 和 Dirk 的回答。
我正在尝试为包 可选 提供一些方便的功能 foo
但我很难解决依赖项的依赖性问题。
具体来说,我想使用已安装的 bioconductor KEGGgraph
-package if 中的一些功能。 KEGGgraph
本身依赖于 graph
-包。
根据我的阅读(虽然不清楚)是按照建议包括 KEGGgraph
(和 graph
?)。
从 the documentation 我看到现在鼓励 requireNamespace
与在函数内部使用 ::
而不是 require
一起使用。事实上,如果使用 require
,包裹检查也会报错。但是,当我使用 requireNamespace
和 ::
时,找不到 KEGGgraph
的依赖项。
考虑以下最小的可重现示例。
安装 KEGGgraph
和全新的 R-session。
下面的函数在 graph
-package:
# If KEGGgraph is not installed:
#source("http://bioconductor.org/biocLite.R")
#biocLite("KEGGgraph")
convenientFunction <- function() {
if (requireNamespace("KEGGgraph")) {
tmp.file <- paste0(tempfile(), ".kgml")
kgml <- KEGGgraph::retrieveKGML("hsa:04115", organism = "hsa",
destfile = tmp.file, method = "internal")
return(KEGGgraph::parseKGML2DataFrame(tmp.file))
} else {
stop("This function needs KEGGgraph and its dependencies")
}
}
convenientFunction()
#Loading required namespace: KEGGgraph
#trying URL 'http://www.genome.jp/kegg-bin/download?entry=hsa04115&format=kgml'
#Content type 'text/xml' length unknown
#opened URL
#.......... .......... ......
#downloaded 26 KB
#
# Error in nodeDataDefaults(gR, "KEGGNode") <- env.node :
# could not find function "nodeDataDefaults<-"
就好像requireNamespace
什么也没做一样。错误重现 运行:
# In a new R-session...
requireNamespace("KEGGgraph") # With and without this line
tmp.file <- paste0(tempfile(), ".kgml")
kgml <- KEGGgraph::retrieveKGML("hsa:04115", organism = "hsa",
destfile = tmp.file, method = "internal")
KEGGgraph::parseKGML2DataFrame(tmp.file)
如果调用了 require("KEGGgraph")
,它工作正常:
require("KEGGgraph")
res <- convenientFunction()
用户真的有必要手动require
这个可选包吗?
在函数定义的 if
条件中添加 && requireNamespace("graph")
似乎没有帮助。
这是 KEGGgraph 的问题 -- 它使用但不导入 graph::nodeDataDefaults<-。解决方案是联系 maintainer("KEGGgraph")
并要求他们更新他们的 NAMESPACE
KEGGgraph$ svn diff
Index: NAMESPACE
===================================================================
--- NAMESPACE (revision 104133)
+++ NAMESPACE (working copy)
@@ -2,7 +2,7 @@
importFrom(XML, "xmlAttrs", "xmlChildren", "xmlName", "xmlRoot", "xmlTreeParse")
-importFrom(graph, "edges", "nodes<-", "nodes", "edgeData")
+importFrom(graph, "edges", "nodes<-", "nodes", "edgeData", "nodeDataDefaults<-")
exportPattern("^[^\.]")
exportMethods("getDisplayName",
似乎还有其他缺失的导入,严厉的解决方案是简单地 import(graph)
;一个更轻但不完美的触摸是使用 codetoolsBioC::writeNamespaceImports()
来生成导入(这个函数是错误的,所以不能 100% 依赖)。
一个解决方法是在你的包中写上 library(graph)
或 Depends: graph
;这会将图形放在 search()
路径上,并且 KEGGgraph 会在那里找到丢失的导入(这就是 KEGGgraph 本身工作的原因——它取决于:在图形上,因此在搜索路径上找到丢失的导入;当你 requireNamespace()
,你没有将 KEGGgraph 的 Depends: packages 添加到搜索路径,所以 nodeDataDefaults<
- 没有找到。
我是 KEGGgraph 的维护者。我确认了问题并更新了包。在 Bioconductor subversion 存储库修订版 103436 中,该问题已得到解决并有望得到解决。
解决方案几乎与 Martin 所建议的一样,从 graph 包中显式导入函数。我也借此机会更改了 KEGGgraph 的依赖策略,以便从中导入 graph 包而不是依赖它。希望这能让 KEGGgraph 对上述用例更加友好。
感谢您报告问题,并感谢 Martin 和 Dirk 的回答。