You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用dplyr编写函数创建新列:推荐的元编程运算符用法

在dplyr中创建新列:拥抱运算符{{}} vs !!运算符的推荐实践

核心结论

推荐优先使用拥抱运算符{{}},这是tidyverse团队在现代dplyr元编程中主推的简化语法,完全替代了旧版enquo()+!!的组合写法。

两种方式的关键差异

  • {{}}是enquo()(捕获用户输入的表达式)+!!(反引用表达式)的语法糖,自动完成了元编程的核心两步操作,无需手动调用enquo()。
  • 从你的示例代码可以看到,使用{{}}的add_col1支持两种更灵活的调用方式:
    • 带引号的列名字符串:add_col1(cars, "new_col")
    • 裸名(无引号)形式:add_col1(cars, new_col)
      这完全贴合dplyr一贯的用户友好设计,让用户可以按自己的习惯选择调用方式。
  • 而依赖!!的add_col2,如果没有提前用enquo()捕获输入表达式,就无法处理裸名调用,必须强制传入带引号的字符串,灵活性大打折扣——这也是你示例中add_col2(cars, new_col)失败的原因。

!!的适用场景

虽然{{}}是常规场景的首选,但!!并非完全被淘汰:当你需要手动控制引用逻辑时(比如提前捕获表达式并存储到变量中,或者需要动态组合多个复杂表达式),!!依然有用。例如:

add_col3 <- function(data, col_name) {
  # 手动捕获表达式
  col_expr <- enquo(col_name)
  data |> dplyr::mutate(!!col_expr := "new")
}

但这种写法已经被{{}}简化,日常场景下完全没必要多此一举。

总结

  • 编写常规的dplyr风格函数时,优先使用{{}},它更简洁、更符合tidyverse的设计理念,还能兼容多种调用方式。
  • 仅在复杂元编程场景(需要手动管理引用的表达式)时,才考虑结合enquo()和!!。

内容的提问来源于stack exchange,提问作者MoltenLight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 10:03:29