Bill Dunlap
2022-Jun-22 16:44 UTC
[Rd] stats::getInitial: requires the model to live in the stats namespace or above
Shouldn't the get()'s in stats:::getInitial.formula be looking in the environment of the formula, not the environment of getInitial.formula? --- selfStart.R (revision 82512) +++ selfStart.R (working copy) @@ -78,13 +79,19 @@ switch (length(object), stop("argument 'object' has an impossible length"), { # one-sided formula - func <- get(as.character(object[[2L]][[1L]])) + if (!is.call(object[[2L]])) { + stop("Right-hand side of formula is not a call") + } + func <- get(as.character(object[[2L]][[1L]]), mode="function", envir=environment(object)) getInitial(func, data, mCall = as.list(match.call(func, call object[[2L]])), ...) }, { # two-sided formula - func <- get(as.character(object[[3L]][[1L]])) + if (!is.call(object[[3L]])) { + stop("Right-hand side of formula is not a call") + } + func <- get(as.character(object[[3L]][[1L]]), mode="function", envir=environment(object)) getInitial(func, data, mCall = as.list(match.call(func, call object[[3L]])), LHS = object[[2L]], ...) -Bill On Wed, Jun 22, 2022 at 8:25 AM Ivan Krylov <krylov.r00t at gmail.com> wrote:> Hello R-devel, > > Here's a corner case I've stumbled upon recently: > > local({ > # Originally this was a package namespace, but a local > # environment also leads to failure > stopifnot(!identical(environment(), globalenv())) > > # Make a self-starting model inside this private environment... > SSlinear <- selfStart( > ~ a * x + b, > function(mCall, data, LHS, ...) { > xy <- sortedXyData(mCall[['x']], LHS, data) > setNames( > coef(lm(y ~ x, xy)), > mCall[c('b', 'a')] > ) > }, > c('a', 'b') > ) > > # ...and try to use it > x <- 1:100 > y <- 100 + 5 * x + rnorm(length(x), sd = 10) > nls(y ~ SSlinear(x, a, b)) > # error in get('SSlinear'): object not found > }) > > As a workaround, I'll just provide the starting values manually, > but should this work? > > As implemented [1], getInitial requires the model object to live in the > stats package namespace or any of its parents, which eventually include > the global environment and the attached packages, but not the private > namespaces of the packages or any other local environments. This > results from the fact that getInitial() uses plain get() in order to > resolve the symbol for the self-starting model, and get() defaults to > the current environment, which leads a chain of stats -> imports:stats > -> base -> global environment -> attached packages. > > It seems easy to suggest get(., envir = environment(object)) as a fix, > which would be able to access anything available at the time of > creation of the formula. On the other hand, it would break the case > when the stats package is not attached to the global environment or the > formula environment, which currently works. > > -- > Best regards, > Ivan > > [1] > > https://github.com/r-devel/r-svn/blob/d43497cbc927e632c6f597fa23001c3f31d4cae6/src/library/stats/R/selfStart.R#L81-L87 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
Duncan Murdoch
2022-Jun-22 17:57 UTC
[Rd] stats::getInitial: requires the model to live in the stats namespace or above
On 22/06/2022 12:44 p.m., Bill Dunlap wrote:> Shouldn't the get()'s in stats:::getInitial.formula be looking in the > environment of the formula, not the environment of getInitial.formula?Yes, that definitely looks like the right environment to use. Ivan, is that what you meant by "environment(object)"? Duncan Murdoch> > --- selfStart.R (revision 82512) > +++ selfStart.R (working copy) > @@ -78,13 +79,19 @@ > switch (length(object), > stop("argument 'object' has an impossible length"), > { # one-sided formula > - func <- get(as.character(object[[2L]][[1L]])) > + if (!is.call(object[[2L]])) { > + stop("Right-hand side of formula is not a call") > + } > + func <- get(as.character(object[[2L]][[1L]]), mode="function", > envir=environment(object)) > getInitial(func, data, > mCall = as.list(match.call(func, call > object[[2L]])), > ...) > }, > { # two-sided formula > - func <- get(as.character(object[[3L]][[1L]])) > + if (!is.call(object[[3L]])) { > + stop("Right-hand side of formula is not a call") > + } > + func <- get(as.character(object[[3L]][[1L]]), mode="function", > envir=environment(object)) > getInitial(func, data, > mCall = as.list(match.call(func, call > object[[3L]])), > LHS = object[[2L]], ...) > > -Bill > > > On Wed, Jun 22, 2022 at 8:25 AM Ivan Krylov <krylov.r00t at gmail.com> wrote: > >> Hello R-devel, >> >> Here's a corner case I've stumbled upon recently: >> >> local({ >> # Originally this was a package namespace, but a local >> # environment also leads to failure >> stopifnot(!identical(environment(), globalenv())) >> >> # Make a self-starting model inside this private environment... >> SSlinear <- selfStart( >> ~ a * x + b, >> function(mCall, data, LHS, ...) { >> xy <- sortedXyData(mCall[['x']], LHS, data) >> setNames( >> coef(lm(y ~ x, xy)), >> mCall[c('b', 'a')] >> ) >> }, >> c('a', 'b') >> ) >> >> # ...and try to use it >> x <- 1:100 >> y <- 100 + 5 * x + rnorm(length(x), sd = 10) >> nls(y ~ SSlinear(x, a, b)) >> # error in get('SSlinear'): object not found >> }) >> >> As a workaround, I'll just provide the starting values manually, >> but should this work? >> >> As implemented [1], getInitial requires the model object to live in the >> stats package namespace or any of its parents, which eventually include >> the global environment and the attached packages, but not the private >> namespaces of the packages or any other local environments. This >> results from the fact that getInitial() uses plain get() in order to >> resolve the symbol for the self-starting model, and get() defaults to >> the current environment, which leads a chain of stats -> imports:stats >> -> base -> global environment -> attached packages. >> >> It seems easy to suggest get(., envir = environment(object)) as a fix, >> which would be able to access anything available at the time of >> creation of the formula. On the other hand, it would break the case >> when the stats package is not attached to the global environment or the >> formula environment, which currently works. >> >> -- >> Best regards, >> Ivan >> >> [1] >> >> https://github.com/r-devel/r-svn/blob/d43497cbc927e632c6f597fa23001c3f31d4cae6/src/library/stats/R/selfStart.R#L81-L87 >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel