r语言 - 是否有一种方式/方法将R6对象分配给S4对象槽?



正如主题所描述的,我正在寻找一种方法来实现这一点:

require("R6")
R6cls <- R6::R6Class("R6obj",
public = list(val = 1, foo = function() "foo!")
)
# check this R6 class
r6o <- R6cls$new()
r6o
# <R6obj>
#  Public:
#    clone: function (deep = FALSE) 
#    foo: function () 
#    val: 1
# now the S4 part 
S4wR6slot <- function() new("S4wR6slot")
setClass("S4wR6slot", contains = "environment", # or maybe "R6" or "R6cls"? tried them all but none seemed to work
slots = list(a = "R6cls", b = "character"))

# Currently gives
Warning message:
undefined slot classes in definition of "S4wR6slot": a(class "R6cls") 
# but you can still kind of use it 
s4r6 <- S4wR6slot()
s4r6
# An object of class "S4wR6slot"
# <environment: 0x00000179de2da628>
# Slot "a":
# NULL
#
# Slot "b":
# character(0)
s4r6@b <- "text" # works nicely 
# BUT trying to assign to that env slot 
s4r6@a <- r6o
# will throw these "ugly" errors 
Error in (function (cl, name, valueClass)  : 
c("assignment of an object of class “R6obj” is not valid for @‘a’ in an object of class “S4wR6slot”; is(value, "R6cls") is not TRUE", 
"assignment of an object of class “R6” is not valid for @‘a’ in an object of class “S4wR6slot”; is(value, "R6cls") is not TRUE")

玩弄setOldClass()也没有什么好处。也许根本没有办法做到这一点——只是问别人是否有想法?或者甚至可能做到了这一点——否则可能我做得不够好,有人可以给我指出文档,那里说你不应该尝试让这个工作?

在S4类中拥有R6对象的一种方法,但是需要通过定义一个称为'R6'的S4类来欺骗S4系统。这将防止methods包抱怨类R6不存在。幸运的是,它实际上并没有检查原型中的"R6"对象是否属于S4类型,从而允许您将实际的R6对象插入其中。

library(R6)
R6cls <- R6::R6Class("R6obj",
public = list(val = 1, foo = function() "foo!")
)
setClass('R6')
setClass("S4wR6slot", slots = list(a = 'R6', b = "character"),
prototype = list(a = R6cls$new(), b = 'Hello'))
S4wR6slot <- function() new("S4wR6slot")
myS4 <- S4wR6slot()
class(myS4)
#> [1] "S4wR6slot"
#> attr(,"package")
#> [1] ".GlobalEnv"
isS4(myS4)
#> [1] TRUE
myS4@a
#> <R6obj>
#>   Public:
#>   clone: function (deep = FALSE) 
#>     foo: function () 
#>       val: 1

我也为这个简单的示例类找到了一个解决方案,似乎可以工作-但遗憾的是,解决方案有趣地失败了/失败了更复杂的R6类。

为了完整,在这里添加示例解决方案

require(R6)
R6cls <- R6::R6Class("R6obj",
public = list(val = 1, foo = function() "foo!")
)
# check this R6 class
r6o <- R6cls$new()
r6o
# <R6obj> # <- I SUDDENLY NOTICED THIS on a second look! 
#   Public:
#     clone: function (deep = FALSE) 
#     foo: function () 
#    val: 1
S4wR6slot <- function() new("S4wR6slot")
setClass("S4wR6slot", contains = "environment",
slots = list(a = "R6obj" , b = "character"))
# list(a = "R6obj" ... is what did the "magic"
s4r6 <- S4wR6slot()
s4r6
# An object of class "S4wR6slot"
# <environment: 0x000002520292f470>
# Slot "a":
# NULL
#
# Slot "b":
# character(0)
s4r6@b <- "text"
s4r6@a <- r6o # THIS THEN WORKED/WORKS! 
class(r6o)
# [1] "R6obj" "R6" # I simply used that "R6obj" in the S4 definition above
is(r6o, "R6")
# [1] TRUE
is(r6o, "R6obj")
# [1] TRUE

但不知怎么的,那个"Robj"class (type)在更复杂的设置中丢失,即我在另一个包中使用在一个包中定义的R6类,然后"R6obj"已不再可用。: - (

相关内容

  • 没有找到相关文章

最新更新