[Rd] how to interpose my own "[" function?
Henrik Bengtsson
hb at biostat.ucsf.edu
Mon Sep 30 06:02:24 CEST 2013
Typically you use NextMethod(), but otherwise you can either "unclass"
your object first or use .subset(). Not sure from ?.subset whether
that is ok to use or not.
/Henrik
On Sun, Sep 29, 2013 at 8:26 PM, Andrew Piskorski <atp at piskorski.com> wrote:
> I want to create my own "[" function (for use on vectors, matrices,
> arrays, etc.), which calls the stock R "[", does some additional work,
> and then finally returns the modified result.
>
> But, how do I properly call the stock R "[" function? It takes a
> varying number of positional arguments, and its R-level closure is
> just: .Primitive("[") It's implemented by do_subset_dflt in
> src/main/subset.c.
>
> The only thing I've come up with so far is using eval after crudely
> re-constructing the original incoming call (example below), which is
> both very slow and gets some of the semantics wrong.
>
> Is there some good way for my function to just say, "take ALL my
> incoming arguments, whatever they might be, and pass them as-is to
> .Primitive('['), then return control to me here"? Or said another
> way, what I want is to hook the end of the R-level "[" function and do
> some extra work there before returning to the user.
>
> Basically, where should I look to figure out how to do this? Is it
> even feasible at all when the call I want to intercept is implemented
> in C and is Primitive like "[" is? Is there some other technique I
> should be using instead to accomplish this sort of thing?
>
> Thanks for your help! Example of awful eval-based code follows:
>
>
> my.subset <- function(x ,i ,j ,... ,drop=TRUE) {
> brace.fcn <- get("[",pos="package:base")
> code <- 'brace.fcn(x,'
> if (!missing(i)) code <- paste(code ,'i' ,sep="")
> # This fails to distinguish between the mat[1:21] and mat[1:21,] cases:
> if (length(dim(x)) > 1 && (missing(i) || length(dim(i)) <= 1))
> code <- paste(code ,',' ,sep="")
> if (!missing(j)) code <- paste(code ,'j' ,sep="")
> if (!missing(...)) code <- paste(code ,',...' ,sep="")
> if (!missing(drop)) code <- paste(code ,',drop=drop' ,sep="")
> code <- paste(code ,')' ,sep="")
> result <- eval(parse(text=code))
> # FINALLY we have the stock result, now modify it some more...
> result
> }
>
> --
> Andrew Piskorski <atp at piskorski.com>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list