I work with a bunch of actuaries who recently switched from matlab to R.
While working on s3 classes, we could not figure out how to write a generic that may or may not already be defined and not interfere with it.
For ex: lets pretend we don't a'ready know that a generic exists for plot
. So we write our s3 class, add a generic for plot
:
plot <- function(x){ UseMethod("plot", x)}
then I have a function:
plot.myclass <- function(x){{#some code)}
The generic above will cause plot
to stop working for other objects that have a plot
function because of how we only require x
and not x
, y
, etc.
I think this may be a common question that others may have. How can you write a generic function without interfering if it is already defined or may be defined?
I thought I made some headway on this by using a package and a namespace.
I manually exported my plot.myclass
in the namespace file and this seemed to work.
I can call plot
with myclass
and plot
can still be called from other objects.
But when I switched to roxygen and used the export attribute to both the generic plot
and plot.myclass
this did not work as expected.
Maybe there is a way to force the s3 plot.myclass
to be exported using export
rather then s3method
through roxygen.
I thought this may be something worth adding to your book. I wouldn't be surprised if other noobs wanted to do something like this as well.
My code looks like:
#' @export
my_class_less <- function(x=1){
object <- list(my_val = 666*x, our_val=999*x)
class(object) <- "my_class_less"
return (object)
}
plot <- function(x){
UseMethod("plot", x)
}
#' @export
plot.my_class_less <- function(obj) {
obj$my_val <- 1234
return(obj)
}
The namespace file looks like:
# Generated by roxygen2 (4.0.2): do not edit by hand
S3method(plot,my_class_less)
export(my_class_less)
This situation can happen if a user defines a generic with its own signature in a package, but another package is loaded first with a different signature.
Stephen