整洁的评估:向函数添加一个参数以防止收集
Tidy evaluation: Adding an argument to a function that prevents gathering
我正在尝试构建一个收集(pivot_longer)数据的函数。
在大多数情况下,该函数应该收集所提供数据中除一列之外的所有列,但是应该允许用户在所提供数据中指定不应收集的其他列。这是用户很少会做的事情,因此参数应该默认为没有额外的列。
我认为我的函数失败了,因为它默认为 NULL
。
数据:
library(tidyverse)
sample_data <- tibble(
frame = rep(seq(1:20), 2),
ID = rep(c(1,2), each = 20),
a = rnorm(n = 40),
b = rnorm(n = 40),
c = rnorm(n = 40))
函数:
a_gather_function <- function(.data, also_dont_gather = NULL) {
.data %>%
tidyr::gather(key, value, -frame, -{{also_dont_gather}})
}
如果我为参数 also_dont_gather
提供一列,该函数将起作用
sample_data %>%
a_gather_function(also_dont_gather = ID) %>%
head(5)
# A tibble: 5 x 4
frame ID key value
<int> <dbl> <chr> <dbl>
1 1 1 a -0.626
2 2 1 a 0.184
3 3 1 a -0.836
4 4 1 a 1.60
5 5 1 a 0.330
但默认值失败 NULL
:
sample_data %>%
a_gather_function()
Error in -x : invalid argument to unary operator
我很确定错误来自对 -NULL
求值的函数,因为以下代码给出了相同的错误:
sample_data %>%
tidyr::gather(key, value, -frame, -NULL)
Error in -x : invalid argument to unary operator
你能帮我构建一个函数,允许用户指定不应该收集但默认没有额外列的额外列吗?
编辑:此答案已过时,请参阅了解推荐的解决方案。
我在 tidyselect 中打开了一个问题。
在此期间,您可以使用引号和反引号模式,并检查您是否使用 quo_is_null()
:
捕获了默认的 NULL
a_gather_function <- function(.data, also_dont_gather = NULL) {
also_dont_gather <- enquo(also_dont_gather)
if (rlang::quo_is_null(also_dont_gather)) {
tidyr::gather(.data, key, value, -frame)
} else {
tidyr::gather(.data, key, value, -frame, -!!also_dont_gather)
}
}
推荐的解决方案(对于这个特定的 tidyselect 案例)现在使用 integer()
而不是 NULL
作为默认参数:
my_gather <- function(data, preserve = integer()) {
tidyr::gather(data, "key", "value", -frame, - {{ preserve }})
}
我正在尝试构建一个收集(pivot_longer)数据的函数。
在大多数情况下,该函数应该收集所提供数据中除一列之外的所有列,但是应该允许用户在所提供数据中指定不应收集的其他列。这是用户很少会做的事情,因此参数应该默认为没有额外的列。
我认为我的函数失败了,因为它默认为 NULL
。
数据:
library(tidyverse)
sample_data <- tibble(
frame = rep(seq(1:20), 2),
ID = rep(c(1,2), each = 20),
a = rnorm(n = 40),
b = rnorm(n = 40),
c = rnorm(n = 40))
函数:
a_gather_function <- function(.data, also_dont_gather = NULL) {
.data %>%
tidyr::gather(key, value, -frame, -{{also_dont_gather}})
}
如果我为参数 also_dont_gather
sample_data %>%
a_gather_function(also_dont_gather = ID) %>%
head(5)
# A tibble: 5 x 4
frame ID key value
<int> <dbl> <chr> <dbl>
1 1 1 a -0.626
2 2 1 a 0.184
3 3 1 a -0.836
4 4 1 a 1.60
5 5 1 a 0.330
但默认值失败 NULL
:
sample_data %>%
a_gather_function()
Error in -x : invalid argument to unary operator
我很确定错误来自对 -NULL
求值的函数,因为以下代码给出了相同的错误:
sample_data %>%
tidyr::gather(key, value, -frame, -NULL)
Error in -x : invalid argument to unary operator
你能帮我构建一个函数,允许用户指定不应该收集但默认没有额外列的额外列吗?
编辑:此答案已过时,请参阅
我在 tidyselect 中打开了一个问题。
在此期间,您可以使用引号和反引号模式,并检查您是否使用 quo_is_null()
:
NULL
a_gather_function <- function(.data, also_dont_gather = NULL) {
also_dont_gather <- enquo(also_dont_gather)
if (rlang::quo_is_null(also_dont_gather)) {
tidyr::gather(.data, key, value, -frame)
} else {
tidyr::gather(.data, key, value, -frame, -!!also_dont_gather)
}
}
推荐的解决方案(对于这个特定的 tidyselect 案例)现在使用 integer()
而不是 NULL
作为默认参数:
my_gather <- function(data, preserve = integer()) {
tidyr::gather(data, "key", "value", -frame, - {{ preserve }})
}