R bquote的反向行为 [英] R reverse behaviour of bquote
问题描述
bquote
函数允许计算表达式的部分,这些部分包装在.()
调用中.例如
bquote
function allows to evaluate parts of the expression which are wrapped in .()
call. For example,
a <- 2
b <- 100
bquote(.(2 * a) * x + .(log10(b)))
会返回
4 * x + 2
我想重写此函数以评估除.()
调用内的内容以外的所有内容.这是所需的行为:
I want to rewrite this function to evaluate everything except for things inside .()
call. This is the desired behavior:
a <- 2
b <- 100
bquote(2 * a * .(x) + log10(b))
> 4 * x + 2
我知道要这样做,我必须仔细阅读提取语法树,并在未调用.()
的情况下评估早午餐,但我无法处理所有此类递归.
I understand that to do so I have to go over the abstract syntax tree and evaluate brunches without .()
call in them but I couldn't handle all this recursion.
您能帮我编写这样的功能吗?
Could you help me to write such a function?
推荐答案
subst
将替换.(...)中的所有变量,而simplify
函数将简化没有变量的子树-如果不需要简化,则省略简化部分.不使用任何软件包.
subst
will substitute all variables except those within .(...) and the simplify
function will simplify sub-trees that have no variables -- omit the simplify part if simplification is not needed. No packages are used.
subst <- function(e) {
if (typeof(e) == "language") {
if (identical(e[[1]], as.name("."))) e[[2]]
else {
if (length(e) > 1) e[-1] <- lapply(as.list(e[-1]), subst)
e
}
} else {
eval(e)
}
}
simplify <- function(e) {
if (typeof(e) == "language") {
if (length(all.vars(e))) {
if (length(e) > 1) {
e[-1] <- lapply(as.list(e[-1]), simplify)
e
} else e
} else eval(e)
} else e
}
inverse_bquote <- function(x, SIMPLIFY = TRUE) {
result <- subst(substitute(x))
if (SIMPLIFY) simplify(result) else result
}
现在进行测试.
a <- 2
b <- 100
inverse_bquote(2 * a * .(x) + log10(b))
## 4 * x + 2
# without simplification
inverse_bquote(2 * a * .(x) + log10(b), SIMPLIFY = FALSE)
## 2 * 2 * x + log10(100)
更新:添加了简化功能.使其成为可选.
Update: Added simplification. Made it optional.
这篇关于R bquote的反向行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!