[R] What if there's nothing to dispatch on?

Bill Dunlap w||||@mwdun|@p @end|ng |rom gm@||@com
Thu Sep 2 00:57:27 CEST 2021


Is this the kind of thing you are looking for?  It separates the scoping
issue from the method dispatch by defining another S3-generic function,
".foo".

> foo <- function(x, ..., data=NULL) with(data, .foo(x, ...))
> .foo <- function(x, ...) UseMethod(".foo")
> .foo.default <- function(x, ...) cat("default method\n")
> .foo.integer <- function(x, ...) cat("integer method\n")
> .foo.formula <- function(x, ...) cat("formula method\n")
>
> rm(x)
Warning message:
In rm(x) : object 'x' not found
> foo(32L)
integer method
> foo(y~x)
formula method
> foo(x, data=list(x=2.7))
default method
> x <- 45L ; foo(x)
integer method
> x <- 45L ; foo(x, data=list(x=3.4))
default method
> x <- 45L ; foo(x, data=list(x=Y~X1+X2))
formula method

On Wed, Sep 1, 2021 at 3:30 PM Rolf Turner <r.turner using auckland.ac.nz> wrote:

>
> On Wed, 1 Sep 2021 05:35:03 -0400
> Duncan Murdoch <murdoch.duncan using gmail.com> wrote:
>
> > On 31/08/2021 11:59 p.m., Rolf Turner wrote:
> > >
> > > I'm trying to build a pair of (S3) methods, a "formula" method and a
> > > "default" method.  The methods have a "data" argument.  If the
> > > variables in question cannot be found in "data" then they should be
> > > sought in the global environment.
> > >
> > > My problem is that the generic dispatches on its first argument,
> > > which may be a formula (in which case it of course dispatches to
> > > the formula method) or the first of the variables.  If this
> > > variable exists in the global environment then all is well.  But if
> > > it doesn't exist there, then the generic falls over with an error
> > > of the form "object 'x' not found" --- because there isn't anything
> > > to dispatch on.
> > >
> > > I'd *like* to be able to tell the generic that if "x" is not found
> > > then it should dispatch to the default method (which will, if the
> > > call is sensible, find "x" in "data").
> > >
> > > Is there any way to tell the generic to do this?
> > >
> > > Or is there any other way out of this dilemma? (Other than "Give up
> > > and go to the pub", which I cannot currently do since Auckland is
> > > in Level 4 lockdown. :-) )
> > >
> >
> > That design is probably not a good idea:  what if one of the
> > variables in data matches the name of some other object in the global
> > environment? Then it would dispatch on that other object, and things
> > won't go well.
> >
> > But here's a way to shoot yourself in the foot:
> >
> > function(x) {
> >    x1 <- try(x, silent = TRUE)
> >    if (inherits(x1, "try-error"))
> >      foo.default(x)
> >    else
> >      UseMethod("foo", x)
> > }
> >
> > Happy shooting!
>
> Thanks Duncan. I don't understand your warning, but.
>
> If I call foo(y ~ x,data=xxx) I want the generic to dispatch to the
> formula method.  That method will then look for y and x first in xxx,
> and if it can't find them there it then will look for them in the global
> environment.
>
> If I call foo(x,y,data=xxx) I want the generic to dispatch to the
> default method, irrespective of whether x exists in the global
> environment.  I can't figure out how to arrange this.  As before
> (if I could arrange for the dispatch to happen as desired) I would want
> the method to look for y and x first in xxx, and if it can't find them
> there it then will look for them in the global environment.
>
> It doesn't matter there is an "x" in both xxx and in the global
> environment; the methods will/should use the "x" from xxx.
>
> I don't see a problem with respect to this issue.
>
> Whatever.  I can't get your shoot-in-the-foot solution to work anyway.
>
> If I set
>
>     xxx <- data.frame(u=1:10,v=rnorm(10))
>
> and do
>
>     foo(x=u,y=v,data=xxx)
>
> I get
>
> > Error in foo.default(x, y, data) : Cannot find x.
>
> The argument names need to match up.  Note that calling foo.default()
> directly works:
>
>     foo.default(x=u,y=v,data=xxx)
>
> runs just fine.
>
> I think I'm going to have to give up on the classes-and-methods
> approach.  I *think* I can see a way through with a using a single
> function and if-statements based on your "try" idea.
>
> Thanks!!!
>
> cheers,
>
> Rolf
>
> --
> Honorary Research Fellow
> Department of Statistics
> University of Auckland
> Phone: +64-9-373-7599 ext. 88276
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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.
>

	[[alternative HTML version deleted]]



More information about the R-help mailing list