什么时候在 R 中调用 S4 对象的访问器方法?

Pir*_*unt 1 r s4

不太确定如何在不深入了解我的特定编程问题的情况下提出这个问题。所以,这个问题有点相关,但要简单得多。我试图了解 R 在分配给 S4 类的插槽时适用的程序。我有自定义访问和分配功能,“$”和“$<-”。

我注意到两点:

  1. 当我使用括号对特定插槽进行子集化时,分配将起作用,即使我没有提供任何这样做的机制。我相信这只是 R 对矢量化代码的热切拥抱。这很好,但是如果我想启用不同的子集逻辑怎么办?在下面的玩具示例中,假设我想根据与生日的匹配进行子集化。
  2. 分配给子集插槽时,将调用“$”访问器。为什么是这样?

以下是用于说明的玩具示例。非常感谢对第 1 点的评论和对第 2 点的回答。

setClass("Person"
     , representation(FirstName = "character"
                      , LastName = "character"
                      , Birthday = "Date")
)

setMethod("$", signature(x = "Person"), function(x, name) {
  print("Just called $ accessor")
  slot(x, name)
})

setMethod("$<-", signature(x = "Person"), function(x, name, value) {
 print("Just called $ assignment")
  slot(x, name) = value
  x
})

objPeople = new("Person"
                , FirstName=c("Ambrose", "Victor", "Jules")
                , LastName=c("Bierce", "Hugo", "Verne")
                , Birthday=seq(as.Date("2001/01/01"), as.Date("2003/12/31"), by="1 year"))

# This assignment will work. When assigning, there will be a call to the "$" accessor function. Why?
objPeople$FirstName[2] = "Joe"

# This assignment will not make a call to the "$" accessor function. Why?
objPeople$FirstName = "Ambroze"
Run Code Online (Sandbox Code Playgroud)

MrF*_*ick 5

请记住,这[只是另一个函数,就像[<-. 所以为了做到

objPeople$FirstName[2] = "Joe"
Run Code Online (Sandbox Code Playgroud)

$将运行第一和回报的东西,在[<-可以操作的。就像是

'$<-'(objPeople, "FirstName", '[<-'( '$'(objPeople, "FirstName"), 2, "Joe"))
Run Code Online (Sandbox Code Playgroud)

因此,为了进行子集化,它必须提取名字。但是随着

 objPeople$FirstName = "Ambroze"
Run Code Online (Sandbox Code Playgroud)

那只是一个

'$<-'( objPeople, "FirstName", "Ambroze")
Run Code Online (Sandbox Code Playgroud)

所以你不需要调用访问器。您只是直接调用赋值函数。

如果你想在你的班级上有一个自定义的子集,它会在Person[]级别上。如果您想在 FirstName 插槽上使用自定义子集,则必须使 FirstName 插槽成为它自己的类,您可以在其中重新定义该[方法。