【问题标题】:How to create an S4 array which has slots containing arrays如何创建具有包含数组的插槽的 S4 数组
【发布时间】:2013-07-22 17:08:21
【问题描述】:

如何创建将数组作为插槽的 S4 类?下面,我有一个示例类。我希望能够以这样一种方式构造,即我得到两个“人”元素,每个元素都有适当的数组成员。

下面的代码给了我以下错误:“validObject(.Object) 中的错误: 无效类“person”对象:类“person”中插槽“children”的无效对象:得到类“character”,应该是或扩展类“array”

setClass("person", representation(name="character", age="numeric", children = "array"))

setMethod(
  f = "[",
  signature="person",
  definition=function(x,i,j,...,drop=TRUE){ 
    initialize(x, name=x@name[i], age = x@age[i], children = x@children[i])
  }
)

setMethod(f = "length", signature = "person", definition = function(x){
  length(x@name)
})

setMethod(f = "dim", signature = "person", definition = function(x){
  length(x@name)
})

kids1 = as.array(c("Bob", "Joe", "Mary"))

person = new("person", name="John", age=40, children = kids1)

person@children[2]

kids2 = as.array(c("Steve", "Beth", "Kim"))

people = new("person", name=c("John", "Fred"), age=c(40, 20), children = as.array(c(kids1, kids2), dim = 2))

people[1]@age
people[2]@children[1]

【问题讨论】:

  • 我真的不明白你为什么要一个 Person 实例来保存几个人的定义。在这种情况下,你的类应该命名为 Persons。你知道你可以将几个 Person 实例放在一个列表中,比如 persons_list,然后使用 people_list[[i]] 访问这些实例吗?

标签: r s4


【解决方案1】:

您可能不希望 @children 成为一个数组。使用长度为 1 的 dim 属性,它本质上与向量相同,并且您失去了区分不同人的孩子的能力。考虑将此插槽设为列表。

setClass("person",
    representation(name="character", age="numeric", children = "list"))

person = new("person", name="John", age=40, children = list(kids1))
person@children

people = new("person", name=c("John", "Fred"), age=c(40, 20),
             children = list(kids1, kids2))
people[1]

【讨论】:

  • 使用列表效果很好。我还必须在子集运算符中添加一个包装器,以确保子槽返回正确类型的变量。
【解决方案2】:

drop=FALSE 添加到children 槽的子集;这是数组子集的标准 R 规则的结果

setMethod(
  f = "[",
  signature="person",
  definition=function(x,i,j,...,drop=TRUE){ 
    initialize(x, name=x@name[i], age = x@age[i], 
      children = x@children[i,drop=FALSE])
  }
)

我也不确定你的as.array() 是否按照你的想法做? dim 参数被忽略。

【讨论】:

    【解决方案3】:

    Hong 的回答很有效。我确实需要在“[”子集函数中添加一个列表包装器。完成后,一切正常。

    kids1 = as.array(c("Bob", "Joe"))
    kids2 = as.array(c("Steve", "Beth", "Kim"))
    
    setClass("person", representation(name="character", age="numeric", children = "list"))
    
    setMethod(
      f = "[",
      signature="person",
      definition=function(x,i,j,...,drop=TRUE){ 
        initialize(x, name=x@name[i], age = x@age[i], children = list(x@children[i]))
      }
    )
    
    people = new("person", name=c("John", "Fred"), age=c(40, 20), children = list(kids1, kids2))
    
    people[1]@name
    people[1]@age
    people[1]@children
    
    people[2]@name
    people[2]@age
    people[2]@children
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-31
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      相关资源
      最近更新 更多