【发布时间】:2011-11-07 10:27:02
【问题描述】:
我目前正在为需要时间生成的大型对象开发参考类 (R5),我想知道是否有人知道比使用 setRefClass 重新定义类并在每次更新方法时重现对象更好的方法来开发方法。
换句话说:可以重新定义现有参考类对象的方法吗?
【问题讨论】:
标签: r methods reference-class
我目前正在为需要时间生成的大型对象开发参考类 (R5),我想知道是否有人知道比使用 setRefClass 重新定义类并在每次更新方法时重现对象更好的方法来开发方法。
换句话说:可以重新定义现有参考类对象的方法吗?
【问题讨论】:
标签: r methods reference-class
我曾考虑过以下操作:
test <- setRefClass("TEST",
fields = list(a = "numeric"),
methods = list(
funA = function(){
a <<- a+1
},
initialize = function(){
a <<- 1
callSuper()
}
)
)
ex1 <- test$new()
ex1$funA()
test$methods(funA = function(){
a <<- a+10
}
)
ex$funA
# Class method definition for method funA()
# function ()
# {
# a <<- a + 1
# }
# <environment: 0x0537f8ac>
ex1 <- test$new()$import(ex1)
ex$funA
# Class method definition for method funA()
# function ()
# {
# a <<- a + 10
# }
# <environment: 0x04badc5c>
我相信您可以使用 class$methods( 覆盖类中以前的方法,然后您可以从重新定义的类中设置一个新对象并导入旧对象。我会注意:
“类的所有方法都应该在定义类的源代码中定义,通常作为包的一部分。特别是,不能在带有命名空间的附加包中的类中重新定义方法:类方法检查类定义的锁定绑定。”也来自?setRefClass。
【讨论】:
这个问题困扰了我好几个月。今天我找到了一个非常方便的解决方案,灵感来自https://stat.ethz.ch/pipermail/r-help/2012-January/299743.html
让我们从一个有错误实现的 ReferenceClass 开始:
MyClass <- setRefClass(
"MyClass",
fields = list(
xy = "data.frame"
),
methods = list(
initialize = function( df ){
if( !missing( df ) ){
xy <<- df
}
},
getSecondRow = function(){
# A mistake happend here
return( xy[1,] )
}
)
)
mc <- MyClass$new( data.frame( a = 1:10, b = rnorm(10) ) )
mc$getSecondRow()
a b
1 1 0.1349983
getSecondRow 的实现显然没有提供预期的结果。所以固定的方法实际上应该是这样的
getSecondRow = function(){
return( xy[2,] )
}
使用默认initialize( ... )构造函数的复制构造函数功能从现有对象构造一个新对象,而不是加载类并从头开始复制对象。调试并重新加载类后,您只需将具有实现的现有对象复制到同一变量中即可
# NOTRUN
mc <- MyClass$new( mc )
但是,在此处介绍的情况下,标准构造函数已被覆盖。但在这种情况下,您可以简单地使用callSuper( ... ) 的功能,这样您的构造函数应该看起来像
initialize = function( df, ... ){
callSuper( ... )
if( !missing( df ) ){
xy <<- df
}
}
最后,你的固定对象是由
派生的mc <- MyClass$new( mc$xy, mc )
mc$getSecondRow()
a b
2 2 0.8452587
【讨论】: