dynamic class coercion in R

138 views Asked by At

is there a way to dynamically coerce an object in R?

Background I am trying to create a function factory for summary which can return the specific method based on the class of the object passed. Particularly, this is for one of the questions in http://adv-r.had.co.nz/Functional-programming.html#lists-of-functions

Implement a summary function that works like base::summary(), but uses a list of functions. Modify the function so it returns a closure, making it possible to use it as a function factory.

I have tried a few variations all of which are incorrect/ incomplete, for ex.

object.list = list(df = data.frame(),fr=factor(), mx = matrix())
summary.new = function(y){
  function(x,...){
    UseMethod(summary,x)
  }
}
summary.new.list = lapply(object.list, summary.new)

I am wondering if there is a way to dynamically coerce an object - something like as.() and use this to return the appropriate method from the generic object.

summary.new.list function

> summary.new.list
$df
function (x, ...) 
{
    UseMethod("summary", x)
}
<environment: 0x108b5edc>

$fr
function (x, ...) 
{
    UseMethod("summary", x)
}
<environment: 0x108b5de0>

$mx
function (x, ...) 
{
    UseMethod("summary", x)
}
<environment: 0x108b5ce4>

I want to call the function based on the object, for ex. for dataframes I want to call summary.new.list$df(data.frame(1:12,3,4)). Though it works now as $df function is still generic - I wish to call the base summary.data.frame function from inside there instead of UseMethod

1

There are 1 answers

0
IRTFM On

I don't exactly understand this example's intended purpose, but here's something to chew on:

 summary2 <- function(x){ switch( class(x)[1], "data.frame"= summary.data.frame, 
                                               "list"=summary.list , 
                                               "factor"=summary.factor,
                                               "matrix"=summary.matrix,
                                               "numeric" = summary.default) }
 summary.new.list = lapply(object.list, summary2)

 # Application of that list of functions matched to object classes
 > mapply( function(x,y) { do.call(x, list(y) )}, summary.new.list, object.list)
$df
< table of extent 0 x 0 >

$fr
integer(0)

$mx
    V1         
 Mode:logical  
 NA's:1   

You are basically reinventing class dispatch of functions. The question asked for "coercion" but the problem didn't seem to require any coercion, at least as I read it.