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.tur...@auckland.ac.nz> wrote: > > On Wed, 1 Sep 2021 05:35:03 -0400 > Duncan Murdoch <murdoch.dun...@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@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]] ______________________________________________ R-help@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.