Domanda

Se ho un una classe denominata foo, allora è semplice sovraccaricare la funzione summary

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

Tuttavia questa tecnica non funziona con la funzione sd, che è

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

Qual è il modo corretto di sovraccarico questa funzione?

È stato utile?

Soluzione

È possibile dirottare qualsiasi funzione non generico, renderlo (S3) generico e impostare la versione originale per essere la versione di default. Ad esempio:

## 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")

Un passo finale, se questo è in un pacchetto, è quello di aggiungere un argomento ... per sd.default per consentire il passaggio dei controlli del pacchetto:

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

dando:

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

Questo dà poi il comportamento desiderato:

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

Questo è documentato nella sezione 7.1 della scrittura R estensioni manuale

Altri suggerimenti

È necessario definire un nuovo generico per sd.

Il modo più semplice è quello di utilizzare S4, perché gestisce il metodo predefinito "sd" automaticamente:

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

guardare il codice di sd() --- esso invia in modo efficace internamente. In altre parole, non è una funzione generica, ma una semplice funzione di regolare vecchi.

Il metodo più semplice può essere solo di modificare sd() al ramo su classe Foo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top