Search code examples
rfunctioninitializerr-s4

Creating initialise method for reference class in R


I would like to create an initialize method for a reference class object in R that will provide default values for missing arguments. In the example above, the reference class object takes a data frame and some strings. If the comment string is missing timestamp is provides.

Class definition

#' Class SummaryData
#'
#' @description Odd class facilitating creation of data frame with
#'   summary information attached.
#'
#' @slot data data.frame.
#' @slot summary_columns character.
#' @slot info character.
#'
#' @return A SummaryData Class
#' @import methods
#' @exportClass SummaryData
#'
setClass(
    Class = "SummaryData",
    slots = list(
        data = "data.frame",
        summary_columns = "character",
        info = "character"
    )
)

#' Constructor method of SummaryData.
#'
#' @name SummaryData
#' @rdname SummaryData-class
setMethod("initialize", "SummaryData", function(.Object,
                                                data = "data.frame",
                                                summary_columns = "character",
                                                info = "character",
                                                ...)
{
    if (missing(data)) {
        data <- data.frame()
    }
    if (missing(summary_columns)) {
        summary_columns <- character()
    }
    if (missing(info)) {
        info <- paste("Object generated on:", Sys.time())
    }

    validObject(.Object)
    return(.Object)
})

#' Wrapper function SummaryData.
#'
#' @name SummaryData
#' @rdname SummaryData-class
#' @export
SummaryData <- function(...) {
    new("SummaryData", ...)
}

Problem

>> SummaryData(data = airquality)
An object of class "SummaryData"
Slot "data":
data frame with 0 columns and 0 rows

Slot "summary_columns":
character(0)

Slot "info":
character(0)

Desired results

  • info slot should contain results of paste("Object generated on:", Sys.time())

  • data slot should contain info on airquality data, which is:

    dim(airquality)
    [1] 153   6
    

Solution

  • You need to actually modify the object and call your initialize method.

    setClass(
      Class = "SummaryData",
      slots = list(
        data = "data.frame",
        summary_columns = "character",
        info = "character"
      )
    )
    
    # Constructor method of SummaryData.
    setMethod("initialize", "SummaryData",
              function(.Object,
                       data,
                       summary_columns,
                       info,
                       ...) {
    
                if (!missing(data)) {
                  .Object@data <- data
                }
                if (!missing(summary_columns)) {
                  .Object@summary_columns <- summary_columns
                }
                if (missing(info)) {
                  .Object@info <- paste("Object generated on:", Sys.time())
                }else {
                  .Object@info <- info
                }
    
                validObject(.Object)
                return(.Object)
              }
    )
    
    # Wrapper function SummaryData.
    SummaryData <- function(...) {
      initialize(new("SummaryData"), ...)
    }
    

    Now, some testing:

    SummaryData(data = airquality, info = "hey")
    #Output not shown
    
    SummaryData(data = data.frame(a = 1, b = 2))
    #An object of class "SummaryData"
    #Slot "data":
    #  a b
    #1 1 2
    #
    #Slot "summary_columns":
    #character(0)
    #
    #Slot "info":
    #[1] "Object generated on: 2018-12-12 20:21:09"