Getting the parse tree for a predefined function in R

旧时模样 提交于 2020-01-01 05:56:09

问题


I feel as if this is a fairly basic question, but I can't figure it out.

If I define a function in R, how do I later use the name of the function to get its parse tree. I can't just use substitute as that will just return the parse tree of its argument, in this case just the function name.

For example,

> f <- function(x){ x^2 }
> substitute(f)
f

How should I access the parse tree of the function using its name? For example, how would I get the value of substitute(function(x){ x^2 }) without explicitly writing out the whole function?


回答1:


I'm not exactly sure which of these meets your desires:

 eval(f)
#function(x){ x^2 }

 identical(eval(f), get("f"))
#[1] TRUE
 identical(eval(f), substitute( function(x){ x^2 })  )
#[1] FALSE

 deparse(f)
#[1] "function (x) " "{"             "    x^2"       "}"            

 body(f)
#------
{
    x^2
}
#---------

eval(parse(text=deparse(f)))
#---------
function (x) 
{
    x^2
}
#-----------

 parse(text=deparse(f))
#--------
expression(function (x) 
{
    x^2
})
#--------

 get("f")
# function(x){ x^2 }

The print representation may not display the full features of the values returned.

 class(substitute(function(x){ x^2 }) )
#[1] "call"
 class( eval(f) ) 
#[1] "function"



回答2:


The function substitute can substitute in values bound to an environment. The odd thing is that its env argument does not possess a default value, but it defaults to the evaluation environment. This behavior seems to make it fail when the evaluation environment is the global environment, but works fine otherwise.

Here is an example:

> a = new.env()
> a$f = function(x){x^2}
> substitute(f, a)
function(x){x^2}
> f = function(x){x^2}
> environment()
<environment: R_GlobalEnv>
> substitute(f, environment())
f
> substitute(f, globalenv())
f

As demonstrated, when using the global environment as the second argument the functionality fails.

A further demosntration that it works correctly using a but not the global environment:

> evalq(substitute(f), a)
function(x){x^2}
> evalq(substitute(f), environment())
f

Quite puzzling.




回答3:


Apparently that's indeed some weird quirk of substitute and is mentioned here:

/* do_substitute has two arguments, an expression and an environment (optional). Symbols found in the expression are substituted with their values as found in the environment. There is no inheritance so only the supplied environment is searched. If no environment is specified the environment in which substitute was called is used. If the specified environment is R_GlobalEnv it is converted to R_NilValue, for historical reasons. In substitute(), R_NilValue signals that no substitution should be done, only extraction of promise expressions. Arguments to do_substitute should not be evaluated. */

And you have already found a way of circumventing it:

e = new.env()
e$fn = f
substitute(fn, e)


来源:https://stackoverflow.com/questions/17054464/getting-the-parse-tree-for-a-predefined-function-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!