Re: [R] setMethod for "["

From: Musa Parmaksiz <musa.parmaksiz_at_gmail.com>
Date: Fri, 21 Mar 2008 20:09:03 +0100

Hi,

I modified the method as following

setMethod("[", signature=signature(x="myClass"),

          function(x, i, j, drop=FALSE)
          {
            myCall <- sys.call(-1)
            narg <- length(myCall)-length(match.call(call=sys.call(-1)))

            if (missing(i) && missing(j)) {
              res <- callNextMethod(x=x_at_x,,,drop=drop)
            } else if (missing(j)) {
              if (narg>0) res <- callNextMethod(x=x_at_x,i=i,,drop=drop)
              else res <- callNextMethod(x=x_at_x,i=i,drop=drop)
            } else if (missing(i)) {
              if (narg>0) res <- callNextMethod(x=x_at_x,,j=j,drop=drop)
              else res <- callNextMethod(x=x_at_x,j=j,drop=drop)
            } else {
              res <- callNextMethod(x=x_at_x,i=i,j=j,drop=drop)
            }
            return(res)
          }
          )

This mimics the "[" for matrices, but with arguments name matching included. It also interprets myClass[i=1] and myClass[j=1] the same way, which is a desirable side effect. I agree with your points, but from an end-user point of view (who will "see" myClass as a matrix), distinguishing myClass[1] and myClass[1,] is suitable. Thanks again for the help...

On Fri, Mar 21, 2008 at 6:05 PM, Martin Morgan <mtmorgan_at_fhcrc.org> wrote:

