我在为S4类定义[
、$
和[[
子集操作符时遇到了困难。
有没有人可以为我提供一个基本的示例来定义这三个操作符的S4类?
发现通用性,以便我们知道我们的目标是什么。
> getGeneric("[")
standardGeneric for "[" defined from package "base"
function (x, i, j, ..., drop = TRUE)
standardGeneric("[", .Primitive("["))
<bytecode: 0x32e25c8>
<environment: 0x32d7a50>
Methods may be defined for arguments: x, i, j, drop
Use showMethods("[") for currently available ones.
定义一个简单的类
setClass("A", representation=representation(slt="numeric"))
setMethod("[", c("A", "integer", "missing", "ANY"),
## we won't support subsetting on j; dispatching on 'drop' doesn't
## make sense (to me), so in rebellion we'll quietly ignore it.
function(x, i, j, ..., drop=TRUE)
{
## less clever: update slot, return instance
## x@slt = x@slt[i]
## x
## clever: by default initialize is a copy constructor, too
initialize(x, slt=x@slt[i])
})
实际应用中:
> a = new("A", slt=1:5)
> a[3:1]
An object of class "A"
Slot "slt":
[1] 3 2 1
integer
,以允许重新排序和重复索引条目,然后使用callGeneric
调用一个单一方法,该方法执行类的子集操作。[[
,没有任何概念上的区别,除了希望尊重返回内容而不是对象的另一个实例的语义,如[
所暗示的那样。对于$
,我们有> getGeneric("$")
standardGeneric for "$" defined from package "base"
function (x, name)
standardGeneric("$", .Primitive("$"))
<bytecode: 0x31fce40>
<environment: 0x31f12b8>
Methods may be defined for arguments: x
Use showMethods("$") for currently available ones.
并且
setMethod("$", "A",
function(x, name)
{
## 'name' is a character(1)
slot(x, name)
})
使用
> a$slt
[1] 1 2 3 4 5
$
操作符来访问S4插槽(除非您打算从存储在特定插槽中的数据框中访问列?),我会小心。一般建议编写访问器函数,如getMySlot()
和setMySlot()
来获取所需的信息。您可以使用@
操作符从这些插槽中访问数据,尽管get和set最适合作为用户界面。对于用户来说,使用$
可能会令人困惑,因为他们可能期望得到一个数据框。有关这些问题的详细讨论,请参见Christophe Genolini的this S4教程。如果这不是您使用$
的方式,请忽略我的建议(但是该教程仍然是一个很好的资源!)。[
和[[
从另一个类继承,比如vector,您还需要定义el()
(相当于[] [[1L]]
或来自子集[]
的第一个元素)和length()
。我目前正在编写一个从numeric继承的类,numeric方法将自动尝试使用这些函数从您的类中调用。如果该类用于更有限的或者是您自己的个人使用,则可能不会出现问题。