在带有rlang的lazyeval调用中使用二元运算符

Posted

技术标签:

【中文标题】在带有rlang的lazyeval调用中使用二元运算符【英文标题】:Using binary operator in lazyeval call with rlang 【发布时间】:2018-03-06 15:27:00 【问题描述】:

假设我想使用 dplyr 和标准评估将一列的每个值加 1。

我能做到:

library(dplyr)
data <- head(iris)
var <- "Sepal.Length"
mutate(data, !!rlang::sym(var) := !!quo(`+`(!!rlang::sym(var), 1)))

但是如果我想使用+ 作为二元运算符而不是函数呢? 我不知道如何用 quosure 中的符号编写 +。 在我的大多数尝试中,我在尝试将非数字参数(例如符号)与二元运算符 + 一起使用时遇到错误。

使用已弃用的mutate_,您可以使用lazyeval::interp,这让您可以轻松完成:

mutate_(data, .dots = setNames(list(lazyeval::interp(~var + 1, var = as.symbol(var))), var))

任何帮助将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

你可以使用

mutate(data, !!rlang::sym(var) := (!!rlang::sym(var)) + 1)

注意 bang-bang 部分周围的括号。这只是必要的,因为您可能使用的是旧版本的 rlang。在旧版本 (!! 的优先级非常低,因此添加发生在扩展之前。从 rlang 0.2 开始,!! 被赋予了不同的运算符优先级,并且按照您的预期工作。

当然,如果您将相同的转换应用于一堆列,您可能希望使用mutate_atmutate_allmutate_if 版本,这也允许转换特定于公式语法.

mutate_if(data, is.numeric, ~.x+1)
mutate_all(data, ~.x+1)
mutate_at(data, var, ~.x+1)

【讨论】:

谢谢!我不知道包装 !!quo() 没用,实际上我正在使用 rlang v0.1.6

以上是关于在带有rlang的lazyeval调用中使用二元运算符的主要内容,如果未能解决你的问题,请参考以下文章

html Lazyeval严格模式

使用 rlang 的 enexprs 捕获函数

解决载入了名字空间‘rlang’ 0.4.5,但需要的是>= 0.4.6

dplyr,使用带有非标准评估的过滤器

keras中的二元交叉熵和带有logits的二元交叉熵有啥区别?

二元操作中的broadcast操作