2011-12-08 14 views
5

Chcę zrobić małe paczka R z kilku bardzo prostych funkcji. Używam literatury "Tworzenie pakietów R: samouczek" i "Pisanie rozszerzeń R". Chociaż próbowałem, ale tak naprawdę nie rozumiem pojęcia ogólnych funkcji i metod oraz jak radzić sobie z argumentami w ramach różnych funkcji.Argumenty i klasy do pisania (ogólne) funkcje w R

Oto mały przykład jak mój kod wygląda następująco:

#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,...){} 

Mam funkcji o nazwie f z domyślnym f.default. W rzeczywistości moja funkcja wymaga kilku argumentów (nieokreślonych jako x), więc w jaki sposób mam wykonać funkcję generyczną? Metoda drukowania powinna po prostu wydrukować dane wyjściowe f.default (w tym prostym przypadku podobnym do wyniku podsumowania). Metoda plot.f używa wyjścia f.default i jednego dodatkowego argumentu (obowiązkowo). Jak mogę poprawnie napisać te funkcje? Zwykłe metody używają argumentów takich jak "object" i "x" ... ale jak już powiedziałem, nie potrzebuję żadnej zmiennej x w moich funkcjach ... Jestem trochę zdezorientowany ... może ktoś może pomóc.

Jeśli jest ktoś, kto jest chętny, by pomóc mi w rozwiązaniu tego problemu, mógłbym wysłać "prawdziwy" kod R (nie tylko ten fikcyjny przykład).

+3

Metody muszą być zgodne z ogólnymi. Jeśli twój ogólny zaczyna się od argumentu "x", to metody też muszą. –

Odpowiedz

5

Masz do prawej bałagan tutaj ...

pierwsze, czynność konstruktor prawdopodobnie nie powinny być ogólne/metoda. Coś jak:

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

Następnie można pisać print.fclass:

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

Następnie zrobić:

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

nadzieję, że pomoże ...

+0

Witam, @spacedman, jakoś twoja odpowiedź dezorientuje mnie jeszcze bardziej ... Podążam za przykładem w ["Tworzenie R Packages: Tutorial, strona 7] [1]. Ale do tej pory to, co przeczytałem, generyczne musi mieć te same argumenty, co metody, i to jest, gdzie mam do czynienia z moim przykładem ... [1]: http://cran.r-project.org/doc/contrib/Leisch-CreatingPackages.pdf – Johannes

+0

"makefclass" isn ' Jest to funkcja, która zwraca obiekt klasy f. Jedynym odniesieniem do generycznych w moim przykładzie jest to, że print.fclass jest metodą dla generycznego druku. print ma argumenty (x, ...) , podobnie jak print.fclass. – Spacedman

+0

Bardzo dziękuję ... Po prostu pomyliłem się z generycznym, ale nie muszę ustawiać niczego ogólnego. Dziękuję, wszystko działa teraz ... – Johannes

3

Naprawiłem Twój kod i umieścić komentarze na temat tego, co naprawiłem ...

UPDATE Jak zauważył @Spacedman, funkcja "constructor" prawdopodobnie nie powinna być generyczna. Ale zatrzymam to tutaj, aby zobaczyć, jak jest wykonywana funkcja ogólna.

#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) 
+0

Użyłeś generyczny konstruktor, który nie jest konieczny, ale jest przydatny, gdy możesz budować z różnych typów argumentów, tak, że f (onething) tworzy "f" w zależności od tego, co "onething". Jest to prawdopodobnie rodzaj funkcjonalności, którą możesz chcieć zastosować w metodach "as.f()" i zachować dość specjalistyczną konstrukcję. YMMV. – Spacedman

+0

@Spacedman - Dobra uwaga.Zgadzam się, że konstruktorzy w większości przypadków powinni być nietypowi. Zaktualizowałem swoją odpowiedź. – Tommy

Powiązane problemy