Использование SD в качестве общей функции в R
Вопрос
Если у меня есть класс, называемый foo
, тогда просто перегрузить summary
функция
summary.foo = function(x, ...) print("bar")
Однако эта техника не работает с sd
функция, то есть
> bar = createFooClass()
> sd.foo = function(x, ...) print("Hi")
> sd(bar)
error: is.atomic(x) is not TRUE
Каков правильный способ перегрузки этой функции?
Решение
Вы можете захватить любую негенерическую функцию, сделать ее (S3) универсальным и установить исходную версию в качестве версии по умолчанию. Например:
## 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")
Последний шаг, если это в пакете, - добавить ...
аргумент sd.default
Чтобы разрешить прохождение проверки пакетов:
formals(sd.default) <- c(formals(sd.default), alist(... = ))
дар:
> args(sd.default)
function (x, na.rm = FALSE, ...)
NULL
> args(stats::sd)
function (x, na.rm = FALSE)
NULL
Это дает желаемое поведение:
> bar <- 1:10
> sd(bar)
[1] 3.027650
> class(bar) <- "foo"
> sd(bar)
[1] "Hi"
Это задокументировано в Раздел 7.1 Руководство по письму R расширения
Другие советы
Вам нужно определить новый общий для sd
.
Самый простой способ - использовать S4, потому что он автоматически обрабатывает метод по умолчанию «SD»:
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
Посмотрите на код sd()
--- Это эффективно отправляет внутреннюю. Другими словами, это не общая функция, а простая старая обычная функция.
Самым простым может быть просто изменение sd()
чтобы разветвляться на классе Foo.