Take the 2-minute tour ×

If only the named arguments of a S4 generic function are defined in a method, substitute() works as expected:

> setGeneric("fS4", function(x, ...) standardGeneric("fS4"))
> setMethod("fS4", signature("numeric"),
+     function(x, ...) deparse(substitute(x))
+ )
[1] "fS4"
> fS4(iris[,1])
[1] "iris[, 1]"

However, if one adds an extra named argument to the method's definition, substitute() ceases to correctly return the argument as it was passed:

+     function(x, y, ...) deparse(substitute(x))
+ )
[1] "fS4"
> fS4(iris[,1])
[1] "x"

Any clues on why this happens and, most importantly, how it can be worked around?

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

Take a look at

showMethods(fS4, includeDef=TRUE)

which shows

Function: fS4 (package .GlobalEnv)
function (x, ...) 
    .local <- function (x, y, ...) 
    .local(x, ...)

The way that S4 implements methods with signatures that differ from the generic is by creating a '.local' function with the modified signature, inside a function with the generic signature. substitute then evaluates in an incorrect environment. The underlying problem is not related to S4

> f = function(x) deparse(substitute(x))
> g = function(y) f(y)
> f(1)
[1] "1"
> g(1)
[1] "y"
> h = function(...) f(...)
> h(1)
[1] "1"

and any attempts to evaluate in the the 'right' environment will be thwarted by arbitrary constructs provided by users.

share|improve this answer
add comment

Your Answer


