I have two functions which appear to differ only in their environments. They look like:> d1 > function (x, mean = 0, sd = 1, log = FALSE) > (((x - mean)/sd)^2 - 1) * if (log) 1 else dnorm(x, mean, sd)/sd > <environment: namespace:stats>and> d2 > function (x, mean = 0, sd = 1, log = FALSE) > (((x - mean)/sd)^2 - 1) * if (log) 1 else dnorm(x, mean, sd)/sdTyping "environment(d1)" gives> <environment: namespace:stats>and typing "environment(d2)" gives> <environment: R_GlobalEnv>The d2() function however gives an incorrect result:> d1(1,0,3,TRUE) > [1] -0.2962963 > d2(1,0,3,TRUE) > [1] -0.8888889In d2() the result of the if() statement does not get divided by the final "sd" whereas in d1() it does (which is the desired/correct result). Of course the code is ridiculously kludgy (it was produced by "symbolic differentiation"). That's not the point. I'm just curious (idly?) as to *why* the association of the namespace:stats environment with d1() causes it to "do the right thing". Can anyone give me any insight? Ta. cheers, Rolf Turner -- Honorary Research Fellow Department of Statistics University of Auckland Phone: +64-9-373-7599 ext. 88276
In general, the search for symbols for a function Z in a package Y will span only those namespaces that the package Y specifies. The search for symbols in a function whose parent environment is the global environment will start there, thereby opening the door to find masking versions of functions instead of the intended package function. Kind of hard to investigate your case from here. On November 6, 2021 5:35:08 PM PDT, Rolf Turner <r.turner at auckland.ac.nz> wrote:> >I have two functions which appear to differ only in their environments. >They look like: > >> d1 >> function (x, mean = 0, sd = 1, log = FALSE) >> (((x - mean)/sd)^2 - 1) * if (log) 1 else dnorm(x, mean, sd)/sd >> <environment: namespace:stats> > >and > >> d2 >> function (x, mean = 0, sd = 1, log = FALSE) >> (((x - mean)/sd)^2 - 1) * if (log) 1 else dnorm(x, mean, sd)/sd > >Typing "environment(d1)" gives > >> <environment: namespace:stats> > >and typing "environment(d2)" gives > >> <environment: R_GlobalEnv> > >The d2() function however gives an incorrect result: > >> d1(1,0,3,TRUE) >> [1] -0.2962963 >> d2(1,0,3,TRUE) >> [1] -0.8888889 > >In d2() the result of the if() statement does not get divided >by the final "sd" whereas in d1() it does (which is the desired/correct >result). > >Of course the code is ridiculously kludgy (it was produced by "symbolic >differentiation"). That's not the point. I'm just curious (idly?) as >to *why* the association of the namespace:stats environment with d1() >causes it to "do the right thing". > >Can anyone give me any insight? Ta. > >cheers, > >Rolf Turner >-- Sent from my phone. Please excuse my brevity.
On Sun, Nov 7, 2021 at 6:05 AM Rolf Turner <r.turner at auckland.ac.nz> wrote:> > > I have two functions which appear to differ only in their environments. > They look like: > > > d1 > > function (x, mean = 0, sd = 1, log = FALSE) > > (((x - mean)/sd)^2 - 1) * if (log) 1 else dnorm(x, mean, sd)/sd > > <environment: namespace:stats> > > and > > > d2 > > function (x, mean = 0, sd = 1, log = FALSE) > > (((x - mean)/sd)^2 - 1) * if (log) 1 else dnorm(x, mean, sd)/sd > > Typing "environment(d1)" gives > > > <environment: namespace:stats> > > and typing "environment(d2)" gives > > > <environment: R_GlobalEnv> > > The d2() function however gives an incorrect result: > > > d1(1,0,3,TRUE) > > [1] -0.2962963 > > d2(1,0,3,TRUE) > > [1] -0.8888889It can't be as simple as that. I get the same result (as your d2) with the following: d <- function (x, mean = 0, sd = 1, log = FALSE) { (((x - mean)/sd)^2 - 1) * if (log) 1 else dnorm(x, mean, sd) / sd } d(1, 0, 3, TRUE) environment(d) environment(d) <- as.environment("package:stats") d(1, 0, 3, TRUE)> In d2() the result of the if() statement does not get divided > by the final "sd" whereas in d1() it does (which is the desired/correct > result). > > Of course the code is ridiculously kludgy (it was produced by "symbolic > differentiation"). That's not the point. I'm just curious (idly?) as > to *why* the association of the namespace:stats environment with d1() > causes it to "do the right thing".This sounds like a difference in precedence. The expression if (log) 1 else dnorm(x, mean, sd) / sd is apparently being interpreted differently as d1: (if (log) 1 else dnorm(x, mean, sd)) / sd d2: if (log) 1 else (dnorm(x, mean, sd)) / sd) It's unclear how environments could affect this, so it would be very helpful to have a reproducible example. Best, -Deepayan> Can anyone give me any insight? Ta. > > cheers, > > Rolf Turner > > -- > Honorary Research Fellow > Department of Statistics > University of Auckland > Phone: +64-9-373-7599 ext. 88276 > > ______________________________________________ > 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.