当前位置 : 主页 > 手机开发 > 其它 >

如何在R中继承S4类正确使用有效性函数

来源:互联网 收集:自由互联 发布时间:2021-06-19
假设您有一个S4类“A”,以及一个具有附加功能的子类“B”.每个都有自己的有效性检查 – B应该只检查其他功能.现在在B的初始化中,我想从A类的对象开始,然后用附加功能修改它.然而
假设您有一个S4类“A”,以及一个具有附加功能的子类“B”.每个都有自己的有效性检查 – B应该只检查其他功能.现在在B的初始化中,我想从A类的对象开始,然后用附加功能修改它.然而,这会产生问题,我猜我在这个例子中违反了R的假设.

这是虚拟代码:

setClass(Class="A",
         representation=
         representation(x="numeric"),
         validity=
         function(object){stopifnot(x > 0)})

setMethod("initialize",
          signature(.Object="A"),
          function(.Object,
                   ...,
                   z){
              x <- get("z") + 1
              callNextMethod(.Object,
                             ...,
                             x=x)
          })

setClass(Class="B",
         contains="A",
         representation=
         representation(y="numeric"),
         validity=
         function(object){stopifnot(y > 0)})

setMethod("initialize",
          signature(.Object="B"),
          function(.Object,
                   ...,
                   bla){

              .Object <- callNextMethod(.Object,
                                        ...)

              .Object@y <- .Object@x + bla
              return(.Object)
          })

test <- new("B",
            z=4,
            bla=5)

如果我尝试创建“测试”对象,我得到:

Error in stopifnot(x > 0): object 'x' not found

你知道我怎么能做得更好吗?

非常感谢提前!
最好的祝福
丹尼尔

对S4中假设的一个方便的测试是,在非VIRTUAL类上调用没有参数的new()需要返回一个有效的对象.你的班级没有通过这个考试

> validObject(new("A"))
Error in get("z") : argument "z" is missing, with no default

一个选项将在initialize方法中为z提供默认值,或者(我的偏好)在类定义中使用原型并与构造函数结合使用.此外,有效性函数应返回TRUE(如果有效)或描述其无效的字符向量.所以我写了你的班级’A’

.A <- setClass(Class="A",
    representation(x="numeric"),
    prototype(x=1),
    validity= function(object) {
        msg <- NULL
        if (length(object@x) != 1 || object@x <= 0)
            msg <- c(msg, "'x' must be length 1 and > 0")
        if (is.null(msg)) TRUE else msg
    })

(setClass()的返回值只是在一个语义更丰富的函数调用中包装new()).

> validObject(.A())
[1] TRUE

而不是使用initialize方法(这是正确实现的棘手 – 它也是一个复制构造函数)我写

A <- function(z, ...)
    .A(x=z+1, ...)

其行为与预期一致

> A()
Error in initialize(value, ...) (from valid.R!7685pfr#2) : 
  argument "z" is missing, with no default
> A(1)
An object of class "A"
Slot "x":
[1] 2

我认为将这些原则扩展到“B”应该是直截了当的,并且是一个很好的“读者练习”!

网友评论