Перейдите в функцию с параметрами для аргументации функции в r - PullRequest
0 голосов
/ 25 октября 2018

Я изо всех сил пытаюсь понять все нюансы при передаче чего-либо функции в R. Пакет rlang и то, как его использовать, сбивает меня с толку.Не могу найти хорошее руководство о том, когда использовать все различные rlang :: sym или связанные функции.

В любом случае, я пытаюсь создать функцию, которая позволяет передавать пользовательскую функцию и связанные с ней параметры.Например, означает, квантили и т. Д. Я хочу, чтобы user_metric всегда был в кавычках, а также он должен иметь возможность содержать различные аргументы, такие как na.rm = TRUE и так далее.Может кто-нибудь показать мне, как это может работать, так что, хочу ли я передать «среднее» или «среднее (., Na.rm = TRUE)», оба сработают?

library(tidyverse)
group_by_metrics=function(data, group_col, user_metric){

metrics = data %>% group_by(!!rlang:sym(group_col)) %>% summarise_all(.funs = funs(!!rlang::syms(user_metric))

return(metrics)
}

group_by_metrics(data=mtcars, group_col='vs', user_metric='mean')
group_by_metrics(data=mtcars, group_col='vs', user_metric='mean(., na.rm = TRUE)'
group_by_metrics(data=mtcars, group_col='vs', user_metric ='quantile(., probs=0.95, na.rm = TRUE')

1 Ответ

0 голосов
/ 27 октября 2018

Вы должны различать ваш первый случай, когда вы просто предоставляете имя функции, и ваши другие случаи, когда вы эффективно определяете лямбда-функцию.Для первого вы можете использовать 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...