Thank you to both Duncan and Ivan for the detailed answers. I'll point
the mixR maintainer at this thread in the list archive, because your
suggestions were so clear, and I can't explain them as thoroughly.

I'll keep using x as the argument name for now.

Much appreciated,
Sarah

On Thu, May 25, 2023 at 10:18 AM Sarah Goslee <sarah.gos...@gmail.com> wrote:
>
> Hi,
>
> I ran into a problem with S3 method dispatch and scoping while trying
> to use functions from the mixR package within my own functions. I know
> enough to find the problem (I think!), but not enough to fix it
> myself. The problem isn't really a package-specific problem, so I'm
> starting here, and will file an issue with the maintainer once I have
> a solution.
>
> Detailed explanation below, but briefly, the S3 methods in this
> package use match.call() and then eval() to select the correct
> internal method. This works fine from the command line, but if the
> method is called from within another function, the use of
> environment() within eval() means that the objects passed to the
> wrapper function are no longer visible within the eval() call.
>
> I have a two-part question:
> A. How do I get around this right now?
> B. What would the correct approach be for the package authors?
>
> library(mixR)
>
> # first example from ?mixfit
> ## fitting the normal mixture models
> set.seed(103)
> x <- rmixnormal(200, c(0.3, 0.7), c(2, 5), c(1, 1))
> data <- bin(x, seq(-1, 8, 0.25))
> fit1 <- mixfit(x, ncomp = 2)  # raw data
> rm(x, data)
> ###
>
> # simple function
> funworks <- function(x) {
>     print(x)
> }
>
> ###
>
> # almost identical simple function
> funfails <- function(thisx) {
>     print(thisx)
> }
>
> ###
>
> funworks(fit1)
> funfails(fit1)
>
> #######
>
> The explanation as I understand it...
>
> print called on this object gets passed to print.mixfitEM(), which is:
>
>
> function (x, digits = getOption("digits"), ...)
> {
>     family <- x$family
>     mc <- match.call()
>     mc$digits <- digits
>     fun.name <- paste0("print", family)
>     mc[[1]] <- as.name(fun.name)
>     eval(mc, environment())
> }
>
>
> Working through the calls, when eval() is called from within funfails(), mc is
> printnormal(x = thisx, digits = 7)
> and the calling environment does not contain thisx.
>
> In funworks(), it's
> printnormal(x = x, digits = 7)
>
> and x is found.
>
> So, I can get around the problem by naming my argument x, as in
> funworks(), but that's unsatisfying. Is there something else I can do
> to get my functions to work?
>
> And what's the correct way to do what print.mixfitEM() is doing, so
> that it works regardless? I poked around for a while, but didn't find
> a clear (to me!) answer.
>
> Thanks,
> Sarah
>
> --
> Sarah Goslee (she/her)
> http://www.numberwright.com



-- 
Sarah Goslee (she/her)
http://www.numberwright.com

______________________________________________
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.

Reply via email to