gpt4 book ai didi

R - 如何从表达式中提取对象名称

转载 作者:行者123 更新时间:2023-12-03 08:36:34 27 4
gpt4 key购买 nike

给定一个 rlang 表达式:

expr1 <- rlang::expr({
d <- a + b
})

如何检索表达式中引用的对象的名称?

> extractObjects(expr1)
[1] "d" "a" "b"

更好的是,如何检索对象名称并按“必需”(输入)和“创建”(输出)对它们进行分类?

> extractObjects(expr1)
$created
[1] "d"

$required
[1] "a" "b"

最佳答案

基本函数all.vars这样做:

〉all.vars(expr1)
[1] "d" "a" "b"

或者,您可以使用all.names获取表达式中的所有名称,而不仅仅是那些不用作调用或运算符的名称:

〉all.names(expr1)
[1] "{" "<-" "d" "+" "a" "b"

不要被误导:这个结果是正确的! 所有这些都出现在表达式中,而不仅仅是 a , bd .

但这可能不是你想要的。

事实上,我假设您想要的内容对应于抽象语法树 (AST) 中的叶标记 - 换句话说,除了函数调用(以及运算符,它们也是函数调用)之外的所有内容。

表达式的语法树如下所示:1

   {
|
<-
/\
d +
/ \
a b

获取此信息意味着遍历 AST:

leaf_nodes = function (expr) {
if(is.call(expr)) {
unlist(lapply(as.list(expr)[-1L], leaf_nodes))
} else {
as.character(expr)
}
}
〉leaf_nodes(expr1)
[1] "d" "a" "b"

借助 AST 表示,我们还可以找到输入和输出:

is_assignment = function (expr) {
is.call(expr) && as.character(expr[[1L]]) %in% c('=', '<-', '<<-', 'assign')
}

vars_in_assign = function (expr) {
if (is.call(expr) && identical(expr[[1L]], quote(`{`))) {
vars_in_assign(expr[[2L]])
} else if (is_assignment(expr)) {
list(created = all.vars(expr[[2L]]), required = all.vars(expr[[3L]]))
} else {
stop('Expression is not an assignment')
}
}
 〉vars_in_assign(expr1)
$created
[1] "d"

$required
[1] "a" "b"

请注意,此函数不能很好地处理复杂的赋值(即 d[x] <- a + bf(d) <- a + b 之类的东西。


1 lobstr::ast以不同的方式显示语法树,即为

<sub>█─`{`
└─█─`<-`
├─d
└─█─`+`
├─a
└─b</sub>

...但是上面的表示在 R 之外更常规,我觉得它更直观。

关于R - 如何从表达式中提取对象名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63727729/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com