What is the tidyeval way of using dplyr :: filter?

Call the function below using foo(c("b")). The outputs are displayed in a line.

What is the correct way to record df %>% filter(!!x > (!!x))?

I included a mutatetidyeval-style usage example to compare 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>

}
+3
source share
4 answers

You are most there, with the exception of a small typo, the parentheses in your filter statement should be in a variable, not a value.

print(df %>% filter((!!x) > !!x))

#> # A tibble: 0 x 2
#> # ... with 2 variables: a <dbl>, b <dbl>
+2
source

The operator !has a very low priority. This means that this applies to most of the expression appearing on the right.

!! x > 3

implicitly equivalent to:

(!! x > 3)

So you need to help R determine the correct priority with explicit parentheses:

(!! x) > 3

, , , :

(!! x) + (!! y) + z

, , :

(!! x ) + (!! y) + (!! z)
+2

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::equalsto show how magrittr style works

oof(c("b"))

#   a b
# 1 1 2
#   a b
# 1 1 2
0
source

This is a very general way of handling any value of a field value.

data%>%
    filter(!!quo((!!as.name (field1)) > (!!myVal)))
0
source

Source: https://habr.com/ru/post/1695544/


All Articles