andrew
andrew

Reputation: 2574

Method dispatching in R based on presence of specific parameters

I have two function, f1(...) and f2(...). I would like to group them under a single function f(...) and conditionally pass the parameters of f(...) to either f1 or f2. If f(...) is passed a parameter called special.param, then I will call f2(...). Otherwise I will call f1(...). I don't believe UseMethod can handle this since it will check for the class of the first parameter rather than the presence of a certain parameter. What is the correct way to do this? Is there a way to check the names of the parameters in ...?

Upvotes: 2

Views: 37

Answers (1)

Martin Morgan
Martin Morgan

Reputation: 46866

If these are your functions and p is your special parameter

f1 <- function(..., p) "f1"
f2 <- function(..., p) "f2"

In S4 (maybe that's not what you're looking for...) you could write a generic that dispatches on the special parameter

setGeneric("f", function(..., p) standardGeneric("f"),
    signature="p", useAsDefault=f1)

and implement a method that is invoked when the parameter is missing

setMethod("f", "missing", f2)

A more symmetric implementation with the same consequence would be

setGeneric("f", function(..., p) standardGeneric("f"), signature="p")
setMethod("f", "ANY", f1)
setMethod("f", "missing", f2)

with

> f(p=1)
[1] "f1"
> f()
[1] "f2"

A simpler base R alternative (implied by a comment and deleted answer) is

f <- function(..., p) {
    if (missing(p))
        f2(...)
    else
        f1(..., p=p)
}

This would become tedious and error prone if there were more than two alternatives for p (e.g., missing vs. numeric vs. logical) or if dispatch were on more than 1 argument f(x, ..., p). The S4 approach also means that available methods are discoverable (showMethods(f)) but carry additional documentation and NAMESPACE burdens when implemented in a package.

Upvotes: 3

Related Questions