I'm trying to provide some optional, convenient features to a package foo
but I struggle with the dependencies of the dependencies.
Specifically, I'd like to use some features from the bioconductor KEGGgraph
-package if it is installed. KEGGgraph
itself depends on the graph
-package.
From what I read (although it is not clear) is to include KEGGgraph
(and graph
?) as suggested.
From the documentation I see that requireNamespace
is now encouraged together with usage of ::
instead of require
inside functions. Indeed the package check will also complain if require
is used. However, when I use requireNamespace
and ::
the dependencies of KEGGgraph
is not found.
Consider the following minimal reproducible example.
With KEGGgraph
installed and a fresh R-session.
The function below cannot find a function in the 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<-"
It is as-if requireNamespace
does nothing. The error reproduce by running:
# 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)
If require("KEGGgraph")
has been called it works fine:
require("KEGGgraph")
res <- convenientFunction()
Is it really necessary for users to require
this optional package manually?
Adding && requireNamespace("graph")
into the if
-condition in the function definition does not seem to help.
答案 0 :(得分:3)
这是KEGGgraph的问题 - 它使用但不导入graph :: nodeDataDefaults&lt; - 。解决方案是与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本身有效 - 它取决于:在图表上,因此在搜索路径上找到了缺少的导入;当你{{ 1}},你没有将KEGGgraph的Depends:包添加到搜索路径,因此找不到requireNamespace()
- 。
答案 1 :(得分:3)
我是KEGGgraph的维护者。我确认了问题,并更新了包。在Bioconductor subversion资源库修订版103436中,该问题已得到解决,并有望得到解决。
解决方案几乎与Martin建议的一样,是从 graph 包中明确导入函数。我抓住机会也改变了 KEGGgraph 的依赖关系策略,以便导入图形包而不是依赖它。希望这使得KEGGgraph对上述用例更加友好。
感谢您报告此问题,感谢Martin和Dirk的回答。