3

I'm trying to define a new data method for a foo class. My foo objects follow the following structure:

setClass(Class = "foo", 
    representation = representation(
        data = "data.frame", 
        id = "character",   
        wl = "numeric"
    )
)

The data method I'm trying to create is actually accessing the contents of the @data slot:

setMethod("data", "foo",
    function(object)
        object@data
)

I've been looking at the section 7.1 of the Writing R Extensions manual, but it only deals with S3 classes. I also had a peek at this post, but without success:

setGeneric("data", function(object, ...) standardGeneric('data'))

setMethod("data", "ANY", utils::data)

setMethod("data", "foo",
  function(object)
    object@data
)

When loading the package:

> data(mtcars)
Error in function (classes, fdef, mtable)  : 
  unable to find an inherited method for function "data", for signature "data.frame"
Community
  • 1
  • 1
Pierre
  • 1,015
  • 1
  • 9
  • 19

2 Answers2

5

Pierre,

The first argument of data is ... (not object!), so you need some special considerations for the dispatch. ? dotsMethods discusses that.

Often (e.g. cbind, rbind), a quick & dirty solution is to use S3 method notation for these functions

data.foo <- function (...) {
   x <- list (...) [[1]]
   x@data
} 

However, I guess you are in trouble here because the original data function uses the unevaluated name of the argument, and the error message suggests that it is evaluated (does make sense: how could R know which class the argument has if it doesn't evaluate?) before the original data function is called.

So in the end it may be much easier to use some other name than data () to access your data slot.

(Your wl slot makes me think of wavelengths: if you are setting up a class for spectroscopic data, have a look at hyperSpec - it may provide already what you need).

setempler
  • 1,681
  • 12
  • 20
cbeleites unhappy with SX
  • 13,717
  • 5
  • 45
  • 57
  • Hi Claudia, and thanks for your answer. I'm of course aware of your work on hyperSpec. I'm indeed setting up a class for spectroscopic data - very much a toy project to learn S4 classes, and test some soil-spectroscopy ideas. You can check it out [here](https://r-forge.r-project.org/projects/inspectr/), but this is much smaller a project than hyerpSpec! – Pierre Jul 04 '11 at 07:01
  • Hi Pierre, thanks. As my data slot is rather central, I use `[]` and `[[]]` to access it. You'd also be welcome to subclass from hyperSpec (which is the product of me learning S4...) or join the hyperSpec developers. – cbeleites unhappy with SX Jul 04 '11 at 07:29
0

What helped me (I am in the S3 world) was to create default function that calls data() from the basic utils package:

data.default <- function(...){
 utils::data(...)
}

Then dispatch behaves as expected:

data(mtcars)
mtcars
                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Daniel Krizian
  • 4,586
  • 4
  • 38
  • 75