[S] SUMMARY ADDENDUM: How to replace formal name with value in call

Terry Elrod (Terry.Elrod@UAlberta.ca)
Tue, 4 Aug 1998 06:59:15 -0600

Since posting my summary, I received additional suggestions that do not
involve eval or do.call, but instead fix up the value returned by the called
function (au) from within the calling function (step.au). The cited
advantage is the avoidance of the overhead of calls to eval (directly or
from within do.call), which can build up over many iterations within a
function like step.

My thanks to Scott Chaslalow (whose note appears below) and Lynd Bacon.

Terry Elrod

-----Original Message-----
From: Scott.Chasalow@USERS.PV.WAU.NL
Sent: Friday, July 31, 1998 3:58 AM
To: Terry.Elrod@UAlberta.ca
Subject: re: [S] SUMMARY: How to replace formal name with value in call

Dear Terry,

Just a wee warning.

On Thu Jul 30 18:56:39 1998,
Terry Elrod <Terry.Elrod@UAlberta.ca> wrote:
>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
>solutions, he seems to prefer the one using do.call, which indeed seems to
>be the most straightforward. He lists that solution second.

Code snippets:

> eval(newcall, sys.parent())

> do.call("update", list(formula=y~x, innerarg=outerarg)) # missing ")" in
original, by the way

> eval(parse(text=tmp))

Explicit calls to eval(), such as suggested by Brian (note that do.call()
calls eval()) have a relatively large cost in terms of both memory usage and
processing time. Ordinarily this is no problem. But if you are working
very large datasets, or doing very many analyses (e.g. doing thousands of
simulations), this extra overhead can really add up. (I think the problems
arise from copying of evaluation frames.) I had such a case not too long
My code was surprisingly slow, and I finally traced the cause to a call to
do.call() embedded deep in the code somewhere. So... my advice is to be
pretty sure you need it, or else that your functions won't be used in a
context in which such issues matter, before adopting such a solution.

It is also possible, by the way, to treat a call as a list, and replace
argument values using list subscripting. For example:

> fun
function(a = 1, b = 2, fix.call = T)
fun2 <- function(a, d)
list(a = a, d = d, call = match.call())
out <- fun2(a, b)
if(fix.call) {
out$call$a <- substitute(a)
out$call$d <- substitute(b)
> fun(fix = F)
[1] 1

[1] 2

fun2(a = a, d = b)

> fun()
[1] 1

[1] 2

fun2(a = 1, d = 2)

> fun(sum(1:10), mean(1:10)) # This is why substitute() is needed.
[1] 55

[1] 5.5

fun2(a = sum(1:10), d = mean(1:10))

This type of solution is less general and possibly less robust than Brian's
suggestions, but it IS more efficient.


Wageningen Agricultural University
Laboratory of Plant Breeding
P.O. Box 386
6700 AJ Wageningen


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