R语言中bang bang运算符(!!)的作用是什么?
!!运算符在R tidyverse中的作用说明
你给出的示例代码如下:
df %>% {if (stringr::str_length("column")>0) dplyr::filter(., !!rlang::parse_expr(expr)) else .}
核心作用
!!是R tidyverse生态下**准引用(Quasiquotation)**机制的核心运算符,作用是立即对其后跟随的表达式完成求值,再将求值结果传入使用非标准评估(NSE)的tidyverse类函数中。
结合示例代码的拆解解释
tidyverse的核心函数(比如示例中的dplyr::filter)默认采用非标准评估逻辑:函数会直接读取你写的参数内容,匹配当前操作数据框的列名,不会先对参数做常规的代码求值。
如果你的筛选条件没有直接写在filter参数里,而是提前存在了其他变量(示例中的expr变量)中,就需要用!!做强制求值:
- 示例中
rlang::parse_expr(expr)的作用是把存在expr变量里的字符串格式筛选条件,转换为R可识别的表达式对象,比如expr存的是"score > 60",这个函数就会输出score > 60的表达式 - 如果不加
!!,dplyr::filter会尝试在df中找名为rlang::parse_expr(expr)的列,完全无法识别你要的筛选逻辑 - 加上
!!后,R会先把!!后面的表达式算完得到真实的筛选条件,再传给filter执行筛选,就能得到预期结果
简单验证示例
你可以用mtcars内置数据集跑下面两段代码对比效果:
- 直接传字符串参数,报错:
library(dplyr) filter_str <- "cyl > 6" filter(mtcars, filter_str)
- 加
!!转换,正常输出筛选结果:
library(dplyr) library(rlang) filter_str <- "cyl > 6" filter(mtcars, !!parse_expr(filter_str))
内容的提问来源于stack exchange,提问作者sainiamaan
相关产品推荐
相关产品推荐

