1

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

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

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]
4

3 回答 3

2

你可能不想@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]
于 2013-07-22T17:29:37.993 回答
1

添加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论点被忽略了。

于 2013-07-22T17:29:09.487 回答
1

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

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
于 2013-07-23T00:35:30.620 回答