Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is `predict` not a generic function?

Tags:

r

why is predict not a generic function? isGeneric('predict') is FALSE but isGeneric('summary') and isGeneric('print') is TRUE. All of them have methods, which can be listed with methods('predict') etc? So predict is not a generic function as described here (also obvious from looking at class) but still dispatches methods depending on the object passed to it (e.g. predict.lm or predict.glm). So there is a different way R dispatches methods? How can I test whether a function has methods so that all of the examples above are true? Yes, I can test the length of methods('predict') but that produces a warning for functions without methods.

like image 800
user2503795 Avatar asked Dec 02 '22 20:12

user2503795


1 Answers

For starters, none of those functions are generic by your test:

> isGeneric('predict')
[1] FALSE
> isGeneric('summary')
[1] FALSE
> isGeneric('print')
[1] FALSE

Let's try again...

> isGeneric("summary")
[1] FALSE
> require(sp)
Loading required package: sp
> isGeneric("summary")
[1] TRUE

What's going on here? Well, isGeneric only tests for S4 generic functions, and when I start R summary is an S3 generic function. If a package wants to use S4 methods and classes and there already exists an S3 generic function then it can create an S4 generic.

So, initially summary is:

> summary
function (object, ...) 
UseMethod("summary")
<bytecode: 0x9e4fc08>
<environment: namespace:base>

which is an S3 generic. I get the sp package...

> require(sp)
Loading required package: sp
> summary
standardGeneric for "summary" defined from package "base"

function (object, ...) 
standardGeneric("summary")
<environment: 0x9f9d428>
Methods may be defined for arguments: object
Use  showMethods("summary")  for currently available ones.

and now summary is an S4 standard generic.

S3 generic methods despatch (usually) by calling {generic}.{class}, and this is what UseMethod("summary") does in the S3 summary generic function.

If you want to test if a function has methods for a particular class, then you probably have to test that it has an S4 method (using the functions for S4 method metadata) and an S3 method (by looking for a function called {generic}.{class}, such as summary.glm.

Great eh?

like image 81
Spacedman Avatar answered Dec 05 '22 08:12

Spacedman