Mike, This makes sense (I was actually surprised I was able to get my example to work as easily as I did).
The thing is, if you are dispatching on i (which you must if any methods do), you HAVE to know what class i is in order to identify the method. AFAIK there is no way in R of doing that without evaluating the object. So I guess we're back to "no, you can't do that". Sorry for the noise and for getting your hopes up. You can always write a subset S3 method. ~G On Wed, Aug 6, 2014 at 1:45 PM, Mike <wjia...@fhcrc.org> wrote: > Gebe, > > Your suggestion only works in an environment where no formal argument 'i' > is defined in any of existing '[' method. e..g > > > > showMethods("[") > Function: [ (package base) > x="nonStructure" > > Once we load the package that exports '[' methods with 'i' (e.g. > 'flowCore' ), then method dispatch still tries to evaluate 'i' in order to > match the call to the available methods. > > > library(flowCore) > > > showMethods("[") > Function: [ (package base) > x="AnnotatedDataFrame", i="ANY" > x="container", i="ANY" > x="eSet", i="ANY" > x="filterResultList", i="ANY" > x="filterSet", i="character" > > x="flowFrame", i="ANY" > ... > > > y[holycrapnothere] > > Error: object 'holycrapnothere' not found > > > Mike > > On 08/06/2014 11:45 AM, Gabe Becker wrote: > > Mike, > > This can be done. I would argue that the convenience your users get from > this is far outweighed by the damage this does to the ability to read and > easily understand the code they are writing. Users, maintainers, etc now > need to know the object class, what columns it has and what variables are > in their environment in order to predict a '[' expression's behavior. > (This is why most people I know to won't touch the attach function with a > 10 foot pole, regardless of how convenient it seems at first). > > But anyway, I'm not the design police and my dislike of non-standard > evaluation is far from universal, so here is how to do it: > > > setClass("toydf", representation(x = "data.frame")) > > setMethod("[", "toydf", function(x, i, j, ...) {key = substitute(i) ; > eval(key, x@x, parent.frame())}) > [1] "[" > > x = data.frame(holycrapnothere = 1:6) > > y = new("toydf", x= x) > > y > An object of class "toydf" > Slot "x": > holycrapnothere > 1 1 > 2 2 > 3 3 > 4 4 > 5 5 > 6 6 > > > holycrapnothere > Error: object 'holycrapnothere' not found > No suitable frames for recover() > > > y[holycrapnothere] > [1] 1 2 3 4 5 6 > > > ~G > > > > On Wed, Aug 6, 2014 at 10:43 AM, Mike <wjia...@fhcrc.org> wrote: > >> I'd like to do 'data.table-like' subsetting on `S4 class` by using 'i >> expression'. However, '[' generic function has the problem to dispatch S4 >> method because of its early evaluation of i argument. >> e.g. >> >> > gslist[Visit == 1, ] >> Error in gslist[Visit == 1, ] : >> error in evaluating the argument 'i' in selecting a method for function >> '[': Error: object 'Visit' not found >> >> Here 'gslist' is a S4 object `GatingSet` . >> >> I wasn't able to bypass this even after I defined my own S3 method (e.g >> [.GatingSet). >> I guess it is because 'GatingSet' is S4 class and there are already some >> S4 methods defined by other packages >> >> > showMethods("[") >> Function: [ (package base) >> x="AnnotatedDataFrame", i="ANY" >> x="flowFrame", i="ANY" >> ... >> >> So it will always try these S4 methods before any S3 gets its chance. >> >> Is there better way other than these two? >> 1. change 'GatingSet' to S3 class >> 2. use a different generic function that is not associated with any S4 >> methods (e.g. subset) >> >> Mike >> >> _______________________________________________ >> Bioc-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/bioc-devel >> > > > > -- > Computational Biologist > Genentech Research > > > -- Computational Biologist Genentech Research [[alternative HTML version deleted]] _______________________________________________ Bioc-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/bioc-devel