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.