正如主题所描述的,我正在寻找一种方法来实现这一点:
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"已不再可用。: - (