给出一个任意的固定表达式,我想用多个值的集合代替单个符号。例子:
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(v0.2.1)于2019-02-09创建
是否可以找到一个env
等于substitute(f(x), env)
的{{1}}?
备注:
f(1, b = 4, c = d)
开始很重要。我们不能简单地写f(x)
。as.call(c(quote(f), env))
,因为drake
中的所有整洁评估都需要单独处理。答案 0 :(得分:1)
这是一个拼接功能
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
永远不会起作用,因为您不只是将一个符号替换为一个值。您需要更改传递给函数的参数数量。
答案 1 :(得分:0)
这个答案很笨拙,但是(我认为)它可以满足您的需求;它是受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
参数,那么您当然可以很容易地更改它。