在 R6 类上定义括号 (`[`) 运算符

zku*_*rtz 5 r r6

这是不起作用的:

library(R6)

Foo = R6::R6Class(
    'Foo',
    public = list(
        X = NULL,
        metadata = NULL,
        initialize = function(X, metadata){
            self$X = X
            self$metadata = metadata
        },
        `[` = function(selection){
            subfoo = Foo$new(X = X[selection], 
                             metadata = self$metadata)
            return(subfoo)
        }
    )
)
Run Code Online (Sandbox Code Playgroud)

具体来说,该[方法是垃圾:

> X = matrix(1:8, ncol = 2)
> foo = Foo$new(X, 'blah blah')
> foo[1:2,]
Error in foo[1:2, ] : object of type 'environment' is not subsettable
Run Code Online (Sandbox Code Playgroud)

期望的结果是,这foo[1:2,]将是一个类的对象Foo,只是foo它的矩阵foo$X更小。有没有直接的方法来实现这一点,将[操作员直接暴露给用户?

Ian*_*ows 5

我想迟到的答案总比没有好。问题是您正在注册可以像这样调用的方法

x$`[`(1:3)
Run Code Online (Sandbox Code Playgroud)

而你想要

x[1:3]
Run Code Online (Sandbox Code Playgroud)

以下内容将为所有 R6 对象正确分派所有[和调用(通过 S3)。[<-

`[.R6` <- function(x, ...) x$`[`(...) 
`[<-.R6` <- function(x, ...) x$`[<-`(...) 
Run Code Online (Sandbox Code Playgroud)

请注意,您不应该对方法执行类似的操作[[,因为这些方法已经被定义和使用,因为 R6 对象是环境。

理想情况下,如果(也可以被重写,以便我们可以创建函子对象(例如调用x(2)),那就太好了,但我不知道如何做到这一点。