问题
Call the function below using foo(c("b"))
. The outputs are shown inline.
What is the right way of writing df %>% filter(!!x > (!!x))
?
I have included an example of using mutate
in tidyeval style to contrast it with filter
.
foo <- function(variables) {
x <- rlang::sym(variables[[1]])
print(x)
#> b
print(typeof(x))
#> [1] "symbol"
df <- data_frame(a = 1, b = 2)
print(df %>% mutate(!!x := 100 + !!x))
#> # A tibble: 1 x 2
#> a b
#> <dbl> <dbl>
#> 1 1 102
print(df %>% filter(!!x > (!!x)))
#> Error in !x : invalid argument type
print(df %>% filter(magrittr::is_greater_than(!!x, !!x)))
#> # A tibble: 0 x 2
#> # ... with 2 variables: a <dbl>, b <dbl>
}
回答1:
You are most of the way there except for a minor typo, the round brackets in your filter statement should be on the variable and not the value.
print(df %>% filter((!!x) > !!x))
#> # A tibble: 0 x 2
#> # ... with 2 variables: a <dbl>, b <dbl>
回答2:
Edit: All of this no longer applies. The precedence tree is reorganised so that !!x + !!y
etc do the right thing by default. The parentheses are no longer necessary since rlang 0.2.0.
The !
operator has really low precedence. This means that it will apply to most of the expression appearing on its right.
!! x > 3
is implicitly equivalent to:
(!! x > 3)
So you have to help R figure out the right precedence with explicit parentheses:
(!! x) > 3
Note that in most cases if you're unquoting on both sides of an operator, you technically don't have to apply the parentheses on the last one:
(!! x) + (!! y) + z
However that will vary according to often mysterious rules of precedence, so I suggest to always enclose in parentheses when operators are involved:
(!! x ) + (!! y) + (!! z)
回答3:
You can use filter_at
oof <- function(variables) {
x <- rlang::sym(variables[[1]])
df <- data.frame(a = 1, b = 2)
print(df %>% filter_at(vars(!!x), any_vars(. == !!x)))
print(df %>% filter(magrittr::equals(!!x, !!x)))
}
I use magrittr::equals
to show the magrittr style works as well
oof(c("b"))
# a b
# 1 1 2
# a b
# 1 1 2
回答4:
This is a very generic way of handling any field value condition
data%>%
filter(!!quo((!!as.name (field1)) > (!!myVal)))
来源:https://stackoverflow.com/questions/46086755/what-is-the-tidyeval-way-of-using-dplyrfilter