Mit sd als generische Funktion in R
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
> 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?
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"
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.