Мне нужно вычислить несколько квантилей из одного числового вектора и использовать для этого dplyr::summarise
.Вот что у меня есть:
library(dplyr)
library(rlang)
quantiles <- function(data, group, ...){
group <- enquo(group)
value_vars <- quos(...)
data %>%
group_by(!!group) %>%
summarise_at(vars(!!!value_vars), funs(
median = median,
q1 = quantile(., probs = 0.25),
q3 = quantile(., probs = 0.75))
) %>%
ungroup()
}
quantiles(data = iris, group = Species, Sepal.Length, Petal.Width)
Работает, но вызывает отсутствие видимой привязки для переменной '.' при проверке пакета.Поэтому я ищу способ избавиться от .
в функции.Я могу заменить mutate_at
на summarise_at
, а затем суммировать с first
, но это может стать довольно тяжелым:
quantiles <- function(data, group, ...){
group <- enquo(group)
value_vars <- quos(...)
data %>%
group_by(!!group) %>%
mutate_at(vars(!!!value_vars), funs(median = median)) %>%
mutate_at(vars(!!!value_vars), funs(q1 = quantile), probs = 0.25) %>%
mutate_at(vars(!!!value_vars), funs(q3 = quantile), probs = 0.75) %>%
summarise_at(vars(matches('(median|q1|q3)$')), first) %>%
ungroup()
}
quantiles(data = iris, group = Species, Sepal.Length, Petal.Width)
edit: использовать purrr:map2
Я могу создать список функций с желаемыми значениями вторичного аргумента:
quantile_funs <- purrr::map2(
.x = list(median = median, q1 = quantile, q3 = quantile),
.y = list(NULL, 0.25, 0.75),
.f = function(fun, arg){
function(x) fun(x, probs = arg)
}
)
quantiles <- function(data, group, ...){
group <- enquo(group)
value_vars <- quos(...)
data %>%
group_by(!!group) %>%
summarise_at(vars(!!!value_vars), .funs = quantile_funs) %>%
ungroup()
}
quantiles(data = iris, group = Species, Sepal.Length, Petal.Width)
Это работает хорошо, но благодаря удаче, поскольку mean
имеет аргумент ...
, который позволяет мне фактически выполнять mean(x, probs = NULL)
пока у него нет аргумента probs
.
Я попробовал следующее, но это не сработало:
quantile_funs <- purrr::map2(
.x = list(median = median, q1 = quantile, q3 = quantile),
.y = list(list(NULL = NULL), list(probs = 0.25), list(probs = 0.75)),
.f = function(fun, arg){
function(x) fun(x, splice(arg))
}
)