[R] Extract the names of the arguments in an "expression"
Duncan Murdoch
murdoch.duncan at gmail.com
Thu Mar 24 13:40:34 CET 2011
An improvement on my suggestion using codetools is to use
codetools::findGlobals(f, merge=FALSE)
which separates the functions and variables:
$functions
[1] "*" "cos"
$variables
[1] "omega" "rho"
This is important, because R distinguishes between functions and
variables by usage when it is doing a search:
mean <- 1:10
mean(mean)
will work, because the function in the second line is found in the base
package, while the variable is the one defined on the line above.
Duncan Murdoch
On 11-03-24 8:02 AM, Duncan Murdoch wrote:
> On 11-03-24 5:03 AM, Javier López-de-Lacalle wrote:
>> Hi everybody:
>>
>> I need to get the names of the arguments in an object of class "expression".
>> I've got the following expression:
>>
>>> x<- expression(rho * cos(omega))
>>
>> Is there any function or procedure that returns the names of the arguments
>> (in the example: "rho" and "omega")?
>
> That expression also includes * and cos, which are also objects in R. I
> presume you would like to restrict the answer to variables in a
> particular environment, e.g. the global environment, or the caller of
> your function. The tricky bit in implementing this is that R has fairly
> rich scoping rules, so rho and omega need not live in the same
> environment, as long as both are visible where you evaluate that
> expression. So then how do you distinguish which of the 4 objects you
> want back?
>
>>
>> I tried a rough approach implemented in the function expr.args() shown
>> below. As the function eval() needs to get access to those arguments, a
>> possible approach is as follows: 1) apply eval() to the expression "x"
>> within an empty environment; 2) get the variable names from the character
>> string containing the error message that will be returned:
>>
>> "Error in eval(expr, envir, enclos) : object 'rho' not found";
>
> I think it would be better to examine the expression, not evaluate it.
> Some expressions have side effects (e.g. plot(rho), or
> remove(list=ls())), and you may not want those side effects.
>
>>
>> 3) assign a value to the first identified variable, "rho", and apply eval()
>> again until the expression is evaluated and no error returned.
>>
>> There are some pitfalls in this approach, expr.args():
>>
>> i) it is a recursive procedure (I guess there must be a more
>> efficient approach);
>>
>> ii) it does not work if some of the arguments, for instance 'rho',
>> exist in the workspace. Despite a new environment is created to evaluate the
>> expression, objects are also searched in the parent environment. The search
>> should somehow stick to the new environment (called 'tmpe' in expr.args());
>>
>> iii) it does not work if the name of an argument coincides with the
>> name of a function (for instance 'gamma').
>>
>> Is there any function to do this task? If not, I would appreciate some
>> guidance to improve the function expr.args().
>
> The codetools package has functions to do things like this, though they
> are aimed at functions and packages, rather than single expressions. I
> think you want codetools::findGlobals, e.g.
>
> f<- function() {} # a dummy function
> body(f)<- x # containing the expression as its body
> codetools::findGlobals(f)
>
> # prints [1] "*" "cos" "omega" "rho"
>
> Duncan Murdoch
>
>>
>>> expr.args<- function(x)
>> {
>> cond<- is.expression(x)
>> if (cond) {
>> tmpe<- new.env()
>> } else return()
>>
>> while (cond)
>> {
>> ref<- try(eval(x, envir = tmpe), silent = TRUE)
>> if (cond<- (class(ref) == "try-error"))
>> {
>> if (length(grep("not found", ref[1]))> 0)
>> {
>> aux<- substr(ref, regexpr("object ", ref) + 8, regexpr(" not
>> found", ref) - 2)
>> assign(as.character(aux), 1, envir = tmpe)
>> } else stop("expression could no be evaluated but a missing variable
>> was not identified.")
>> }
>> }
>>
>> ls(envir = tmpe)
>> }
>>
>> Many thanks.
>>
>> javi
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> 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.
>
More information about the R-help
mailing list