From pdalgd at gmail.com  Sat Jul 13 11:12:27 2013
From: pdalgd at gmail.com (peter dalgaard)
Date: Sat, 13 Jul 2013 11:12:27 +0200
Subject: [Rd] Alternative to eval(cl, parent.frame()) ?
In-Reply-To: <s3sk3kubzya.fsf@slagelg.uio.no>
References: <s3sk3kubzya.fsf@slagelg.uio.no>
Message-ID: <A047A4FA-A260-4484-9864-1EB1C20CDC4B@gmail.com>


On Jul 13, 2013, at 10:56 , Bj?rn-Helge Mevik wrote:

> Dear developeRs,
> 
> I maintain a package 'pls', which has a main fit function mvr(), and
> functions plsr() and pcr() which are meant to take the same arguments as
> mvr() and do exactly the same, but have different default values for the
> 'method' argument.  The three functions are all exported from the name
> space.
> 
> In the 'pre namespace' era, I took inspiration from lm() and implemented
> it like this:
> 
> plsr <- function(..., method = pls.options()$plsralg) {
>    cl <- match.call()
>    cl$method <- match.arg(method, c("kernelpls", "widekernelpls", "simpls",
>                                     "oscorespls", "model.frame"))
>    cl[[1]] <- as.name("mvr")
>    res <- eval(cl, parent.frame())
>    ...
> 
> 
> Recently, Prof. Brian Ripley kindly pointed out that this doesn't work
> properly when the 'pls' package in not attached:
> 
>> data(yarn, package='pls')
>> pls::plsr(density ~ NIR, 6, data = yarn, validation = "CV")
> <environment: R_GlobalEnv>
> Error in eval(expr, envir, enclos) : could not find function "mvr"
> 
> I first believed that
> 
>    cl[[1]] <- as.name("pls::mvr")
> 
> would fix the problem, but that did not help.  I have found that the
> following seems to work:
> 
> plsr <- function(..., method = pls.options()$plsralg) {
>    cl <- match.call()
>    cl$method <- match.arg(method, c("kernelpls", "widekernelpls", "simpls",
>                                     "oscorespls", "model.frame"))
>    arguments <- as.list(cl)[-1]
>    res <- do.call(mvr, arguments, envir = parent.frame())
>    ...
> 
> However, if I understand correctly, this will evaluate the arguments
> before handing them over to mvr().  Currently, mvr() doesn't need the
> unevaluated arguments, but if it were to, this would be a problem.
> 
> Is there an 'R best practice' for achieving what I want (several
> versions of the same function, with different default value for an
> argument)?

We discussed this recently, and I believe the winner was 

cl[[1]] <- quote(pls::mvr)

(notice that :: is an operator, so this is profoundly different from as.name("pls::mvr"), which is a symbol with two colons inside!)

-- 
Peter Dalgaard, Professor,
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com



[Rd] Alternative to eval(cl, parent.frame()) ?
peter dalgaard