我目前正在为需要时间来制作的大型对象开发引用类(R5),我想知道是否有人知道开发方法的更好方法,而不是每次使用setRefClass重新定义类并在每次更新方法时重现对象。
换句话说:可以重新定义现有Reference类对象的方法吗?
答案 0 :(得分:2)
我考虑过以下几点:
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
。
答案 1 :(得分:2)
这个问题困扰了我好几个月了。今天我发现了一个非常方便的解决方案,灵感来自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