2011-01-18 12 views
8

अगर मैं एक एक वर्ग 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 

इस फ़ंक्शन को ओवरलोड करने का सही तरीका क्या है?

उत्तर

7

आप किसी भी गैर सामान्य समारोह का अपहरण कर सकते हैं, यह (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" 

इस लेखन आर एक्सटेंशन मैनुअल

+0

आर-डेवेल ईमेल करने के लिए बेहतर है और अनुरोध है कि 'sd' (या बेहतर, 'var') सामान्य बनाया जाए। – hadley

+0

@ हैडली सहमत हुए, लेकिन साथ ही आर कोर को बनाए रखने की आवश्यकता के साथ, कुछ सामान्य बनाने के दौरान प्रदर्शन प्रदर्शन हुआ, इसलिए आर एक्स में शब्द और सलाह। मैनुअल। –

+0

मैं उन बहाने नहीं खरीदता हूं। जेनेरिक और var नहीं क्यों मतलब चाहिए? – hadley

1

sd() के कोड को देखें --- यह प्रभावी ढंग से आंतरिक रूप से प्रेषित होता है। दूसरे शब्दों में, यह एक सामान्य कार्य नहीं है बल्कि एक सादा पुराना नियमित कार्य है।

क्लास फू पर शाखा में sd() को संशोधित करना सबसे आसान हो सकता है।

+0

काफी मजेदार है कि मैं क्या किया है की section 7.1 में दर्ज है, लेकिन यह सिर्फ "गलत" और थोड़ा अजीब लग रहा था। – csgillespie

3

आपको sd के लिए एक नया जेनेरिक परिभाषित करने की आवश्यकता है।

सबसे आसान तरीका है, एस 4 उपयोग करने के लिए है, क्योंकि यह डिफ़ॉल्ट "एसडी" स्वचालित रूप से विधि संभालता है:

setClass("foo", list(a = "numeric", names = "character")) 

setGeneric("sd") 

setMethod("sd", "foo", 
      function(x, na.rm = FALSE){ 
       print("This is a foo object!") 
       callNextMethod([email protected]) 
       }) 

tf <- new("foo", a = 1:10) 
sd(tf) 
#[1] "This is a foo object!" 
#[1] 3.027650 
संबंधित मुद्दे