I'm working on an R package where one of the functions contains a match.fun
call to a function in a package that's imported to the package namespace. But on loading the package, the match.fun
call can't find the function name. From Hadley Wickham's description I think I'm doing everything right, but this is clearly not the case.
Example:
# 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)
}
And then in 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
From my understanding of namespaces, the match.fun
call should have access to the package namespace, which should include the topicmodels
functions. But that doesn't appear to be the case here. If I import topicmodels
directly to the global namespace for the R session, then this works.
Any help is much appreciated. This is R64 2.14.1 running on OSX.
UPDATE: The package is here
Re the DESCRIPTION file, perhaps that's the problem: roxygen2 doesn't update the DESCRIPTION file with Imports:
statements. But none of the other packages are listed there, either; only the match.fun
calls appear to be affected.
Re the NAMESPACE extract, here's the import section:
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)
I believe this an issue of scope. Although you have imported topicmodels
and thus LDA
, you haven't exported these functions, so they aren't available in the search path.
From ?match.fun
:
match.fun
is not intended to be used at the top level since it will perform matching in the parent of the caller.
Thus, since you are using ModelTopics
in the global environment, and LDA
isn't available in the global environment, the match.fun
call fails.
It seems to me you have two options:
get
An alternative would be to use get
where you can specify the environment. Consider this: try to use match.fun
to find print.ggplot
in the package ggplot2
:
match.fun("print.ggplot")
Error in get(as.character(FUN), mode = "function", envir = envir) :
object 'print.ggplot' of mode 'function' was not found
Since print.ggplot
isn't exported, match.fun
can't find it.
However, get
does find it:
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>
topicmodels
that you needIf you make the necessary functions from topicmodels
available in your NAMESPACE, your code should also work.
Do this by either:
LDA
and other functions to the namespace using @export
Depends: topicmodels
- this is the same as calling library(topicmodels)
in the global environment. This will work, but is possibly a bit of a brute force approach. It also means that any subsequent library
call can mask your LDA
function, thus leading to unexpected results.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With