Правильное использование дополнительных функций пакета и зависимостей

Я пытаюсь добавить некоторые необязательные удобные функции в пакет foo, но я борюсь с зависимостями зависимостей. В частности, я хотел бы использовать некоторые функции пакета bioconductor KEGGgraph, если он установлен. Сам KEGGgraph зависит от graph-пакета. Из того, что я прочитал (хотя это неясно), следует включить KEGGgraphgraph?), как было предложено.

Из документации я вижу что requireNamespace теперь поощряется вместе с использованием :: вместо require внутри функций. Действительно, проверка пакета также будет жаловаться, если используется require. Однако, когда я использую requireNamespace и ::, зависимости KEGGgraph не найдены.

Рассмотрим следующий минимальный воспроизводимый пример. С установленным KEGGgraph и свежей R-сессией. Функция ниже не может найти функцию в пакете graph:

# 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 вручную устанавливали этот необязательный пакет? Добавление && requireNamespace("graph") в условие if в определении функции не помогает.


person Anders Ellern Bilgrau    schedule 24.05.2015    source источник
comment
Выстрел от бедра: rc <- requireNamespace("KEGGgraph", quietly=TRUE, character.only=TRUE), а затем вы можете проверить rc. Я думаю, что недавно тоже попался на эту удочку -- requireNamespace() не является прямой заменой require().   -  person Dirk Eddelbuettel    schedule 25.05.2015


Ответы (2)


Это проблема с 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: в путь поиска, чтобы nodeDataDefaults<- не было найдено).

person Martin Morgan    schedule 25.05.2015

Я сопровождаю KEGGgraph. Я подтверждаю проблему и обновил пакет. В версии 103436 репозитория подрывной деятельности Bioconductor проблема решена и, надеюсь, решена.

Решение почти такое, как предложил Мартин, — явно импортировать функцию из пакета graph. Я рискнул также изменить политику зависимостей KEGGgraph, чтобы пакет graph импортировался из, а не зависел от него. Надеюсь, это сделает KEGGgraph более удобным для случаев использования, показанных выше.

Спасибо за сообщение о проблеме и спасибо Мартину и Дирку за их ответы.

person Jitao David Zhang    schedule 25.05.2015