如何为S4类矢量化存取方法?

时间:2014-03-14 17:56:45

标签: r s4

我正在编写一个S4类,正在研究访问器方法。我想写一个方法,如果你给它一个或多个我的S4对象将返回一个带有某个槽内容的向量。这是一些示例代码

setClass(Class="TestClass",slots=c(Type="character"))   ### Creates Class             

setGeneric(name="getType",function(object){standardGeneric("getType")} )

setMethod(f="getType", signature="TestClass",      ### accessor for "TYPE
      function(object){object@Type})

现在我制作了两个对象:

 FOO<-new("TestClass",Type="A")
 BAR<-new("TestClass",Type="B")

使用getType(FOO)按计划工作。但是,当我这样做时:

Both<-c(FOO,BAR)
getType (Both)

而不是获得"A","B"我当然得到:

Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘getType’ 
  for signature ‘"list"’

这并不奇怪。我知道我可以写一个像

这样的函数
getType2<-function(object){sapply(object, FUN=getType)}

这会给我我想要的东西。但是,在访问器函数本身中是否有某种方法可以做到这一点?我可以对@进行矢量化吗?

1 个答案:

答案 0 :(得分:1)

我认为答案是否定的,你无法对列表内容进行调度;你可以写一个getType,list-method。或者,您可以创建一个包含Test类列表的TestList类,并为其编写方法。 IRanges包有一个通用容器...

library(IRanges)
.TestList = setClass("TestList", contains="SimpleList", 
    prototype=c(elementType="Test"))
TestList = function(...) .TestList(listData=list(...))
lst = TestList(FOO, BAR)
lst[[1]]

或者在我看来,最好的解决方案是编写你的类,使其已经被矢量化,就像character()被矢量化一样 - 0,1或任何数量的&#39;测试&#39;元件。

一个简单的例子是为一组人建模。非R方式会想到每行一个人,一个代表几个人的集合(这里是一个列表):

.Person = setClass("Person", representation(First="character", Last="character"))
friends = list(.Person(First="Bill", Last="Smith"),
               .Person(First="Sue", Last="Bird"))

与更为R的方式,其中类为整个表建模,其中字段表示列。

.People = setClass("People", representation(First="character", Last="character"))
setMethod(show, "People", function(object) {
    print(data.frame(First=object@First, Last=object@Last))
})

friends = .People(First=c("Bill", "Sue"), Last=c("Smith", "Bird"))