使用 dplyr::filter 的正确方法是什么?
What is the tidyeval way of using dplyr::filter?
使用foo(c("b"))
调用下面的函数。输出以内联方式显示。
正确的写法是什么df %>% filter(!!x > (!!x))
?
我提供了一个使用 mutate
风格的例子,以将其与 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>
}
您可以使用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)))
}
我用 magrittr::equals
来证明 magrittr 风格也能正常工作
oof(c("b"))
# a b
# 1 1 2
# a b
# 1 1 2
除了一个小的拼写错误外,您已经完成了大部分工作,过滤语句中的圆括号应该在变量上而不是值上。
print(df %>% filter((!!x) > !!x))
#> # A tibble: 0 x 2
#> # ... with 2 variables: a <dbl>, b <dbl>
编辑:所有这些都不再适用。优先级树被重新组织,以便 !!x + !!y
等默认情况下做正确的事情。自 rlang 0.2.0.
起不再需要括号
!
运算符的优先级非常低。这意味着它将应用于出现在其右侧的大部分表达式。
!! x > 3
隐式等同于:
(!! x > 3)
所以你必须帮助 R 找出带有显式括号的正确优先级:
(!! x) > 3
请注意,在大多数情况下,如果您在运算符的两边都取消引用,从技术上讲,您不必在最后一个上应用括号:
(!! x) + (!! y) + z
然而,这会根据通常神秘的优先规则而有所不同,所以我建议在涉及运算符时始终用括号括起来:
(!! x ) + (!! y) + (!! z)
这是处理任何字段值条件的一种非常通用的方法
data%>%
filter(!!quo((!!as.name (field1)) > (!!myVal)))
使用foo(c("b"))
调用下面的函数。输出以内联方式显示。
正确的写法是什么df %>% filter(!!x > (!!x))
?
我提供了一个使用 mutate
风格的例子,以将其与 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>
}
您可以使用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)))
}
我用 magrittr::equals
来证明 magrittr 风格也能正常工作
oof(c("b"))
# a b
# 1 1 2
# a b
# 1 1 2
除了一个小的拼写错误外,您已经完成了大部分工作,过滤语句中的圆括号应该在变量上而不是值上。
print(df %>% filter((!!x) > !!x))
#> # A tibble: 0 x 2
#> # ... with 2 variables: a <dbl>, b <dbl>
编辑:所有这些都不再适用。优先级树被重新组织,以便 !!x + !!y
等默认情况下做正确的事情。自 rlang 0.2.0.
!
运算符的优先级非常低。这意味着它将应用于出现在其右侧的大部分表达式。
!! x > 3
隐式等同于:
(!! x > 3)
所以你必须帮助 R 找出带有显式括号的正确优先级:
(!! x) > 3
请注意,在大多数情况下,如果您在运算符的两边都取消引用,从技术上讲,您不必在最后一个上应用括号:
(!! x) + (!! y) + z
然而,这会根据通常神秘的优先规则而有所不同,所以我建议在涉及运算符时始终用括号括起来:
(!! x ) + (!! y) + (!! z)
这是处理任何字段值条件的一种非常通用的方法
data%>%
filter(!!quo((!!as.name (field1)) > (!!myVal)))