Вы должны различать ваш первый случай, когда вы просто предоставляете имя функции, и ваши другие случаи, когда вы эффективно определяете лямбда-функцию.Для первого вы можете использовать match.fun
, чтобы найти функцию по имени.В последнем случае преобразуйте свои строки в формулы, затем используйте purrr::as_mapper()
, чтобы сделать из них функции.Используйте ensym
вместо sym
для разрешения аргументов без кавычек.
group_by_metrics <- function(.data, group_col, user_metric)
{
f <- purrr::possibly( match.fun, NULL )(user_metric)
if( is.null(f) )
f <- str_c( "~", user_metric ) %>% as.formula %>% as_mapper
.data %>% group_by(!!rlang::ensym(group_col)) %>% summarize_all( f )
}
group_by_metrics( mtcars, "vs", "quantile(., probs=0.95, na.rm=TRUE)" )
# vs mpg cyl disp hp drat wt qsec am gear carb
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 0 21.7 8 462. 275. 4.25 5.36 18.0 1 5 6.30
# 2 1 32.9 6 237. 123 4.47 3.45 21.2 1 4.35 4
## Using ensym instead of sym allows you to drop " for group_col
group_by_metrics( mtcars, vs, "mean" )
# vs mpg cyl disp hp drat wt qsec am gear carb
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 0 16.6 7.44 307. 190. 3.39 3.69 16.7 0.333 3.56 3.61
# 2 1 24.6 4.57 132. 91.4 3.86 2.61 19.3 0.5 3.86 1.79
Обратите внимание, что вы можете избежать всего этого преобразования, если передаете дополнительные аргументы отдельно, используя ...
:
group_by_metrics2 <- function(.data, group_col, user_metrics, ...)
{
.data %>% group_by(!!rlang::ensym(group_col)) %>%
summarize_all( user_metrics, ... )
}
group_by_metrics2( mtcars, "vs", "quantile", probs=0.05, na.rm=TRUE)
# # A tibble: 2 x 11
# vs mpg cyl disp hp drat wt qsec am gear carb
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 0 10.4 5.7 141. 107. 2.90 2.55 14.6 0 3 2
# 2 1 18.0 4 74.1 58.5 2.97 1.58 17.8 0 3 1
В последнем примере строковые кавычки "
являются необязательными для vs
и quantile
.