Search code examples
rclassoopmethodsreference-class

Extending as.data.frame and as.matrix methods for an object created via setRefClass


I'm creating a reference class object in a manner similar to the example below:

# Class -------------------------------------------------------------------

myDataFrame <- setRefClass(Class = "myDataFrame",
                           fields = list(data = "data.frame",
                                         key_columns = "character"))

# Instance ----------------------------------------------------------------

myCars <- myDataFrame$new(data = mtcars,
                          key_columns = c("mpg", "cyl"))

I'm creating a show method for that class:

myDataFrame$methods(
    show = function() {
        cat(
            paste("Rows:", nrow(data)),
            paste("Cols:", ncol(data)),
            paste("Summary for key columns:", paste(key_columns, collapse = " ")),
            sep = "\n"
        )
        sapply(data[, key_columns], function(key_col) {
            print(summary(key_col))
        })
    }
)

this works as envisaged:

>> myCars
Rows: 32
Cols: 11
Summary for key columns: mpg cyl
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.40   15.43   19.20   20.09   22.80   33.90 
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  4.000   4.000   6.000   6.188   8.000   8.000 

Problem

I would like to extend this class with as.matrix and as.data.frame methods.

myDataFrame$methods(
    as.matrix = function() {
        as.matrix(data)
    }
)

This does not seem to work:

>> myCars$as.matrix()
Error in as.matrix(data) : unused argument (data)
>> as.matrix(myCars)
Error in as.vector(x, mode) : 
  cannot coerce type 'environment' to vector of type 'any'

Desired results

  • For as.matrix in the context of the provided example the result should be equivalent to as.matrix(mtcars)
  • For as.data.frame the result should be equivalent to as.data.frame(mtcars[,c("mpg", "cyl")]) where the selected columns reflect key_columns.

Solution

  • You need to specify the namespace for the as.matrix when your method name is called the same thing e.g.

    myDataFrame$methods(
        as.matrix = function() {
            base::as.matrix(data)
        }
    )