使用substitute()函数替换标签/参数名称。

4

我有以下代码:

eval(substitute(list(x = y), list(x = "foo", y = "bar")))

这将返回list(x = "bar"),即仅替换了值而未替换标签。

我该如何让substitute()也替换标签,以便结果为list(foo = "bar")

2个回答

4

x被绑定到一个名称上。我们可以通过以下方式查看:

as.list(substitute(list(x = y)))
# [[1]]
# list
#
# $x
# y

因此,在substitute调用中更改名称并不是非常容易。但是您可以这样做:

e <- substitute(list(x = y), list(y = "bar"))
names(e)[2] <- "foo"
eval(e)
# $foo
# [1] "bar"

或者仅使用substitute,您可以更改表达式以使用setNames

e <- substitute(setNames(list(y), x), list(x = "foo", y = "bar"))
eval(e)
# $foo
# [1] "bar"

但你也可以使用更加简单的call方法

cl <- call("list", foo = "bar")
eval(cl)
# $foo
# [1] "bar"

感谢你的答案并指出了各种方法。不幸的是,它们都不能让我完全满意。我更希望找到一种通用的解决方案,适用于其他表达式(而不仅仅是列表)。此外,x的值是一个字符串,这就是为什么使用call()无法工作的原因,因为它预设了应该是整个事物的结果的参数列表构造。我有印象类似于例子#2和#3的双步骤方法是首选方法。我希望有一个使用substitute()和相关函数的一站式解决方案。 - lith
@lith - 中间的 setNames 代码对你无效吗? - Rich Scriven
嗯,我开始喜欢setNames()了,因为它可以与do.call()结合使用来解决原始问题。谢谢。 - lith

0
我想出了这个怪物:
eval(parse(text=eval(substitute(paste0("list(",x," = \"",y,"\")"),list(x="foo",y="bar")))))

谢谢你的“怪物”。:-) 我想避免字符串篡改。 - lith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接