R名称空间访问和match.fun

mar*_*rty 3 namespaces r package

我正在开发一个R包,其中一个函数包含match.fun对导入到包命名空间的包中的函数的调用.但是在加载包时,match.fun调用找不到函数名.从Hadley Wickham的描述我认为我做的一切都是正确的,但事实显然并非如此.

例:

# in the package file header, for creation of the NAMESPACE via roxygen2:
##` @import topicmodels

# The function declaration in the package
ModelTopics <- function(doc.term.mat, num.topics, topic.method="LDA"){
  topic.fun <- match.fun(topic.method)
  output <- topic.fun(doc.term.mat, k=num.topics)
  return(output)

}    
Run Code Online (Sandbox Code Playgroud)

然后在R:

> library(mypackage)
> sample.output <- ModelTopics(my.dtm, topic.method="LDA", num.topics=5)
Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object 'LDA' of mode 'function' was not found
Run Code Online (Sandbox Code Playgroud)

根据我对命名空间的理解,match.fun调用应该可以访问包命名空间,包括topicmodels函数.但这似乎并非如此.如果我topicmodels直接导入R会话的全局命名空间,那么这是有效的.

任何帮助深表感谢.这是在OSX上运行的R64 2.14.1.

更新:包裹在这里

重新描述文件,也许这就是问题:roxygen2不会使用Imports:语句更新DESCRIPTION文件.但是其他包都没有在那里列出; 只有match.fun通话似乎受到影响.

重新命名NAMESPACE,这是导入部分:

import(catspec)
import(foreach)
import(gdata)
import(Hmisc)
import(igraph)
import(lsa)
import(Matrix)
import(plyr)
import(RecordLinkage)
import(reshape)
import(RWeka)
import(stringr)
import(tm)
import(topicmodels)
Run Code Online (Sandbox Code Playgroud)

And*_*rie 7

我认为这是一个范围问题.虽然您已导入topicmodels,因此LDA您尚未导出这些功能,因此它们在搜索路径中不可用.

来自?match.fun:

match.fun 不打算在顶级使用,因为它将在调用者的父级中执行匹配.

因此,由于您ModelTopics在全局环境中使用,并且在全局环境LDA中不可用,因此match.fun调用失败.


在我看来,你有两个选择:

选项1:使用 get

另一种方法是使用get可以指定环境的地方.考虑一下:尝试使用在包中match.fun查找:print.ggplotggplot2

match.fun("print.ggplot")
Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object 'print.ggplot' of mode 'function' was not found
Run Code Online (Sandbox Code Playgroud)

由于print.ggplot未导出,match.fun无法找到它.

但是,get确实找到了:

get("print.ggplot", envir=environment(ggplot))
function (x, newpage = is.null(vp), vp = NULL, ...) 
{
    set_last_plot(x)
    if (newpage) 
        grid.newpage()
    data <- ggplot_build(x)
    gtable <- ggplot_gtable(data)
    if (is.null(vp)) {
        grid.draw(gtable)
    }
    else {
        if (is.character(vp)) 
            seekViewport(vp)
        else pushViewport(vp)
        grid.draw(gtable)
        upViewport()
    }
    invisible(data)
}
<environment: namespace:ggplot2>
Run Code Online (Sandbox Code Playgroud)

选项2:从topicmodels您需要的地方导出功能

如果您topicmodels在NAMESPACE中提供了必要的功能,那么您的代码也应该有效.

通过以下任一方式执

  • 使用选择性导出LDA和其他函数到命名空间@export
  • 使用Depends: topicmodels- 声明依赖项- 这与library(topicmodels)在全局环境中调用相同.这将有效,但可能是一种蛮力方法.这也意味着任何后续library调用都可以掩盖您的LDA功能,从而导致意外结果.