dplyr arrange() 在 c() 内部使用单个变量,但在函数内部评估时不适用于 c() 内部的多个变量
dplyr arrange() works with single variable inside c(), but not multiple variables inside of c() when evaluated inside of a function
我在网上可以找到的关于 tidyeval 的所有信息要么较旧,要么不是最新版本 tidyverse\dplyr 的最新版本,要么不太适用。
一个例子是:
df <- tribble(
~var1, ~var2, ~var3,
1, 2, 3,
4, 5, 6,
7, 8, 9
)
我写了一个小函数:
fun <- function(data, select_var, arrange_var) {
select_var <- enquo(select_var)
arrange_var <- enquo(arrange_var)
data %>%
select(!!select_var) %>%
arrange(!!arrange_var)
}
该函数只是选择列,然后按行排列。
当我将参数传递给函数时,它可以很好地处理 c() 中的单个变量:
fun(df,
c(var1,
var2)),
c(var2))
但是,当我尝试将两个变量传递给它时:
fun(df,
c(var1,
var2)),
c(var1,
var2))
我收到以下错误:
Error: incorrect size (282) at position 1, expecting : 141
我能找到的最接近的堆栈响应是:
和
Pass a vector of variable names to arrange() in dplyr
但这两个似乎都给出了包含已弃用解决方案的答案(例如,arrange_())
这里有一些重要信息:
tidyeval resource roundup 作者:玛拉·埃弗里克
和
Separating and Trimming Messy Data the Tidy Way 作者:保罗·奥尔德姆
当然我已经深入研究:tidyeval
然而 none 他们似乎解决了这个问题。花了一个下午后,我已经用尽了我的资源。该代码可以在标准 R 文件中找到,只是无法让它在函数内部工作,但准备放弃,所以我想看看你们这些好心人是否可以提供帮助。提前致谢。
更新 2022/03/17
tidyverse 已经发展,这个答案也应该如此。
不需要enquo
了!相反,我们将 tidy-select 表达式括在双大括号 {{ }}
.
中
library("tidyverse")
df <- tribble(
~var1, ~var2, ~var3,
1, 2, 3,
4, 5, 6,
7, 8, 9
)
fun <- function(data, select_vars, ...) {
data %>%
select(
{{ select_vars }}
) %>%
arrange(
...
)
}
fun(df, c(var1, var2), desc(var2))
#> # A tibble: 3 × 2
#> var1 var2
#> <dbl> <dbl>
#> 1 7 8
#> 2 4 5
#> 3 1 2
fun(df, c(var1, var2), var1, var2)
#> # A tibble: 3 × 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
我们仍然不能将 c()
与 arrange
和 filter
动词一起使用,因为 data-masking.
不允许这样做
df %>%
arrange(
c(var1, var2)
)
#> Error in `arrange()`:
#> ! Problem with the implicit `transmute()` step.
#> x Problem while computing `..1 = c(var1, var2)`.
#> x `..1` must be size 3 or 1, not 6.
由 reprex package (v2.0.1)
于 2022-03-17 创建
旧答案
将 arrange_var
替换为 ...
并指定变量而不将它们包含在 c()
中使其工作。
library("dplyr")
df <- tribble(
~var1, ~var2, ~var3,
1, 2, 3,
4, 5, 6,
7, 8, 9
)
fun <- function(data, select_var, ...) {
select_var <- enquo(select_var)
data %>%
select(!!select_var) %>%
# You can pass the dots to `arrange` directly
arrange(...)
}
fun(df, c(var1, var2), var2)
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
fun(df, c(var1, var2), var1, var2)
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
由 reprex package (v0.2.1)
于 2019-03-08 创建
原来只有select
支持字符串和字符向量。正如文档所说,“这与其他字符串不明确的动词不同。” 请参阅 dplyr::select
的最后一个示例。
# Two alternatives; both work with `select`.
df %>%
select(var1, var2)
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
df %>%
select(c(var1, var2))
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
# `arrange` only works with lists on comma separated unquoted variable names.
df %>%
arrange(var1, var2)
#> # A tibble: 3 x 3
#> var1 var2 var3
#> <dbl> <dbl> <dbl>
#> 1 1 2 3
#> 2 4 5 6
#> 3 7 8 9
df %>%
arrange(c(var, var2))
#> Error: incorrect size (4) at position 1, expecting : 3
由 reprex package (v0.2.1)
于 2019-03-08 创建
我在网上可以找到的关于 tidyeval 的所有信息要么较旧,要么不是最新版本 tidyverse\dplyr 的最新版本,要么不太适用。
一个例子是:
df <- tribble(
~var1, ~var2, ~var3,
1, 2, 3,
4, 5, 6,
7, 8, 9
)
我写了一个小函数:
fun <- function(data, select_var, arrange_var) {
select_var <- enquo(select_var)
arrange_var <- enquo(arrange_var)
data %>%
select(!!select_var) %>%
arrange(!!arrange_var)
}
该函数只是选择列,然后按行排列。
当我将参数传递给函数时,它可以很好地处理 c() 中的单个变量:
fun(df,
c(var1,
var2)),
c(var2))
但是,当我尝试将两个变量传递给它时:
fun(df,
c(var1,
var2)),
c(var1,
var2))
我收到以下错误:
Error: incorrect size (282) at position 1, expecting : 141
我能找到的最接近的堆栈响应是:
但这两个似乎都给出了包含已弃用解决方案的答案(例如,arrange_())
这里有一些重要信息: tidyeval resource roundup 作者:玛拉·埃弗里克
和 Separating and Trimming Messy Data the Tidy Way 作者:保罗·奥尔德姆
当然我已经深入研究:tidyeval
然而 none 他们似乎解决了这个问题。花了一个下午后,我已经用尽了我的资源。该代码可以在标准 R 文件中找到,只是无法让它在函数内部工作,但准备放弃,所以我想看看你们这些好心人是否可以提供帮助。提前致谢。
更新 2022/03/17
tidyverse 已经发展,这个答案也应该如此。
不需要enquo
了!相反,我们将 tidy-select 表达式括在双大括号 {{ }}
.
library("tidyverse")
df <- tribble(
~var1, ~var2, ~var3,
1, 2, 3,
4, 5, 6,
7, 8, 9
)
fun <- function(data, select_vars, ...) {
data %>%
select(
{{ select_vars }}
) %>%
arrange(
...
)
}
fun(df, c(var1, var2), desc(var2))
#> # A tibble: 3 × 2
#> var1 var2
#> <dbl> <dbl>
#> 1 7 8
#> 2 4 5
#> 3 1 2
fun(df, c(var1, var2), var1, var2)
#> # A tibble: 3 × 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
我们仍然不能将 c()
与 arrange
和 filter
动词一起使用,因为 data-masking.
df %>%
arrange(
c(var1, var2)
)
#> Error in `arrange()`:
#> ! Problem with the implicit `transmute()` step.
#> x Problem while computing `..1 = c(var1, var2)`.
#> x `..1` must be size 3 or 1, not 6.
由 reprex package (v2.0.1)
于 2022-03-17 创建旧答案
将 arrange_var
替换为 ...
并指定变量而不将它们包含在 c()
中使其工作。
library("dplyr")
df <- tribble(
~var1, ~var2, ~var3,
1, 2, 3,
4, 5, 6,
7, 8, 9
)
fun <- function(data, select_var, ...) {
select_var <- enquo(select_var)
data %>%
select(!!select_var) %>%
# You can pass the dots to `arrange` directly
arrange(...)
}
fun(df, c(var1, var2), var2)
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
fun(df, c(var1, var2), var1, var2)
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
由 reprex package (v0.2.1)
于 2019-03-08 创建原来只有select
支持字符串和字符向量。正如文档所说,“这与其他字符串不明确的动词不同。” 请参阅 dplyr::select
的最后一个示例。
# Two alternatives; both work with `select`.
df %>%
select(var1, var2)
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
df %>%
select(c(var1, var2))
#> # A tibble: 3 x 2
#> var1 var2
#> <dbl> <dbl>
#> 1 1 2
#> 2 4 5
#> 3 7 8
# `arrange` only works with lists on comma separated unquoted variable names.
df %>%
arrange(var1, var2)
#> # A tibble: 3 x 3
#> var1 var2 var3
#> <dbl> <dbl> <dbl>
#> 1 1 2 3
#> 2 4 5 6
#> 3 7 8 9
df %>%
arrange(c(var, var2))
#> Error: incorrect size (4) at position 1, expecting : 3
由 reprex package (v0.2.1)
于 2019-03-08 创建