I have and new S4 object with 4 Slots, one of them is a data.frame (g_table), so I want to add a parameters to setMethod to subset the data:
this is my actual code:
setGeneric('g_table', function(x) standardGeneric('g_table'))
setMethod('g_table', 'NewPackage', function(x) { x@g_table })
# assignment-methods:
setGeneric("g_table<-", function(x, value) standardGeneric("g_table<-"))
setMethod("g_table<-", "NewPackage", function(x, value) {
x@g_table <- value
return(x)
})
and have no problem with it, just if I want to filter something in the data.frame (g_table) I need to do something like:
g_table(myObj) %>% filter(., gene %in% c("gene1", "gene2") )
and it filter the data, but I want to add the filter or subset option to g_table methods
first I tried to create a function
my_function <- function(obj, by){
par <- substitute(by)
dat <- obj@g_table
gt <- subset(dat, eval(par, dat))
return(gt)
}
it works like:
my_function(myObj, gene %in% c("gene1", "gene2") )
so I tried to replicate it in setMethod, something like:
setGeneric('g_table', function(x, by=NULL) standardGeneric('g_table'))
setMethod('g_table', 'NewPackage', function(x, by=NULL) {
if(!is.null(by)){
par <- substitute(by)
dat <- x@g_table
gt <- subset(dat, eval(par, dat))
}
if(is.null(by)){
gt <- x@g_table
}
return(gt)
})
This is the error:
g_table(MyObj, gene %in% c("gene1", "gene1") )
Error in h(simpleError(msg, call)) :
error in evaluating the argument 'x' in selecting a method for function '%in%': object 'gene' not found
any way to fix or do it ??
Thanks
This doesn't appear to have anything to do with S4's setMethod specifically. You can simplify this to
foo <- function(x, by=NULL) {
if(!is.null(by)){
par <- substitute(by)
subset(x, eval(par, x))
} else {
x
}
}
dd <- data.frame(gene=c("gene1", "gene2", "gene3", "gene1"), val=1:4)
foo(dd, gene %in% c("gene1", "gene2"))
which gives the same error. The problem is when you do is.null(by)
you are evaluating the by
parameter. The collapses the promise and you can no longer use substitute
on that value.
It's safer to use missing()
rather than checking for NULL
foo <- function(x, by) {
if(!missing(by)){
par <- substitute(by)
subset(x, eval(par, x))
} else {
x
}
}
foo(dd, gene %in% c("gene1", "gene2"))
foo(dd)
If you really needed to check for NULL, you could do something like
foo <- function(x, by=NULL) {
by <- substitute(by)
if(length(by)>0 && as.list(by)[[1]] != as.symbol("NULL")){
subset(x, eval(by, x))
} else {
x
}
}
foo(dd, gene %in% c("gene1", "gene2"))
foo(dd)
foo(dd, NULL)