external_func использует аккуратную оценку для col_rfs и dflt_flag, т. е. это можно сделать col_rfs = dplyr::starts_with("col")
.
library(magrittr)
outer_func <- function(dat, col_rfs, dflt_flag){
col_rfs_str <- tidyselect::eval_select(rlang::enquo(col_rfs), dat) %>% names
freqs <- purrr::map(col_rfs_str, \(x) get_freq(dat, !!rlang::sym(x), {{dflt_flag}}))
return(freqs)
}
get_freq <- function(dat, rf, dflt_flag){
freq <- dat %>%
dplyr::group_by({{rf}}) %>%
dplyr::summarise(count = dplyr::n(), dr = mean({{dflt_flag}}), .groups = "drop")
return(freq)
}
dat <- tibble::tibble(dflt = sample(c(0,1), size = 1000, replace = TRUE), rf_1 = sample(c("a","b"), size = 1000, replace = TRUE), rf_2 = sample(c(1,2), size = 1000, replace = TRUE))
outer_func(dat, dplyr::starts_with("rf"), dflt)
Какой хороший шаблон позволяет избежать преобразования col_rfs
в строку через tidyselect::eval_select(rlang::enquo(col_rfs), dat) %>% names
, а затем обратно в столбец без кавычек через !!rlang::sym(x)
при использовании purrr::map
?
Важно сохранять входные данные outer_func
и get_freq
как строки без кавычек.
Извинения. Я привел полный пример. Это работает так, как задумано, но у меня такое ощущение, что есть способ получше, чем обработка строк на предмет purrr...
Вы можете использовать .data[[x]]
, как показано ниже.
outer_func <- function(dat, col_rfs, dflt_flag){
dat |>
dplyr::select(all_of(col_rfs)) |>
names() |>
purrr::map(function(x) get_freq(dat, .data[[x]], {{dflt_flag}}))
}
Это дает тот же результат, что и ваша функция.
Примерно раз в неделю я обращаюсь к статье Программирование с помощью dplyr.
Хороший ответ! Я думаю, что all_of()
не нужен, потому что col_rfs
— это выражение аккуратного выбора, а не внешний вектор.
Вам будет легче помочь, если вы включите простой воспроизводимый пример с примерами ввода и желаемым результатом, который можно использовать для тестирования и проверки возможных решений. Покажите, как именно вы вызываете эти функции.