给定任意固定的表情,我想替换一个符号具有多个值的集合。例子:
Expression | Symbol | Replace with | Desired Output
-----------------------------------------------------------------------------------------
f(x, 5) | x | a = 1, b = sym, c = "char" | f(a = 1, b = sym, c = "char", 5)
g(f(h(y)), z) | y | 1, 2, 3 | g(f(h(1, 2, 3)), z)
g(f(h(y), z), z) | z | 4, x | g(f(h(y), 4, x), 4, x)
该substitute()
功能接近,但它不正是我所期待的。在下面的例子中,我想转成f(x)
f(1, b = 4, c = d)
,但我还没有找到合适的env
说法。
substitute(
expr = f(x),
env = list(x = list(1, b = 4, c = rlang::sym("d")))
)
#> f(list(1, b = 4, c = d))
substitute(
expr = f(x),
env = list(x = as.call(c(quote(x), 1, b = 4, c = quote(d)))[-1])
)
#> f(1(b = 4, c = d))
由reprex package创建于2019年2月9日(v0.2.1)
是否有可能找到一个env
这样substitute(f(x), env)
等于f(1, b = 4, c = d)
?
备注:
f(x)
。我们不能简单地写as.call(c(quote(f), env))
。!!!
所有整齐的评价,我们不能整齐评价使用drake
。这里有一个拼接功能的纺丝
splice <- function(x, replacements) {
if (is(x, "call")) {
as.call(do.call("c",lapply(as.list(x), splice, replacements), quote=T))
} else if (is(x, "name")) {
if (deparse(x) %in% names(replacements)) {
return(replacements[[deparse(x)]])
} else {
list(x)
}
} else {
list(x)
}
}
这似乎与样品的输入工作
splice(quote(f(x, 5) ), list(x=list(a = 1, b = quote(sym), c = "char" )))
# f(a = 1, b = sym, c = "char", 5)
splice(quote(g(f(h(y)), z)) , list(y=list(1,2,3)))
# g(f(h(1, 2, 3)), z)
splice(quote(g(f(h(y), z), z)), list(z=list(4, quote(x))) )
# g(f(h(y), 4, x), 4, x)
基本上你只掉出符号名。它也应该有一个变量替换不在列表中的工作。
splice(quote(f(x,5)), list(x=7))
# f(7, 5)
你基本上需要通过操纵它作为一个列表来重新编写调用。这是tidyverse功能正在做什么幕后。他们拦截当前通话,重新写出来,然后评估新扩展的呼叫。 substitute
行不通,因为你不只是用一个数值代替一个符号。您需要更改的要传递给函数的参数数量。
这个答案是笨重的,但(我认为)它你需要的;它的灵感来自于(且取自同一行)this Stack Overflow answer了几分相关帖子:
multi_substitute <- function(expr, key, ...) {
expr <- deparse(substitute(expr))
key <- deparse(substitute(key))
# The following line is the bit I got from the mentioned SO answer
l <- sapply( substitute(list(...)), deparse)[-1]
l <- paste(names(l), l, sep = " = ")
l <- sub("^ = ", "", l)
l <- paste(l, collapse = ",")
vals <- deparse(substitute(...))
result <- sub(key, l, expr)
return(parse(text = result)[[1]])
}
multi_substitute(f(x), x, 1, b = 4, c = quote(d))
# f(1, b = 4, c = quote(d))
您或许能够得到这一点更优雅或对其进行定制,以更好地满足您的需求。
如果你不希望强制规定的key
说法那里,你当然可以改变的,大约相当容易。