3

Here, the top answers describes a good way to make a method dispatch on both S3 and S4 objects. However, that way only works when both methods have the same signature.

Is there a way to create an S4 method for median with a different signature?

For example, the following does not work:

setGeneric("median")
median.Foo <- function(arg1, arg2, ...){}
setMethod("median", "Foo", median.Foo)

When installing the libary, there is an error saying that formal arguments are missing, x and na.rm, which are the arguments for the original median function.

I would like to avoid the solution at the top of author's post.

Community
  • 1
  • 1
Jon Claus
  • 2,862
  • 4
  • 22
  • 33
  • That does not look like a correct method for creating an S4 function. The formalism `fn_name.class_name <- function(...) {body}` is for defining S3 functions. Read `?setMethod` and look at the examples there. – IRTFM Sep 26 '13 at 15:02
  • I was just replicating part of the code in the link. Normally I don't structure my function names like that. – Jon Claus Sep 26 '13 at 15:11
  • You need to look at the answer by Marin Morgan (and on the help page). He knows more than the questioner. – IRTFM Sep 26 '13 at 15:12
  • In Marin's code, he calls `setMethod` with a third argument in the form `function.class". In this case I want a S4 method for `median` for class `Foo` and `median.default` (the built in S3 method) called otherwise. – Jon Claus Sep 26 '13 at 15:21
  • Have you solved the problem? – rankthefirst Oct 30 '15 at 23:33

1 Answers1

1

setGeneric("median") creates an S4 generic with the same signature as stats::median

> stats::median
function (x, na.rm = FALSE) 
UseMethod("median")
<environment: namespace:stats>

so you could write methods

median.Foo <- function(x, na.rm=FALSE) {}
setMethod(median, "Foo", median.Foo)

I think the package check message would be addressed by

setGeneric("median", function(arg1, arg2, ...) standardGeneric("median"))

and then as you write. But probably that is a bad idea because now the S3 methods are masked by your function

> median(1:5)
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function 'median' for signature '"integer"'

I think you're stuck with the default arguments or a modified function name. The title of your post says Median and R is case sensitive... but that's also a bad idea.

Martin Morgan
  • 45,935
  • 7
  • 84
  • 112
  • OK, a bit of a bummer than I'm stuck with default arguments. What I did was mask the default `median` function (in the `stats` package) using an S4 method with a `...` construct in the argument list and then just dispatch to the built in `median` like the OP did in the link. When I introduce the library in R, it gives me a warning saying that `The following object is masked from ‘package:stats’: median`. Is there a way to make so such a message doesn't occur? `suppressWarnings` doesn't work with the `library` function. – Jon Claus Sep 26 '13 at 21:12
  • `suppressPackageStartupMessages()` quietens the message (not a warning, technically), but the message is not incorrect so... – Martin Morgan Sep 27 '13 at 00:12