在 `dplyr` 动词中使用不带引号的字符串:`select` 和 `arrange` 的工作方式不同
Using unquoted strings in with `dplyr` verbs: `select` and `arrange` working differently
我正在尝试取消引用一个字符串以供在 dplyr::arrange
中使用。它似乎不起作用。但是,它似乎在 dplyr::select
中可以正常工作。
我是不是遗漏了什么或做错了什么?
library(tidyverse)
df <- tibble(x = c(1, 2, 3),
y = c(8, 6, 3))
v <- 'y'
# `select` works with `!!v`
df %>% select(y)
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
df %>% select(!!v)
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
# `arrange` not work with `!!v`
df %>% arrange(y)
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
df %>% arrange(!!v)
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 1 8
#> 2 2 6
#> 3 3 3
您需要先将字符串转换为变量(使用 sym()
),然后在 arrange()
.
中取消引用
df %>% arrange(!!sym(v))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
select()
可以直接接受字符串输入,但不推荐
df %>% select(v)
#> Note: Using an external vector in selections is ambiguous.
#> i Use `all_of(v)` instead of `v` to silence this message.
#> i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
#> This message is displayed once per session.
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
由 reprex package (v0.3.0)
于 2020-11-21 创建
在 selecting 动词中,使用 all_of()
或 any_of()
。如果不是所有变量都存在于数据框中,前者会导致错误,后者是宽松的(并且通常对 deselecting 更有用)
df %>% select(all_of(v))
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
在动作动词中,例如 arrange()
或 mutate()
,select 单个变量通过子代化 .data
代词:
df %>% arrange(.data[[v]])
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
您还可以通过使用 across()
:
在动作动词中使用 selection
df %>% arrange(across(starts_with("y")))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
这意味着您也可以使用 all_of()
以及来自字符向量的 select:
df %>% arrange(across(all_of(v)))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
我正在尝试取消引用一个字符串以供在 dplyr::arrange
中使用。它似乎不起作用。但是,它似乎在 dplyr::select
中可以正常工作。
我是不是遗漏了什么或做错了什么?
library(tidyverse)
df <- tibble(x = c(1, 2, 3),
y = c(8, 6, 3))
v <- 'y'
# `select` works with `!!v`
df %>% select(y)
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
df %>% select(!!v)
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
# `arrange` not work with `!!v`
df %>% arrange(y)
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
df %>% arrange(!!v)
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 1 8
#> 2 2 6
#> 3 3 3
您需要先将字符串转换为变量(使用 sym()
),然后在 arrange()
.
df %>% arrange(!!sym(v))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
select()
可以直接接受字符串输入,但不推荐
df %>% select(v)
#> Note: Using an external vector in selections is ambiguous.
#> i Use `all_of(v)` instead of `v` to silence this message.
#> i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
#> This message is displayed once per session.
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
由 reprex package (v0.3.0)
于 2020-11-21 创建在 selecting 动词中,使用 all_of()
或 any_of()
。如果不是所有变量都存在于数据框中,前者会导致错误,后者是宽松的(并且通常对 deselecting 更有用)
df %>% select(all_of(v))
#> # A tibble: 3 x 1
#> y
#> <dbl>
#> 1 8
#> 2 6
#> 3 3
在动作动词中,例如 arrange()
或 mutate()
,select 单个变量通过子代化 .data
代词:
df %>% arrange(.data[[v]])
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
您还可以通过使用 across()
:
df %>% arrange(across(starts_with("y")))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8
这意味着您也可以使用 all_of()
以及来自字符向量的 select:
df %>% arrange(across(all_of(v)))
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 3
#> 2 2 6
#> 3 1 8