r - 在函数中生成表达式并在 R 中返回
问题描述
我试图在一个单独的函数中生成一个表达式。防止重复代码。然后将表达式传递到 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()
第三个示例给出以下错误: *Error in x * 2 : non-numeric argument to binary operator*
这意味着不评估提供给函数的“x”。x 包含一个列名的字符串。表达式应该是:displ * 2
有趣的是,在函数中访问 varName 一次后,第 4 个示例也可以工作。请注意,从未使用过a 。
我不明白为什么会这样。对我来说,这看起来像是一个肮脏的黑客,但它可能与范围界定有关。有没有更清洁的方法来做到这一点?
解决方案
如果要将包含名称的变量作为字符值传递,则要使用sym
而不是ensym
. sym
将评估要传递给它的参数以获取值。ensym
仅用于在函数中捕获传递给函数的表达式。请注意,此魔法仅在参数仍处于“承诺”状态并且尚未由函数中的任何先前代码评估时才有效。这就是第 4 个示例“有效”的原因,因为额外的代码会强制对 promise 进行评估。
推荐阅读
- python - 当我将鼠标悬停在 Windows 系统或程序中的图标上时如何提取数据?
- python - 使用 Python 自动登录时 Cloudflare 出错
- vba - 将发件人更改为使用代表发送
- android - 现代 Android 小部件开发
- node.js - Sinon.restore 不适用于存根和测试 AWS 功能
- flutter - 如何在下一页上滑动图像 Like Mob Gallery
- sql-server - 在处理 SQL 中的 Count 和 Case 时,你能有一个最终的 ELSE 吗?
- php - 根据数据输出改变字体颜色
- r - 如何重新排列/整理 R 数据框中的列?
- matlab - Matlab:如何限制对抽象类方法的子类的访问