Получение дерева разбора для предопределенной функции в R
Мне кажется, что это довольно простой вопрос, но я не могу понять его.
Если я определю функцию в R, как позже использовать имя функции, чтобы получить ее дерево разбора. Я не могу просто использовать substitute
так как это просто вернет дерево разбора его аргумента, в этом случае просто имя функции.
Например,
> f <- function(x){ x^2 }
> substitute(f)
f
Как мне получить доступ к дереву разбора функции, используя ее имя? Например, как бы я получить значение substitute(function(x){ x^2 })
без явного выписывания всей функции?
3 ответа
Я не совсем уверен, что из этого отвечает вашим желаниям:
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 }
Печатное представление может не отображать все возможности возвращаемых значений.
class(substitute(function(x){ x^2 }) )
#[1] "call"
class( eval(f) )
#[1] "function"
Функция substitute
может подставить в значения, связанные с окружающей средой. Странно то, что его env
Аргумент не имеет значения по умолчанию, но по умолчанию он соответствует среде оценки. Такое поведение вызывает сбой, когда среда оценки является глобальной, но в остальном работает нормально.
Вот пример:
> 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
Как показано, при использовании глобальной среды в качестве второго аргумента функциональность не срабатывает.
Еще одна демонстрация, что она работает правильно, используя a
но не глобальная среда:
> evalq(substitute(f), a)
function(x){x^2}
> evalq(substitute(f), environment())
f
Довольно загадочно.
По-видимому, это действительно странная причуда substitute
и упоминается здесь:
/ * do_substitute имеет два аргумента: выражение и окружение (необязательно). Символы, найденные в выражении, заменяются их значениями, найденными в среде. Наследования нет, поэтому выполняется поиск только в предоставленной среде. Если среда не указана, используется среда, в которой был вызван заменитель. Если указанной средой является R_GlobalEnv, она преобразуется в R_NilValue по историческим причинам. В substitute() R_NilValue сигнализирует о том, что подстановка не должна производиться, только извлечение выражений обещаний. Аргументы do_substitute не должны оцениваться. */
И вы уже нашли способ обойти это:
e = new.env()
e$fn = f
substitute(fn, e)