12

I am a newbee in programming, and I run into an issue with R about generic function: how to write it when there are multiple inputs?

For an easy example, for dataset and function

z <- c(2,3,4,5,8)
calc.simp <- function(a,x){a*x+8}
# Test the function:
calc.simp(x=z,a=3)
[1] 14 17 20 23 32

Now I change the class of z: class(z) <- 'simp' How should I write the generic function 'calc' as there are two inputs? My attempts and errors are below:

calc <- function(x) UseMethod('calc',x)
calc(x=z)
Error in calc.simp(x = z) : argument "a" is missing, with no default

And

calc <- function(x,y) UseMethod('calc',x,y)
Error in UseMethod("calc", x, y) : unused argument (y)

My confusion might be a fundamental one as I am just a beginner. Please help! Thank you very much!

  • 1
    What do you expect to be returned from `calc(x=z)`? You aren't giving your function a value for `a` and your function depends on it. Also you can let your generic function know there may be other argumets with `calc <- function(x, ...) UseMethod('calc',x)` – MrFlick Apr 03 '19 at 19:45
  • What do you want your function to do? Your first function (calc.simp) still works even after changing the class of z. – Luis Apr 03 '19 at 19:49
  • @MrFlick I simply want to test whether my generic function can work! It helps me understand the dispatch mechanism better. The 'function(x,...)' works perfectly for my question. Thank you so much! :) – Branda Newbee Apr 03 '19 at 19:58
  • question is about dispatching? didn't see this keyword anywhere on this page, hence adding it here. – chinsoon12 Apr 04 '19 at 00:24

1 Answers1

10

I'd suggest you model your generic function off of the template used by innumerable base R functions as, e.g., mean:

> mean
function (x, ...) 
UseMethod("mean")

In your case, that would translate to the following generic which (if I understand your question correctly) works just fine:

calc <- function(x, ...) UseMethod('calc')

calc.simp <- function(a, x) {
    x <- unclass(x)
    a * x + 8
}


## Try it out

z <- c(2,3,4,5,8)
class(z) <- "simp"

calc.simp(x = z, 10)
## [1] 28 38 48 58 88

calc(x = z, 10)
## [1] 28 38 48 58 88
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455