2011-12-08 26 views
5

寫入(通用)功能,我想作一個小小的[R包裝出來的一些非常簡單的功能。我使用的文獻是「創建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),所以我該如何使我的泛型函數? 打印方法應該簡單地打印f.default的輸出(在簡單情況下類似於彙總輸出)。 plot.f方法使用f.default的輸出和一個附加參數(強制性)。我該如何正確編寫這些功能?通常的方法使用「object」和「x」等參數......但正如我所說的,我的函數中不需要任何變量x ......我有點困惑......也許有人可以提供幫助。

如果有一個人在那裏如何願意幫我解決這個問題,我也可以發送「真正的」 R代碼(不只是這個虛構的例子)。

+3

的方法必須與通用保持一致。如果你的泛型以參數'x'開頭,那麼方法也必須。 –

回答

5

你得進到這裏亂七八糟......

首先,你的構造函數可能不應該是通用/方法。喜歡的東西:

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 

希望幫助...

+0

嗨, @spacedman,不知何故你的回答讓我困惑甚至更多...我遵循例如[「創建R程序包:一個教程,第7頁] [1]。但到目前爲止,我讀通用必須有相同的參數的方法,而這正是我與我的例子struggeling ... [1]:http://cran.r-project.org/doc/contrib/Leisch-CreatingPackages.pdf – Johannes

+0

「makefclass」 ISN」它不是一個方法,它只是一個返回fclass對象的函數,在我的例子中泛型的唯一參考是print.fclass是print generic的一個方法print具有args(x,...) ,也是如此print.fclass。 – Spacedman

+0

謝謝了很多...我只是弄糊塗了與通用的,但我並不需要設置任何通用的..謝謝你,一切正常,現在... – Johannes

3

,我已經修復你的代碼,並在我所固定的一些意見...

UPDATE正如@Spacedman指出的那樣,「構造函數」函數可能不是通用的。但我會保留在這裏,所以你看到如何完成一個通用功能。

#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

您已經使用一個通用的構造函數,這是不必要的,但是在你可能正在構建的時候很方便來自不同類型的論據,以便f(onething)根據'onething'是什麼來做'f'。它可能是你想放入「as.f()」方法的功能,並保持構造函數相當專業化。因人而異。 – Spacedman

+0

@Spacedman - 好點。我同意在大多數情況下構造函數應該是非泛型的。我更新了我的答案。 – Tommy