Problem with "setMethod" in R package
On 01/26/2011 05:08 AM, Pascal A. Niklaus wrote:
Dear all, My apologies for re-posting this question, but I have not found any solution to my problem so far. I also think that my post may have been overseen due to the posting time and high traffic on this list. I experience a problem in implementing a S4 class in a package and would appreciate your help in this matter. The class is implemented using Rcpp, which works well. I then extend the class with R functions, adding them as methods with a call to setMethod(...). When I do this outside the package (after loading the package with "library(...)"), everything works smoothly. However, when I try to incorporate the call to setMethod(...) in the package code itself, the only way I get it to work is to include the call in .onLoad(...) or .onAttach(...). This works, but when loading the library I get the messages "creating new generic function for "plot" in ".GlobalEnv", as well as "no definition for class "Rcpp_rothC""... Again, the code works, but the messages let me presume that I add the methods in the wrong way or miss-specify name spaces, class names, or something else. Thank you for your advice. Pascal (The error message and the relevant parts of the package files are pasted below, together with my related questions as "comments".)
showMethods("plot")
Function "plot":
<not a generic function> # I am surprised about this --
# why isn't plot a generic function?
library("RrothC2")
Loading required package: Rcpp
Loading required package: pascal
Creating a new generic function for "plot" in ".GlobalEnv"
in method for ?plot? with signature ?x="Rcpp_rothC",y="missing"?: no
definition for class "Rcpp_rothC"
# class seems not to be known
# at this stage.
# but where should I put setMethod()?
r1 <- new(rothC$rothC); class(r1) # class is known by now
[1] "Rcpp_rothC" attr(,"package") [1] ".GlobalEnv"
plot(r1) # "plot" is dispatched correctly
showMethods("plot")
Function: plot (package graphics) # now "plot" from graphics shows up
x="ANY", y="ANY" # why was it missing before?
x="Rcpp_rothC", y="missing"
######### FILE rcpp_rothC_module.h #########
class rothC { ... }
######### FILE rcpp_rothC_module.cpp #########
using namespace Rcpp ;
RCPP_MODULE(rothC) {
class_<rothC>("rothC")
.constructor()
...
}
######### FILE rcpp_rothC.R #########
Rcpp_rothC.plot <- function(x,y,...) { ... }
########## FILE zzz.R ##########
.NAMESPACE <- environment()
rothC <- new( "Module" )
.onLoad <- function(libname, pkgname) {
unlockBinding( "rothC" , .NAMESPACE )
assign( "rothC", Module( "rothC" ), .NAMESPACE )
setMethod(f="plot",signature(x="Rcpp_rothC",y="missing"),definition=Rcpp_rothC.plot,where=.GlobalEnv);
lockBinding( "rothC", .NAMESPACE )
}
.onAttach <- function(libname, pkgname) {}
.onUnload <- function(libname, pkgname) { gc(); }
Hi Pascal --
Normally one would arrange code (e.g., using the Collate: field of the
DESCRIPTION file to define S4 classes, generics, then methods, equivalent to
setClass("Foo")
setGeneric("plot") ## promote plot to S4 generic
setMethod("plot, c(x="Foo", y="missing"), Rcpp_rothC.plot)
One would not normally specify a 'where' argument to setMethod; by
default the method is created in the 'top' environment at the time the
package is installed, which is the package name space. It is not usually
necessary to include setMethod and friends in .onLoad.
I do not use Rcpp, but one would normally have to write R code to wrap
the C++ object, e.g., an S4 class with an 'externalptr' slot to contain
the address of the object, plus methods to interact with the object.
This part of the problem sounds like a question for the Rcpp help list.
Martin
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Computational Biology Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: M1-B861 Telephone: 206 667-2793