R:从 S4 方法中更改 S4 对象

  • 本文关键字:S4 对象 方法 r self r-s4
  • 更新时间 :
  • 英文 :


>我有一个 S4 对象,它表示一个递归树结构,其中包含一些数据和其他同一类的对象。我还有一个递归函数来修改树中每个节点中的两个插槽。 当我这样做时,该函数(称为"propagate(("(可以正常工作:

> obj <- treeObj(4, 5)
> slotNames(obj)
[1] "x" "y" "listOfOtherTreeObjs"
> obj <- propagate(obj, 1, 4)  

我可以编写这样的函数,它接受一个参数并用该数据填充树,没问题。

不过,我想要的是能够从根对象的方法中调用 propagate((:

setMethod("transform", signature="treeObj",
definition=function(object, i, j) {
object@x <- i;  object@y <- j;
object <- propagate(object, i, j);
... (do some other stuff in the tree)
})

在此方法中,propagate(( 似乎可以正常工作,但它的结果似乎没有以在 transform(( 方法定义中可检测到的方式分配给父对象。我的问题:

  1. 我想这与 R 的按值调用性质有关,我不能影响用于调用转换函数的对象的值。这是正确的还是我只是愚蠢,这应该有效?

  2. 有没有一种R魔法可以解决这个问题? 某种方法可以调用"assign(("函数来强制对象的新定义替换当前定义? 还是什么?

  3. 有没有一种更 R 的方法来构建我的递归对象来支持这种事情?

提前谢谢。

您需要做两件事才能完成这项工作:

1(据推测,递归不会永远持续下去,即在某些时候,一个对象不会包含指向另一个对象的链接,因为它位于树的底部。因此,您需要其他树对象列表为 NULL 的可能性。你可以通过类工会来做到这一点:

setClassUnion("listOfOtherTreeObjsOrNULL",c("listOfOtherTreeObjs","NULL"))

然后,在对象的第三个插槽中使用的正确类是这个新的类联合。

2(当你定义transform的方法时,它需要看起来像这样:

function(object,i,j){
## do whatever you want with i and j
if(is.null(object@listOfOtherTreeObjs)) return(object)
else{
object@listOfOTherTreeObjs <- lapply(object@listOfOtherTreeObjs,propagate)
return(object)
}
}

您的更改似乎没有产生任何效果的原因是您没有从函数中return任何内容,因此您只是修改了未保存在任何地方的对象的副本。

最新更新