【问题标题】:how to define a dynamic constructor in R for s4 object如何在 R 中为 s4 对象定义动态构造函数
【发布时间】:2015-05-02 09:25:39
【问题描述】:

是否可以在 R 中为 S4 对象定义动态构造函数?我所说的动态是指:

firstClass <- setClass(Class = "firstClass",slots = c(Name = "character", ID = "numeric"))

现在我想定义一个智能的构造函数,即它检查函数调用提供了哪些参数,并通过将插槽设置​​为默认值或提供的参数来创建一个名为“firstClass”的对象。例如

firstClass <- function(Name, ID){
  if(missing(Name) & missing(ID)){
    return(new(Class = firstClass))
  }
  if(missing(Name) & !missing(ID)){
    return(new(Class = firstClass,ID = ID))
  }
  if(!missing(Name) & missing(ID)){
    return(new(Class,Name = Name))
  }
  if(!missing(Name) & !missing(ID)){
    return(new(Class, Name = Name, ID = ID))
  }
}

显然,还应该进行一些健全性检查。这个构造函数完全符合我的要求,具体取决于它构造对象的调用。然而,对于一个简单的类(很少的插槽),这是可以的,但是随着插槽的增加,复杂性会增加。所以我想知道是否有一种优雅的方式来做到这一点。

【问题讨论】:

  • 您是否尝试过使用不同的编号运行默认的firstClass()。论据?它已经做了你想做的事。

标签: r s4


【解决方案1】:

使用原型提供合理的默认值

.firstClass <-
    setClass(Class = "firstClass",
             representation = representation(
               Name = "character",
               ID = "integer"),
             prototype=c(ID=0L))

在构造函数中使用默认值作为参数,并在必要时强制转换为适当的类型

firstClass <- function(Name=character(), ID=0L)
    .firstClass(Name=Name, ID=as.integer(ID))

(.firstClassnew("firstClass", ...) 的一个轻量级包装,对我来说,它在实现细节(调用 new() 来构造一个类)和类构造的接口之间提供了一点分离。firstClass() 是第二个和更有用的层,以不需要底层类知识的方式向用户公开对象构造的必要参数)。在有效性方法中执行“健全性检查”

setValidity("firstClass", function(object) {
    msg <- NULL
    if (length(object@ID) != 1)
        msg <- c(msg, "ID must be length 1")
    else if (object@ID < 0)
        msg <- c(msg, "ID must be >= 0")
    if (is.null(msg)) TRUE else msg
})

【讨论】:

  • 感谢您的回答。我是 R 中 s4 的新手,那么拥有两个不同的函数有什么好处:.firstClass 和 firstClass?
  • @user8 一些 cmets 添加到文本中
  • 感谢额外的 cmets。为什么不直接写:firstClass &lt;- function(Name = character(), ID=0L){return(new("firstClass",Name = Name, ID = ID))}.
猜你喜欢
  • 2021-07-14
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
  • 2019-04-22
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多