1

I define a class which has a dataframe slot, df, which is accessed by method doAnalysis.

setClass(Class='E166Hist',representation=representation(df='data.frame'), contains='ImmutableAnalysis')

setGeneric(name='doAnalysis', def=function(x){standardGeneric('doAnalysis')})

setMethod(f='doAnalysis', signature='E166Hist', definition=function(x){
    tmp<-melt(x@df, variable.name='source', value.name='pc')})

When I call

dh<-new(Class='E166Hist')
doAnalysis(dh)

I get Error in varnames[discrete] : invalid subscript type 'list' which seems to be caused by x@df. It works ok if I replace x@df with just df. I'm confused because I thought the @ was needed to access the slots of a class. If anyone could explain what I'm missing here I'd appreciate it. Thanks!

stegzzz
  • 407
  • 4
  • 9
  • I would have thought that you just needed `tmp<-melt(x, variable.name='source', value.name='pc')`. This doesn't appear to be a complete example but there is certainly no `'df'` column/slot in any of the implicit objects as would be needed for `@df` to have any meaning. – IRTFM Dec 22 '15 at 18:59

2 Answers2

2

Here's a simpler reproduction of the error

> melt(data.frame(), variable.name="source")
Error in varnames[discrete] : invalid subscript type 'list'

It suggests that the problem is that the data.frame has no column named source

> melt(data.frame(source=character()), variable.name="source")
Using source as id variables
[1] source
<0 rows> (or 0-length row.names)

This seems to get us off the ground, so with your class (omitting the inheritance relationship and using the generating function returned by setClass())

.E166Hist <- setClass(Class='E166Hist', representation(df='data.frame'))

setGeneric('doAnalysis', function(x) standardGeneric('doAnalysis'))

setMethod('doAnalysis', 'E166Hist', function(x) {
    melt(x@df, variable.name='source', value.name='pc')
})

We reproduce the error when our object has a data.frame() without the column

> doAnalysis(.E166Hist())
Error in varnames[discrete] (from #2) : invalid subscript type 'list'

but not when it does have the column

> result = doAnalysis(.E166Hist(df=data.frame(source=character())))
Using source as id variables
> result
[1] source
<0 rows> (or 0-length row.names)
>
Martin Morgan
  • 45,935
  • 7
  • 84
  • 112
0

OK, @martin-morgan, df was not initialised properly. Adding initialize gets it to work as intended:

setClass(Class='E166Hist', representation(df='data.frame'))
setGeneric('doAnalysis', function(x) standardGeneric('doAnalysis'))

setMethod('doAnalysis', 'E166Hist', function(x) {
melt(x@df, variable.name='source', value.name='pc')})

setMethod('initialize','E166Hist',
function(.Object) {.Object@df=data.frame(source=character()); .Object})

.E166Hist<-new ('E166Hist')

Now doAnalysis does the job:

doAnalysis(.E166Hist)
Using source as id variables
[1] source  
<0 rows> (or 0-length row.names)
stegzzz
  • 407
  • 4
  • 9
  • It's usually [better to write a plain-old-function](http://stackoverflow.com/questions/16247583/inheritance-in-r/16248773#16248773) `E166Hist()` rather than an initialize method, because of the complicated contract `initialize()` implies. – Martin Morgan Dec 23 '15 at 10:00