在函数中生成表达式并在R中返回

在函数中生成表达式并在R中返回,r,expression,R,Expression,我试图在一个单独的函数中生成一个表达式。防止重复代码。然后将表达式传递到ggplot 这个表达式很简单 ggplot(mpg, aes(x = model, y = displ)) + geom_boxplot() 这也适用于带有公式和字符串的表达式 x = "displ" xVar = expr(!!ensym(x) * 2) ggplot(mpg, aes(x = model, y = !!xVar)) + geom_boxplot() 这对公式中生成的表达式不起作用 makeExpre

我试图在一个单独的函数中生成一个表达式。防止重复代码。然后将表达式传递到ggplot

这个表达式很简单

ggplot(mpg, aes(x = model, y = displ)) + geom_boxplot()
这也适用于带有公式和字符串的表达式

x = "displ"
xVar = expr(!!ensym(x) * 2)
ggplot(mpg, aes(x = model, y = !!xVar)) + geom_boxplot()
这对公式中生成的表达式不起作用

makeExpression = function(varName){
    return(expr(!!ensym(varName) * 2))
}
xVar = makeExpression(x)
ggplot(mpg, aes(x = model, y = !!xVar)) + geom_boxplot()
这适用于在公式中生成的表达式

makeExpression = function(varName){
    a = varName
    return(expr(!!ensym(varName) * 2))
}
xVar = makeExpression(x)
ggplot(mpg, aes(x = model, y = !!xVar)) + geom_boxplot()
第三个示例给出了以下错误: *x*2中出错:二进制运算符的非数值参数*

这意味着不计算提供给函数的x。x包含一个列名字符串。表达式应该是:displ*2

有趣的是,第四个示例在函数中访问varName一次后也可以工作。请注意,从不使用


我不明白为什么会这样。对我来说,这看起来像一个肮脏的黑客,但它可能和范围界定有关。有没有更干净的方法可以做到这一点?

如果要将包含名称的变量作为字符值传递,则需要使用sym而不是ensym。sym将计算要传递给它的参数以获得值。ensym仅用于函数中捕获传递给函数的表达式。请注意,只有当参数仍处于承诺状态且未被函数中以前的任何代码求值时,此魔术才起作用。这就是第四个示例之所以有效的原因,因为额外的代码迫使您对承诺进行评估。

如果您包含一个简单的示例输入和所需的输出,可以用来测试和验证可能的解决方案,那么就更容易为您提供帮助。也许可以简化函数以隔离您正试图解决的确切问题。目前还不清楚您到底在向这些函数传递什么,或者您可能正在使用哪些包来定义这些函数。@MrFlick您完全正确。我做了一个简单的工作示例并编辑了我的原始问题。我不确定你的问题是什么。如果要将需要计算的字符值传递给函数,请使用sym而不是ensym。后者是为传递一个不带引号的符号而设计的。这就解决了这个问题。显然,我以前没有使用sym和ensym。有了sym,它就工作了。有趣的是,对于ensym来说,这种行为仍然很奇怪。此外,我所有的代码都使用了ensym,直到我在函数中尝试了它。ensym实际上只用于函数中。但与其他en函数不同,它有一个接受字符值的回退,这可能会导致更多的混乱,而不是在这种情况下的帮助。