如何用 ... (dot-dot-dot) 编写一个函数,它也可以接受 tidyselect 助手?
How to write a function with ... (dot-dot-dot) that can also accept tidyselect helpers?
我想编写一个处理数据的自定义函数。该函数的输入应为:
- data.frame 对象
- 数据中与函数将要执行的操作相关的列的名称。
我想编写此函数,使指定列名的参数尽可能灵活。因此,我决定使用 dot-dot-dot (...
).
但是,我不知道如何合并 tidyselect
的 selection helpers(即 contains
,starts_with
, 等等)
例子
举个例子,假设我想为 dplyr::coalesce()
.
写一个包装器
library(rlang)
library(dplyr)
my_coalesce_func <- function(dat, ...) {
# step 1: save `...` into cols (https://tidyeval.tidyverse.org/multiple.html)
cols <- enquos(...)
# step 2: mutate new column `new_col` that coalesces columns of interest
mutate(dat, new_col = coalesce(!!!cols))
}
# toy data
my_df <-
data.frame(
col_a = c(2, 2, 5, 5, 3),
col_b = c(NA, 4, 2, 3, 1),
col_c = c(4, 5, 3, 1, 2),
col_d = c(1, NA, 4, 2, 4),
col_e = c(3, 3, 1, 4, 5),
extra_col = 1:5
)
# run the function -- works fine when we explicitly provide column names
my_coalesce_func(dat = my_df, col_a, col_b, col_c, col_d, col_e)
#> col_a col_b col_c col_d col_e extra_col new_col
#> 1 2 NA 4 1 3 1 2
#> 2 2 4 5 NA 3 2 2
#> 3 5 2 3 4 1 3 5
#> 4 5 3 1 2 4 4 5
#> 5 3 1 2 4 5 5 3
# run the function -- fails to use a select helper
my_coalesce_func(dat = my_df, starts_with("col"))
#> Error: Problem with `mutate()` column `new_col`.
#> i `new_col = coalesce(starts_with("col"))`.
#> x `starts_with()` must be used within a *selecting* function.
#> i See <https://tidyselect.r-lib.org/reference/faq-selection-context.html>.
由 reprex package (v2.0.0)
于 2021-07-01 创建
我需要向 my_coalesce_func()
添加什么才能使其 运行 成功
my_coalesce_func(dat = my_df, starts_with("col"))
或传递给 ...
的任何其他 select 助手。
谢谢!
在这个的基础上,一招就是靠dplyr::select()
:
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
my_coalesce_func = function(data, ...) {
data %>%
select(...) %>%
transmute(new_col = coalesce(!!!.)) %>%
bind_cols(data, .)
}
my_df <-
data.frame(
col_a = c(2, 2, 5, 5, 3),
col_b = c(NA, 4, 2, 3, 1),
col_c = c(4, 5, 3, 1, 2),
col_d = c(1, NA, 4, 2, 4),
col_e = c(3, 3, 1, 4, 5),
extra_col = 1:5
)
# explicitly provide column names
my_coalesce_func(dat = my_df, col_d, col_e)
#> col_a col_b col_c col_d col_e extra_col new_col
#> 1 2 NA 4 1 3 1 1
#> 2 2 4 5 NA 3 2 3
#> 3 5 2 3 4 1 3 4
#> 4 5 3 1 2 4 4 2
#> 5 3 1 2 4 5 5 4
# use tidyselect helpers
my_coalesce_func(dat = my_df, starts_with("col"), -(col_a:col_c))
#> col_a col_b col_c col_d col_e extra_col new_col
#> 1 2 NA 4 1 3 1 1
#> 2 2 4 5 NA 3 2 3
#> 3 5 2 3 4 1 3 4
#> 4 5 3 1 2 4 4 2
#> 5 3 1 2 4 5 5 4
由 reprex package (v1.0.0)
创建于 2021-07-01
我想编写一个处理数据的自定义函数。该函数的输入应为:
- data.frame 对象
- 数据中与函数将要执行的操作相关的列的名称。
我想编写此函数,使指定列名的参数尽可能灵活。因此,我决定使用 dot-dot-dot (...
).
但是,我不知道如何合并 tidyselect
的 selection helpers(即 contains
,starts_with
, 等等)
例子
举个例子,假设我想为 dplyr::coalesce()
.
library(rlang)
library(dplyr)
my_coalesce_func <- function(dat, ...) {
# step 1: save `...` into cols (https://tidyeval.tidyverse.org/multiple.html)
cols <- enquos(...)
# step 2: mutate new column `new_col` that coalesces columns of interest
mutate(dat, new_col = coalesce(!!!cols))
}
# toy data
my_df <-
data.frame(
col_a = c(2, 2, 5, 5, 3),
col_b = c(NA, 4, 2, 3, 1),
col_c = c(4, 5, 3, 1, 2),
col_d = c(1, NA, 4, 2, 4),
col_e = c(3, 3, 1, 4, 5),
extra_col = 1:5
)
# run the function -- works fine when we explicitly provide column names
my_coalesce_func(dat = my_df, col_a, col_b, col_c, col_d, col_e)
#> col_a col_b col_c col_d col_e extra_col new_col
#> 1 2 NA 4 1 3 1 2
#> 2 2 4 5 NA 3 2 2
#> 3 5 2 3 4 1 3 5
#> 4 5 3 1 2 4 4 5
#> 5 3 1 2 4 5 5 3
# run the function -- fails to use a select helper
my_coalesce_func(dat = my_df, starts_with("col"))
#> Error: Problem with `mutate()` column `new_col`.
#> i `new_col = coalesce(starts_with("col"))`.
#> x `starts_with()` must be used within a *selecting* function.
#> i See <https://tidyselect.r-lib.org/reference/faq-selection-context.html>.
由 reprex package (v2.0.0)
于 2021-07-01 创建我需要向 my_coalesce_func()
添加什么才能使其 运行 成功
my_coalesce_func(dat = my_df, starts_with("col"))
或传递给 ...
的任何其他 select 助手。
谢谢!
在这个dplyr::select()
:
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
my_coalesce_func = function(data, ...) {
data %>%
select(...) %>%
transmute(new_col = coalesce(!!!.)) %>%
bind_cols(data, .)
}
my_df <-
data.frame(
col_a = c(2, 2, 5, 5, 3),
col_b = c(NA, 4, 2, 3, 1),
col_c = c(4, 5, 3, 1, 2),
col_d = c(1, NA, 4, 2, 4),
col_e = c(3, 3, 1, 4, 5),
extra_col = 1:5
)
# explicitly provide column names
my_coalesce_func(dat = my_df, col_d, col_e)
#> col_a col_b col_c col_d col_e extra_col new_col
#> 1 2 NA 4 1 3 1 1
#> 2 2 4 5 NA 3 2 3
#> 3 5 2 3 4 1 3 4
#> 4 5 3 1 2 4 4 2
#> 5 3 1 2 4 5 5 4
# use tidyselect helpers
my_coalesce_func(dat = my_df, starts_with("col"), -(col_a:col_c))
#> col_a col_b col_c col_d col_e extra_col new_col
#> 1 2 NA 4 1 3 1 1
#> 2 2 4 5 NA 3 2 3
#> 3 5 2 3 4 1 3 4
#> 4 5 3 1 2 4 4 2
#> 5 3 1 2 4 5 5 4
由 reprex package (v1.0.0)
创建于 2021-07-01