Frage

Wenn ich eine Klasse namens foo haben, dann ist es einfach, die summary Funktion zu überlasten

summary.foo = function(x, ...) print("bar")

Allerdings ist diese Technik nicht mit der sd Funktion arbeiten, das

ist
> bar = createFooClass()
> sd.foo = function(x, ...) print("Hi")
> sd(bar)
  error: is.atomic(x) is not TRUE

Was ist der richtige Weg, um diese Funktion zu überlasten?

War es hilfreich?

Lösung

Sie können eine beliebige nicht-generische Funktion kapern, machen es (S3) generic und stellen Sie die ursprüngliche Version der Standard-Version. Zum Beispiel:

## make an S3 generic for sd
sd <- function(x, ...) UseMethod("sd")
## take the usual definition of sd,
## and set it to be the default method
sd.default <- stats::sd
## create a method for our class "foo"
sd.foo = function(x, ...) print("Hi")

Ein letzter Schritt, wenn dies in einem Paket ist, ist ein ... Argument sd.default hinzufügen gab von Paketprüfungen zu ermöglichen:

formals(sd.default) <- c(formals(sd.default), alist(... = ))

geben:

> args(sd.default)
function (x, na.rm = FALSE, ...) 
NULL
> args(stats::sd)
function (x, na.rm = FALSE) 
NULL

Dies ergibt dann das gewünschte Verhalten:

> bar <- 1:10
> sd(bar)
[1] 3.027650
> class(bar) <- "foo"
> sd(bar)
[1] "Hi"

Dies ist in des Schreibens href="http://cran.r-project.org/doc/manuals/R-exts.html#Adding-new-generics"> dokumentiert R Erweiterungen manuell

Andere Tipps

Sie müssen eine neue generische für sd definieren.

Der einfachste Weg ist S4 zu verwenden, da sie den Standard „sd“ Methode behandelt automatisch:

setClass("foo", list(a = "numeric", names = "character"))

setGeneric("sd")

setMethod("sd", "foo", 
          function(x,  na.rm = FALSE){
              print("This is a foo object!")
              callNextMethod(x@a)
              })

tf <- new("foo", a = 1:10)
sd(tf)
#[1] "This is a foo object!"
#[1] 3.027650

Blick auf den Code von sd() --- es löst effektiv intern. Mit anderen Worten, ist es nicht eine generische Funktion, sondern eine einfache alte reguläre Funktion.

Am einfachsten kann nur sein, sd() zu Zweig auf class foo zu ändern.

scroll top