On 2/9/2016 9:51 AM, Bert Gunter wrote:> Spencer, et. al.: > > As I suspected, my previous "solution" was pretty stupid. Here is, I > think, the "right" way to > go about it: > > plotxy <- function(x,...){ > mcall <- match.call(expand.dots=FALSE) > mcall[[1]]<- plot.default > eval(mcall) > }Hi, Bert, et al.: I couldn't get that to work, either: > XY <- data.frame(x1=1:3, y1=4:6) > plotxy(y1~x1, XY, xlim=c(0, max(x1))) Error in eval(expr, envir, enclos) : object 'y1' not found However, my original function inside "with" worked, but Bert's suggestion didn't: > plot.sg <- function(x, ...){ + plot(x, ...) + } > with(XY, plot.sg(y1~x1, xlim=c(0, max(x1)))) > # worked, but "plotxy" with match.call didn't: > with(XY, plotxy(y1~x1, xlim=c(0, max(x1)))) Error in eval(expr, envir, enclos) : object 'y1' not found > sessionInfo() R version 3.2.3 (2015-12-10) Platform: x86_64-apple-darwin13.4.0 (64-bit) Running under: OS X 10.11.2 (El Capitan) locale: [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 attached base packages: [1] stats graphics grDevices utils datasets methods base loaded via a namespace (and not attached): [1] tools_3.2.3 I don't understand this, but "with" is acceptable for my current needs. Thanks again to Bert & Jeff. Spencer Graves> > Best, > Bert > > > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Mon, Feb 8, 2016 at 8:10 PM, Spencer Graves > <spencer.graves at effectivedefense.org> wrote: >> Hi, Jeff et al.: >> >> >> On 2/8/2016 9:52 PM, Jeff Newmiller wrote: >>> plotxy(y1~x1, XY, xlim=c(0, max(XY$x1))) >> >> Yes, Thanks. >> >> >> Is there a way to do this from within "plotxy", so I can call >> "plotxy" as I call "plot"? >> >> >> Thanks, >> Spencer >> >> >>> -- >>> Sent from my phone. Please excuse my brevity. >>> >>> On February 8, 2016 7:17:57 PM PST, Spencer Graves >>> <spencer.graves at effectivedefense.org> wrote: >>> >>> I'm getting an interesting error: >>> >>> >>> plotxy <- function(x, ...){ >>> >>> + plot(x, ...) >>> + } >>> >>> XY <- data.frame(x1=1:3, y1=4:6) plotxy(y1~x1, XY, xlim=c(0, >>> max(x1))) >>> >>> Show Traceback >>> >>> Rerun with Debug >>> Error in eval(expr, envir, enclos) : object 'x1' not found >>> >>> >>> The following work: >>> >>> >>> plotxy(y1~x1, XY) >>> plot(y1~x1, XY, xlim=c(0, max(x1))) >>> >>> >>> Within "plotxy", R can't find "x1" to compute "xlim". Is there a >>> way I can make x1 available to xlim? >>> >>> >>> Thanks, >>> Spencer >>> >>> ------------------------------------------------------------------------ >>> >>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >>> https://stat.ethz.ch/mailman/listinfo/r-help >>> PLEASE do read the posting guidehttp://www.R-project.org/posting-guide.html >>> and provide commented, minimal, self-contained, reproducible code. >>> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at 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.
Oh, yes certainly. But I thought the point was to avoid "cheating" with with() or assuming that the "x" argument was a formula. Yes, my "smarter" solution doesn't work -- my error. I still think there must be a small tweak to fix it, but I haven't figured it out yet. AFAICS, my earlier "stupid" solution does work as originally intended with no "cheating" :> plotxy <- function(x,data = NULL,...){+ mcall <- match.call() + if(inherits(x,"formula"))enc <- environment(x) + else enc <- parent.frame() + if(!is.null(data)){ + env <- data + mcall <- mcall[-match("data",names(mcall))] + } else env <- NULL + mcall[[1]] <- plot.default + eval(mcall,envir=env,enclos=enc) + }> > > > XY <- data.frame(x1=1:3, y1=4:6) > plotxy(y1~x1, XY, xlim=c(0, max(x1)))The problem with your original approach I believe is that the evaluator wants to evaluate xlim before it passes it on to your plot call. By default, it evaluates it in the parent frame where there is no x1 -- ergo the error (I would appreciate correction if this is wrong). If you look at the code for plot.default() and then grDevices:: xy.coords, you'll see how the call is parsed and evaluated in the appropriate environment. My code above is trying to do the same thing, though I may still have holes. Cheers, Bert Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Tue, Feb 9, 2016 at 8:33 AM, Spencer Graves <spencer.graves at effectivedefense.org> wrote:> > > On 2/9/2016 9:51 AM, Bert Gunter wrote: >> >> Spencer, et. al.: >> >> As I suspected, my previous "solution" was pretty stupid. Here is, I >> think, the "right" way to >> go about it: >> >> plotxy <- function(x,...){ >> mcall <- match.call(expand.dots=FALSE) >> mcall[[1]]<- plot.default >> eval(mcall) >> } > > > > Hi, Bert, et al.: I couldn't get that to work, either: > > >> XY <- data.frame(x1=1:3, y1=4:6) >> plotxy(y1~x1, XY, xlim=c(0, max(x1))) > > Error in eval(expr, envir, enclos) : object 'y1' not found > > > However, my original function inside "with" worked, but Bert's > suggestion didn't: > > >> plot.sg <- function(x, ...){ > + plot(x, ...) > + } >> with(XY, plot.sg(y1~x1, xlim=c(0, max(x1)))) >> # worked, but "plotxy" with match.call didn't: >> with(XY, plotxy(y1~x1, xlim=c(0, max(x1)))) > > Error in eval(expr, envir, enclos) : object 'y1' not found > >> sessionInfo() > R version 3.2.3 (2015-12-10) > Platform: x86_64-apple-darwin13.4.0 (64-bit) > Running under: OS X 10.11.2 (El Capitan) > > locale: > [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 > > attached base packages: > [1] stats graphics grDevices utils datasets methods base > > loaded via a namespace (and not attached): > [1] tools_3.2.3 > > > I don't understand this, but "with" is acceptable for my current > needs. > > > Thanks again to Bert & Jeff. > > > Spencer Graves >> >> >> Best, >> Bert >> >> >> >> Bert Gunter >> >> "The trouble with having an open mind is that people keep coming along >> and sticking things into it." >> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) >> >> >> On Mon, Feb 8, 2016 at 8:10 PM, Spencer Graves >> <spencer.graves at effectivedefense.org> wrote: >>> >>> Hi, Jeff et al.: >>> >>> >>> On 2/8/2016 9:52 PM, Jeff Newmiller wrote: >>>> >>>> plotxy(y1~x1, XY, xlim=c(0, max(XY$x1))) >>> >>> >>> Yes, Thanks. >>> >>> >>> Is there a way to do this from within "plotxy", so I can call >>> "plotxy" as I call "plot"? >>> >>> >>> Thanks, >>> Spencer >>> >>> >>>> -- >>>> Sent from my phone. Please excuse my brevity. >>>> >>>> On February 8, 2016 7:17:57 PM PST, Spencer Graves >>>> <spencer.graves at effectivedefense.org> wrote: >>>> >>>> I'm getting an interesting error: >>>> >>>> >>>> plotxy <- function(x, ...){ >>>> >>>> + plot(x, ...) >>>> + } >>>> >>>> XY <- data.frame(x1=1:3, y1=4:6) plotxy(y1~x1, XY, xlim=c(0, >>>> max(x1))) >>>> >>>> Show Traceback >>>> >>>> Rerun with Debug >>>> Error in eval(expr, envir, enclos) : object 'x1' not found >>>> >>>> >>>> The following work: >>>> >>>> >>>> plotxy(y1~x1, XY) >>>> plot(y1~x1, XY, xlim=c(0, max(x1))) >>>> >>>> >>>> Within "plotxy", R can't find "x1" to compute "xlim". Is >>>> there a >>>> way I can make x1 available to xlim? >>>> >>>> >>>> Thanks, >>>> Spencer >>>> >>>> >>>> ------------------------------------------------------------------------ >>>> >>>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >>>> https://stat.ethz.ch/mailman/listinfo/r-help >>>> PLEASE do read the posting >>>> guidehttp://www.R-project.org/posting-guide.html >>>> and provide commented, minimal, self-contained, reproducible code. >>>> >>> [[alternative HTML version deleted]] >>> >>> ______________________________________________ >>> R-help at 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. > >
Hi, Bert: On 2/9/2016 11:46 AM, Bert Gunter wrote:> Oh, yes certainly. But I thought the point was to avoid "cheating" > with with() or assuming that the "x" argument was a formula. > > Yes, my "smarter" solution doesn't work -- my error. I still think > there must be a small tweak to fix it, but I haven't figured it out > yet. AFAICS, my earlier "stupid" solution does work as originally > intended with no "cheating" : > >> plotxy <- function(x,data = NULL,...){ > + mcall <- match.call() > + if(inherits(x,"formula"))enc <- environment(x) > + else enc <- parent.frame() > + if(!is.null(data)){ > + env <- data > + mcall <- mcall[-match("data",names(mcall))] > + } else env <- NULL > + mcall[[1]] <- plot.default > + eval(mcall,envir=env,enclos=enc) > + } >> >> >> XY <- data.frame(x1=1:3, y1=4:6) >> plotxy(y1~x1, XY, xlim=c(0, max(x1))) > The problem with your original approach I believe is that the > evaluator wants to evaluate xlim before it passes it on to your plot > call. By default, it evaluates it in the parent frame where there is > no x1 -- ergo the error (I would appreciate correction if this is > wrong). If you look at the code for plot.default() and then > grDevices:: xy.coords, you'll see how the call is parsed and evaluated > in the appropriate environment. My code above is trying to do the > same thing, though I may still have holes.Thanks. I failed to mention that I also wanted the same function to work with a time series, class "ts". Amazingly, my "plot.sg" worked with an object of class "ts", but your "plotxy" didn't plot what I wanted: y.ts <- ts(matrix(1:6, 3), 7) plotxy(y.ts) # plots the first series as points and ignores the second plot.sg(y.ts) # works as desired When I replaced "plot.default" with "plot" in your "plotxy", plotxy(y.ts) performed as desired, but plotxy(y1~x1, XY, xlim=c(0, max(x1))) threw an error. The following revision of your function works: plotxy <- function(x, data = NULL,...){ mcall <- match.call() if(inherits(x,"formula"))enc <- environment(x) else enc <- parent.frame() if(!is.null(data)){ env <- data mcall <- mcall[-match("data",names(mcall))] } else env <- NULL mcall[[1]] <- (if(is.ts(x)) plot else plot.default) eval(mcall,envir=env,enclos=enc) } plotxy(y1~x1, XY, xlim=c(0, max(x1))) # good plotxy(y.ts) # good However, this will be embedded in a vignette on time series analysis, so I think I'll stick with the simpler "with" solution. Thanks again, Spencer> > Cheers, > Bert > > > > > Cheers, > Bert > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Tue, Feb 9, 2016 at 8:33 AM, Spencer Graves > <spencer.graves at effectivedefense.org> wrote: >> >> On 2/9/2016 9:51 AM, Bert Gunter wrote: >>> Spencer, et. al.: >>> >>> As I suspected, my previous "solution" was pretty stupid. Here is, I >>> think, the "right" way to >>> go about it: >>> >>> plotxy <- function(x,...){ >>> mcall <- match.call(expand.dots=FALSE) >>> mcall[[1]]<- plot.default >>> eval(mcall) >>> } >> >> >> Hi, Bert, et al.: I couldn't get that to work, either: >> >> >>> XY <- data.frame(x1=1:3, y1=4:6) >>> plotxy(y1~x1, XY, xlim=c(0, max(x1))) >> Error in eval(expr, envir, enclos) : object 'y1' not found >> >> >> However, my original function inside "with" worked, but Bert's >> suggestion didn't: >> >> >>> plot.sg <- function(x, ...){ >> + plot(x, ...) >> + } >>> with(XY, plot.sg(y1~x1, xlim=c(0, max(x1)))) >>> # worked, but "plotxy" with match.call didn't: >>> with(XY, plotxy(y1~x1, xlim=c(0, max(x1)))) >> Error in eval(expr, envir, enclos) : object 'y1' not found >> >>> sessionInfo() >> R version 3.2.3 (2015-12-10) >> Platform: x86_64-apple-darwin13.4.0 (64-bit) >> Running under: OS X 10.11.2 (El Capitan) >> >> locale: >> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 >> >> attached base packages: >> [1] stats graphics grDevices utils datasets methods base >> >> loaded via a namespace (and not attached): >> [1] tools_3.2.3 >> >> >> I don't understand this, but "with" is acceptable for my current >> needs. >> >> >> Thanks again to Bert & Jeff. >> >> >> Spencer Graves >>> >>> Best, >>> Bert >>> >>> >>> >>> Bert Gunter >>> >>> "The trouble with having an open mind is that people keep coming along >>> and sticking things into it." >>> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) >>> >>> >>> On Mon, Feb 8, 2016 at 8:10 PM, Spencer Graves >>> <spencer.graves at effectivedefense.org> wrote: >>>> Hi, Jeff et al.: >>>> >>>> >>>> On 2/8/2016 9:52 PM, Jeff Newmiller wrote: >>>>> plotxy(y1~x1, XY, xlim=c(0, max(XY$x1))) >>>> >>>> Yes, Thanks. >>>> >>>> >>>> Is there a way to do this from within "plotxy", so I can call >>>> "plotxy" as I call "plot"? >>>> >>>> >>>> Thanks, >>>> Spencer >>>> >>>> >>>>> -- >>>>> Sent from my phone. Please excuse my brevity. >>>>> >>>>> On February 8, 2016 7:17:57 PM PST, Spencer Graves >>>>> <spencer.graves at effectivedefense.org> wrote: >>>>> >>>>> I'm getting an interesting error: >>>>> >>>>> >>>>> plotxy <- function(x, ...){ >>>>> >>>>> + plot(x, ...) >>>>> + } >>>>> >>>>> XY <- data.frame(x1=1:3, y1=4:6) plotxy(y1~x1, XY, xlim=c(0, >>>>> max(x1))) >>>>> >>>>> Show Traceback >>>>> >>>>> Rerun with Debug >>>>> Error in eval(expr, envir, enclos) : object 'x1' not found >>>>> >>>>> >>>>> The following work: >>>>> >>>>> >>>>> plotxy(y1~x1, XY) >>>>> plot(y1~x1, XY, xlim=c(0, max(x1))) >>>>> >>>>> >>>>> Within "plotxy", R can't find "x1" to compute "xlim". Is >>>>> there a >>>>> way I can make x1 available to xlim? >>>>> >>>>> >>>>> Thanks, >>>>> Spencer >>>>> >>>>> >>>>> ------------------------------------------------------------------------ >>>>> >>>>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >>>>> https://stat.ethz.ch/mailman/listinfo/r-help >>>>> PLEASE do read the posting >>>>> guidehttp://www.R-project.org/posting-guide.html >>>>> and provide commented, minimal, self-contained, reproducible code. >>>>> >>>> [[alternative HTML version deleted]] >>>> >>>> ______________________________________________ >>>> R-help at 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. >>