34

Henrik Bengtsson has provided the internet with a nice way of creating S3 generics in R without having to bother whether they were already created before... in 2002.

What his function setGenericsS3 does, is basically:

  • check whether the name is fine
  • check whether there is a function with that name

if so,

  • check whether it is a generic
  • in case it's not, rename it as .default and create a generic

if not, just create the generic.

This code proved very useful to automatically create generics when there was none available in your own packages. As we moved quite past this R era, I was wondering what the correct way is to achieve the same in R now. I can't find an isS3Generic() or similar function in R, and the code of Henrik Bengtsson originates from long before the obligatory namespaces as introduced in R 2.14. I remember I've seen other ways of achieving the same, but can't locate them.

EDIT : I'm specifically looking for S3. The function isGeneric() only works for S4, eg for anova (which is a S3 generic) :

> isGeneric('anova')
[1] FALSE
> anova
function (object, ...) 
UseMethod("anova")
<bytecode: 0x04dc7a18>
<environment: namespace:stats>
shosaco
  • 5,915
  • 1
  • 30
  • 48
Joris Meys
  • 106,551
  • 31
  • 221
  • 263
  • See `?isGeneric` in the 'methods' package. – IRTFM Dec 12 '11 at 14:38
  • 1
    @DWin That's S4, not S3. – Joris Meys Dec 12 '11 at 14:45
  • Maybe: `isGenericS3 = function(FUN) body(match.fun(FUN))[[1]] == 'UseMethod'`. Perhaps there is a more general solution as I believe some base methods dispatch internally without visibly using UseMethod. – Charles Dec 12 '11 at 16:35
  • @Charles I'm thinking along the same lines. Problem starts if you want to use that to determine whether or not you have to create an S3 generic within your package... – Joris Meys Dec 12 '11 at 16:51
  • Interesting question. If you end up needing to piece something together, `.knownS3Generics` might be useful. It does know about base group generic functions (e.g. `Math` and `Ops`) that don't include `'UseMethod'" in their body. – Josh O'Brien Dec 12 '11 at 16:53
  • @JoshO'Brien : Thx for the tip! very useful indeed. – Joris Meys Dec 13 '11 at 09:18
  • So Josh, whey not post as answer `isS3Generic<- function(fname) fname %in% names(.knownS3Generics)` and get this off the unanswered queue? – IRTFM Dec 18 '11 at 15:50
  • Or if you want to work on the unquoted actual function name then `isS3Generic<- function(fname) gsub("\\(|\\)", "", deparse(sys.call()[2])) %in% names(.knownS3Generics)` – IRTFM Dec 18 '11 at 16:03
  • @DWin because that only recognizes the ones in that list. You could copy the code from the link I gave and update it to R 2.14 which is what I was planning to do if I find the time somewhere... – Joris Meys Dec 19 '11 at 10:25

1 Answers1

1

You can use isGenericS3 function of the R.methodsS3 package. Please see the code below:

library(R.methodsS3)
isGenericS3(anova)
# [1] TRUE
Artem
  • 3,304
  • 3
  • 18
  • 41