[R] Question about substitute (and eval, parse and deparse)
Henrik Bengtsson
hb at maths.lth.se
Wed Jan 23 18:50:12 CET 2002
I would like to define a function at run-time, but I just can't make it
work (please don't question why I want to do this, because that would be
too much to explain). For example, I want to define the the following
function
foo <- function(x) {
cat("Function", "foo", "was called with argument", x, ".\n")
}
However, I would like to create similar function where 'foo' is replaced
with say 'bar' and 'x' is replaced with 'object'. I'll use the variables
'name' and 'arg' for this purpose;
name <- "foo";
arg <- "x";
Now I'll create the 'call' to be evaluate to define the new function:
call <- substitute(fcn <- function(arg) { cat("Function", name, "was
called with argument", arg, ".\n"); }, list=list(fcn=as.name(name),
arg=as.name(arg), name=name))
Now looking at the call things look a little bit strange:
> print(call)
foo <- function(arg) {
cat("Function", "foo", "was called with argument", x, ".\n")
}
> str(call)
language foo <- function(arg) { cat("Function", "foo", "was called
with argument", x, ".\n") ...
Notice how the name ('foo') and the arguments to 'cat' ("foo", and 'x')
of the function are correct, but *not* the first argument/formal ('arg').
For me this is strange. Continuing anyway and evaluating this call by
> eval(call)
will define the function 'foo'. Now looking at this function we get
> print(foo)
function(arg) { cat("Function", name, "was called with argument", arg,
".\n"); }
where we see that 'name' and 'arg' now is back!? If we instead use
body() we get the following
> body(foo)
{
cat("Function", "foo", "was called with argument", x, ".\n")
}
which is what we expected and finally
> attr(foo, "source")
[1] "function(arg) { cat(\"Function\", name, \"was called with
argument\", arg, \".\\n\"); }"
which is not what we expected. Further more, calling 'foo' will *not*
work:
> foo(2)
Error in cat("Function", "foo", "was called with argument", x, ".\n") :
Object "x" not found
> foo(x=2)
Error in foo(x = 2) : unused argument(s) (x ...)
> foo(arg=2)
Error in cat("Function", "foo", "was called with argument", x, ".\n") :
Object "x" not found
I have also tried
call <- substitute(fcn <- function(arg) { cat("Function", name,
"was called with argument", argName, ".\n"); },
list=list(fcn=as.name(name), arg=arg, name=name, argName=as.name(arg)))
with the same result. So, it comes to the argument/formal 'arg'.
A STEP CLOSER?
If one first deparse the call and the parse into a new call, which is then
evaluated by 'eval':
> eval(parse(text=deparse(call)))
then it the body of the function gets correct but I still have problem
with the arguments/formals:
> print(foo)
function(arg) {
cat("Function", "foo", "was called with argument", x, ".\n")
}
> body(foo)
{
cat("Function", "foo", "was called with argument", x, ".\n")
}
> attr(foo, "source")
[1] "function(arg) {"
[2] " cat(\"Function\", \"foo\", \"was called with argument\", x,
\".\\n\")"
[3] "}"
So, what is going on here? How should I do this in a correct way?
I really appreciate your help!
Henrik Bengtsson
Dept. of Mathematical Statistics @ Centre for Mathematical Sciences
Lund Institute of Technology/Lund University, Sweden (+2h UTC)
Office: P316, +46 46 222 9611 (phone), +46 46 222 4623 (fax)
h b @ m a t h s . l t h . s e
http://www.maths.lth.se/matstat/staff/hb/
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
More information about the R-help
mailing list