混合...与s4泛型方法中的正式args

时间:2015-04-10 14:12:58

标签: r ellipsis s4

来自?dotsMethods

 Beginning with version 2.8.0 of R, S4 methods can be dispatched
 (selected and called) corresponding to the special argument “...”.
 Currently, “...” cannot be mixed with other formal arguments:
 either the signature of the generic function is “...” only, or it
 does not contain “...”.  (This restriction may be lifted in a
 future version.)

以下是EBImage包中的一些代码:

## image IO, display
setGeneric ("image", function (x, ...) standardGeneric("image") )

## statistics
setGeneric ("hist", function (x, ...) standardGeneric("hist") )

这显然违反了“...” cannot be mixed with other formal arguments规则。这是否意味着限制已被解除但没有记录?

2 个答案:

答案 0 :(得分:5)

您引用的部分中的关键字是'已发送'。这里

setGeneric("foo", function(x, ...) standardGeneric("foo"))

您可以根据' x'。

的类别编写方法
.A = setClass("A", "integer")
.B = setClass("B", "integer")
setMethod("foo", "A", function(x, ...) "foo,A-method")

' ...'仍然可以使用,例如,提供特定于方法的参数,但没有可用于" ..."

的调度
setMethod("foo", "B", function(x, barg, ...) sprintf("barg=%d", barg))

> foo(.B(), barg=123)
[1] "barg=123"

这就是EBImage使用的方式" ...",这是一个非常常见的用例。

下面

setGeneric("bar", function(...) standardGeneric("bar"))

如果所有类都相同,您可以编写在" ..."上发送的方法

setMethod("bar", "A", function(...) "bar,A-method")

> bar(.A(), .A())
[1] "bar,A-method"
> bar(.A(), .B())
Error in standardGeneric("bar") : 
  no method or default matching the "..." arguments in bar(.A(), .B())
> setMethod("bar", c("A", "B"), function(...) "bar,A,B-method")
Error in matchSignature(signature, fdef) : 
  more elements in the method signature (2) than in the generic signature (1) for function 'bar'

上面使用隐式规则来确定签名,并且调度的参数由getGeneric()显示,其中输出表示'可以为参数定义方法:',例如,

> getGeneric("foo")
standardGeneric for "foo" defined from package ".GlobalEnv"

function (x, ...) 
standardGeneric("foo")
<environment: 0x2ba550a0>
Methods may be defined for arguments: x
Use  showMethods("foo")  for currently available ones.
> getGeneric("bar")
standardGeneric for "bar" defined from package ".GlobalEnv"

function (...) 
standardGeneric("bar")
<environment: 0x2c127e58>
Methods may be defined for arguments: ...
Use  showMethods("bar")  for currently available ones.

R似乎可以让你定义在x上混合发送的泛型......

> setGeneric("baz", function(x, ...) standardGeneric("baz"), 
             signature=c("x", "..."))
[1] "baz"

但事实并非如此

> getGeneric("baz")
standardGeneric for "baz" defined from package ".GlobalEnv"

function (x, ...) 
standardGeneric("baz")
<environment: 0x2c704cc0>
Methods may be defined for arguments: x
Use  showMethods("baz")  for currently available ones.

答案 1 :(得分:0)

是的,您可以在...泛型中使用s4和其他正式参数。您应该记住将其作为setMethod函数的参数之一包含在其中。