【问题标题】:Mixing ... with formal args in s4 generic method在 s4 泛型方法中混合 ... 与形式参数
【发布时间】:2023-03-12 08:51:01
【问题描述】:

来自?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 规则。这是否意味着限制已经解除但没有记录?

【问题讨论】:

    标签: r ellipsis s4


    【解决方案1】:

    您引用的部分中的关键字是“已调度”。这里

    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()显示,其中输出指示'Methods may be defined for arguments:',例如,

    > 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.
    

    【讨论】:

      【解决方案2】:

      是的,您可以将...s4 泛型中的其他形式参数一起使用。您应该记得将其作为setMethod 函数的参数之一。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-29
        • 2021-05-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多