> Hi Musa --
>
> Musa Parmaksiz wrote:
> > Hi Martin,
> >
> > Thanks for the suggestions.
> >
> > If possible I would avoid defining several methods with different
> > signatures. For the first solution,namely
> >
> > setMethod("[",
> > signature=signature(x="myClass"),
> > function(x, i, j, ..., drop=FALSE)
> > {
> > if (missing(i) && missing(j))
> > callNextMethod(x=x_at_x,,, ..., drop=drop)
> > else if (missing(j))
> > callNextMethod(x=x_at_x, i=i, , ..., drop=drop)
> > else if (missing(i))
> > callNextMethod(x=x_at_x, , j=j, ..., drop=drop)
> > else
> > callNextMethod(x=x_at_x, i=i, j=j, ..., drop=drop)
> > })
> >
> > one cannot distinguish between test[1] and test[1,] ! I suspect we could
> > use nargs()...
>
> I thought I had seen a cleaner solution to this; perhaps someone else
> will contribute. Here's what I think:
>
> One could do something like nargs() - length(list(...)) -
> !missing(drop), but as a class designer a better decision might be to
> define [1] to be the same as [1,], and provide other ways for the
> user to convert a matrix-like object to a vector-like object.
>
> To make this point a bit stronger, an interpretation of '[' is that it
> returns a subset of the original object (i.e., an object of the same
> class as the original). This is in contrast to '[[', which might be
> interpreted as returning the contents of (a subset of) the
> object. '[' returning a vector-like object when invoked on a
> matrix-like object violates this interpretation, and might therefore
> be avoided.
>
> Also, it might seem good to 'mimic' the behavior of [ on matrices.
> But remember that the method defined above matches arguments by name
> rather than position, so already one is departing from the way in
> which subsets work with the primitive [. I would say that this
> departure is an improvement over the situation with primitive [, and
> it would be a mistake to implement [ for myClass in such a way as to
> restore position-matching.
>
> These are my opinions, probably others arrive at different conclusions.
>
> Martin
>
> > On Fri, Mar 21, 2008 at 12:43 AM, Martin Morgan <mtmorgan_at_fhcrc.org
> > <mailto:mtmorgan_at_fhcrc.org>> wrote:
> >
> > Hi Musa --
> >
> > Musa Parmaksiz wrote:
> > > Hi R-Help,
> > >
> > > Please consider the following simple case: I have a class like
> > >
> > > setClass("myClass",
> > > representation(x="matrix", y="character"))
> > >
> > > and I would like to use the method *"["* for a *myClass* objects
> (but
> > > changing the default *drop* argument from TRUE to FALSE):
> > >
> > > setMethod("[","myClass",
> > > function(x,i,j,...,drop=FALSE)
> > > {
> > > x <- x_at_x
> > > callNextMethod()
> >
> > I think you are hoping that x_at_x will be subsetted, and it appears
> that
> > it is. But I think this is a bug. 'callNextMethod' without any
> arguments
> > should be using the 'x' in the signature. This should result in an
> error
> > like the one seen here
> >
> > setMethod("[",
> > signature=signature(x="myClass"),
> > function(x, i, j, ..., drop=FALSE)
> > {
> > callNextMethod()
> > })
> >
> > > test[1,]
> > Error in x[i = i, j = , ...] : object is not subsettable
> >
> > Normally, to change the value of the variable 'seen' by the next
> method,
> > one would expect to have to write something like
> >
> >
> > setMethod("[",
> > signature=signature(x="myClass"),
> > function(x, i, j, ..., drop=FALSE)
> > {
> > callNextMethod(x=x_at_x, i=i, j=j, ..., drop=drop)
> > })
> >
> > You can now see how this is a little more complicated -- if j is
> missing
> > in the original function call, then it can't be used in an
> assignment in
> > callNextMethod. You'd have to write something like
> >
> > setMethod("[",
> > signature=signature(x="myClass"),
> > function(x, i, j, ..., drop=FALSE)
> > {
> > if (missing(i) && missing(j))
> > callNextMethod(x=x_at_x,,, ..., drop=drop)
> > else if (missing(j))
> > callNextMethod(x=x_at_x, i=i, , ..., drop=drop)
> > else if (missing(i))
> > callNextMethod(x=x_at_x, , j=j, ..., drop=drop)
> > else
> > callNextMethod(x=x_at_x, i=i, j=j, ..., drop=drop)
> > })
> >
> > or, since this is really an implementation that dispatches on the
> > 'misssing'-ness of i, j, a series of methods like
> >
> > setMethod("[",
> > signature=signature(
> > x="myClass",
> > i="ANY',
> > j="missing")
> > function(x, i, j, ..., drop=FALSE)
> > {
> > callNextMethod(x_at_x, i=i, , ..., drop=drop)
> > })
> >
> > Notice too how it is necessary to specify the argument list in quite
> an
> > odd way, with a ',' for the 'missing' variable(s). This is because
> "["
> > is a so-called 'Primitive' function, and primitive functions match
> by
> > position rather than the usual matching by name:
> >
> > > matrix(1:20,5)[4,2]
> > [1] 9
> > > matrix(1:20,5)[j=4,i=2]
> > [1] 9
> >
> > !
> >
> > I read somewhere that when faced with learning complicated systems,
> > otherwise intelligent people will develop wildly inaccurate stories
> to
> > explain why the system 'works'. The above is my story.
> >
> > Martin
> >
> >
> > > x<-as.myClass(x)
> > > }
> > > )
> > >
> > > suppose that *as.myClass* method has been already defined.
> > Actually, all I
> > > want is to pass all the arguments to *"["* method for *matrix*,
> > except
> > > changing the default behaviour for *drop*.
> > >
> > > When I execute:
> > >> test<-new("myClass",x=cbind(1:3,4:6),y="a")
> > >> test[1,] # works as expected
> > > [1] 1 4
> > >
> > >> test[1,drop=TRUE] # does not work
> > > Error: argument "j" is missing, with no default
> > > Error in callNextMethod() : error in evaluating a 'primitive'
> > next method
> > >
> > > but with a matrix the two cases work:
> > >> m<-cbind(1:3,4:6)
> > >> m[1,]
> > > [1] 1 4
> > >> m[1,drop=TRUE]
> > > [1] 1
> > >
> > > Can you please advise me a solution for this problem?
> > > Thank you in advance for the help.
> > >
> > > Musa
> > >
> > > [[alternative HTML version deleted]]
> > >
> > > ______________________________________________
> > > R-help_at_r-project.org <mailto:R-help_at_r-project.org> mailing list
> > > https://stat.ethz.ch/mailman/listinfo/r-help
> > > PLEASE do read the posting guide
> > http://www.R-project.org/posting-guide.html
> > > and provide commented, minimal, self-contained, reproducible
> code.
> >
> >
> > --
> > Martin Morgan
> > Computational Biology / Fred Hutchinson Cancer Research Center
> > 1100 Fairview Ave. N.
> > PO Box 19024 Seattle, WA 98109
> >
> > Location: Arnold Building M2 B169
> > Phone: (206) 667-2793
> >
> >
>
>
> --
> Martin Morgan
> Computational Biology / Fred Hutchinson Cancer Research Center
> 1100 Fairview Ave. N.
> PO Box 19024 Seattle, WA 98109
>
> Location: Arnold Building M2 B169
> Phone: (206) 667-2793
>

        [[alternative HTML version deleted]]



R-help_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. Received on Fri 21 Mar 2008 - 19:23:14 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Fri 21 Mar 2008 - 19:31:14 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.

list of date sections of archive