LTkongjianyang
!!
会用在自定义函数中处理传入参数的时候,会配合enquo
、sym
、data_sim
啥的函数,而且一般不会显式使用了。你再检查一下你的例子代码的结果,两者运行出来是不一样的:
filter(!!var_name > 1
实际会变成filter("x" > 1)
(好吧这里我也不是很确定),是一个字符串在和1比大小,得到的是一个一维的TRUE
,然后这个判断结果经过循环,于是把整个df的所有行都取出来了。所以其实应该
var_name <- sym("x")
df %>%
filter(!!var_name > 1)
filter(get(var_name) > 1
会取到数据框中的x
列,经过判断后只有2、3行才会被取出来。
get
是来自于base R的函数,并不是tidyverse系列的。它的第二个参数pos
可以指定到底从哪里开始搜索对应变量的值。所以如果你当前的环境里已经有一个x
,而你想以这个x
来进行判断的话,那么可以
df <- data.frame(x = 1:3, y = 4:6)
x <- -(1 : 3)
var_name <- "x"
# get的默认位置是-1
df %>%
filter(get(var_name, pos = -1) > 1)
# 从 pos = 1 开始进行get,这样会搜索到当前环境中的`x = c(-1, -2, -3)`
df %>%
filter(get(var_name, pos = 1) > 1)
像这个例子里,第一个做法会得到2行,第二个做法则得到0行。而如果想采用tidyeval系列的做法,则是像 tctcab 提及的.data
和.env
df %>%
filter(.data[[var_name]] > 1)
df %>%
filter(.env[[var_name]] > 1)
关于这个消除歧义的话题,可以参考The data mask ambiguity