Аргументы и классы для написания (обобщенных) функций в R - PullRequest
5 голосов
/ 08 декабря 2011

Я хочу сделать небольшой пакет R из нескольких очень простых функций. Литература, которую я использую: «Создание пакетов R: учебник» и «Написание расширений R». Хотя я пытался, но я не совсем понимаю концепцию универсальных функций и методов и как обрабатывать аргументы в различных функциях.

Вот небольшой пример того, как выглядит мой код:

#Make generic function
f <- function(x,...) UseMethod("newmethod")

#Default method
f.default <- function(a,b=5,c=3,...){
    out <- a+b+c
    class(out) <- "fclass"
}

# Print method
print.f <- function(x,...){
    cat("Result:")
    print(x)
}

# Summary method
summary.f <- function(object,...){
    res <- object
    class(res) <- "fsummary"
    print(res)
}

# Plot method
plot.f <-function(x,p=0.3,...){}

У меня есть функция с именем f и значением по умолчанию f.default. На самом деле моя функция нуждается в нескольких аргументах (ни один из них не определен как x), так как мне сделать свою универсальную функцию? Метод print должен просто напечатать вывод f.default (в этом простом случае, аналогичном итоговому выводу). Метод plot.f использует выходные данные f.default и один дополнительный аргумент (обязательный). Как я могу написать эти функции правильно? Обычные методы используют такие аргументы, как «object» и «x» ... но, как я уже сказал, мне не нужны переменные x в моих функциях ... я немного запутался ... может быть, кто-то может помочь.

Если есть кто-то, кто хочет помочь мне с этой проблемой, я мог бы также отправить «настоящий» код R (не только этот вымышленный пример).

Ответы [ 2 ]

5 голосов
/ 08 декабря 2011

Вы попали в правильный беспорядок ...

Во-первых, ваша функция конструктора, вероятно, не должна быть универсальной / методом.Что-то вроде:

makefclass = function(a,b,c){
        l = list(a=a,b=b,c=c)
        class(l)="fclass"
        return(l)
      }

Тогда вы можете написать print.fclass:

print.fclass=function(x,...){
     cat("I'm an fclass!")
     cat("my abc is ",x$a,x$b,x$c,"\n")
}

Тогда вы сделаете:

> f=makefclass(1,2,3)
> f
I'm an fclass!my abc is  1 2 2 

Надеюсь, что поможет ...

4 голосов
/ 08 декабря 2011

Я исправил ваш код и добавил несколько комментариев о том, что исправил ...

ОБНОВЛЕНИЕ Как указывало @Spacedman, функция "constructor", вероятно, не должна быть универсальной. Но я оставлю это здесь, чтобы вы увидели как выполняется универсальная функция.

#Make generic function
# This is the "constructor" function...
# ... UseMethod should have the name of the function!
f <- function(x,...) UseMethod("f")

#Default method
# ... The class name should be the same as the constructor
f.default <- function(a,b=5,c=3,...){
    out <- a+b+c
    class(out) <- "f"
    out # must return the object out, not the class name!
}

# Print method
# The "f" part of "print.f" must be the same as the class!
print.f <- function(x,...){
    cat("Result for f: ")
    print(unclass(x)) # Must unclass to avoid infinite recursion
    # NextMethod(x) # Alternative, but prints the class attribute...
}

# Summary method
# Should return a summary object (and not print it!)
# Need a unique class for it ("fsummary")
summary.f <- function(object,...){
    res <- object
    class(res) <- "fsummary"
    res
}

# Now need to print the summary too:
print.fsummary <- function(x, ...) {
    cat("f summary!\n")
    # Nice summary print goes here...
}

# Plot method
plot.f <-function(x,p=0.3,...){ cat("PLOTTING!\n") }

# Try it out:

x <- f(3)
x # print x

y <- summary(x) # 
y # print summary

plot(x)
...