[S] SUMMARY: How to replace formal name with value in call to another function?

Terry Elrod (Terry.Elrod@UAlberta.ca)
Thu, 30 Jul 1998 10:56:39 -0600


My heartfelt thanks to Nick Ellis, Pierre Joyet and Prof. Brian D. Ripley
for helpful solutions. Rather than list all solutions, I reprint in full
Prof. Ripley's reply, which is definitive and most instructive. Of his three
solutions, he seems to prefer the one using do.call, which indeed seems to
be the most straightforward. He lists that solution second.

Again, my thanks to all.

Terry Elrod
------------------------------------------------------------------------
Terry Elrod; Assoc. Prof. of Marketing
3-23 Faculty of Business; Univ. of Alberta; Edmonton, AB; Canada T6G 2R6
phone: 403-492-5884; fax: 403-492-3325; email: Terry.Elrod@UAlberta.ca
------------------------------------------------------------------------

On Wed, 29 Jul 1998, Terry Elrod wrote:

> Here's a problem that sometimes arises in S-Plus:
>
> I have written an estimation method which creates its own class. The
> estimation is accomplished by a function au with arguments such as
innerarg.
> It returns an estimated model of class "au", including a list component
> "call" containing the call to au as returned by match.call().
>
> I have also written a stepwise procedure called step.au, which of course
> calls au a number of times. The call to au (through update) has an
argument
> such as innerarg = outerarg, where the value of outerarg is set within
> step.au.
>
> The problem is that the model returned by step.au, the best model as found
> by step.au, has component call containing innerarg = outerarg. Since
> outerarg is not given a value within au, and since its value was not
stored
> in the object created by step.au, this model cannot be re-estimated by a
> call directly to au, or by a call to update, etc.
>
> Here's a bit of code to illustrate the problem. Four dots is used to
> indicate missing code.
>
> step.au(object, scope, ...., outerarg){
> ....
> update(object, newformula, innerarg = outerarg)
> ....
> }
>
> au(formula, ...., ...) {
> ....
> rslt$call _ match.call()
> rslt
> }
>
> > .test _ step.au(object, ...., outerarg = 5)
> > .test$call
> .... innerarg = outerarg ....
> > # The result I would like to see here is innerarg = 5
> > # Can anyone help with this?
> > # Hint: I've checked into this enough that the answer is not blazingly
> obvious.
> > # Thanks in advance for any help ....

There are not quite enough details here (what method is update using?)
but the answer should be `do.call'.

Let me fake an example with update.default:

step.au <- function(object, scope, outerarg)
{
update(object, y ~ x, innerarg = outerarg)
}
au <- function(formula, innerarg=0)
{
call <- match.call()
fit <- list(formula= call$formula, call=call)
class(fit) <- "au"
fit
}

> test.au <- au(y ~ z, 17)
> test.au
$formula:
y ~ z

$call:
au(formula = y ~ z, innerarg = 17)

attr(, "class"):
[1] "au"

> step.au(test.au, outerarg=5)
$formula:
y ~ x

$call:
au(formula = y ~ x, innerarg = outerarg)

OK, so that is what you want to avoid, and update is trying hard to give
you. One possibility is your own update:

update.au <- function(object, formula, innerarg)
{
newcall <- object$call
if(!missing(formula))
newcall$formula <- as.vector(update.formula(object$formula, formula))
if(!missing(innerarg)) newcall$innerarg <- innerarg
eval(newcall, sys.parent())
}

> step.au(test.au, outerarg=5)
$formula:
y ~ x

$call:
au(formula = y ~ x, innerarg = 5)

attr(, "class"):
[1] "au"

Another is to construct the call:

step.au <- function(object, scope, outerarg)
{
do.call("update", list(formula=y~x, innerarg=outerarg)
}

or

step.au <- function(object, scope, outerarg)
{
newform <- as.formula("y ~ x")
tmp <- paste("update(", deparse(substitute(object)),
", formula=", deparse(newform),
", innerarg=", outerarg, ")")
eval(parse(text=tmp))
}

I hope that is instructive.

-- 
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
Uni
versity of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272860 (secr)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

----------------------------------------------------------------------- This message was distributed by s-news@wubios.wustl.edu. To unsubscribe send e-mail to s-news-request@wubios.wustl.edu with the BODY of the message: unsubscribe s-news