我需要从一个数字矢量计算几个分位数,并为此使用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)
编辑:使用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
。 / p>
我尝试了以下操作,但没有成功:
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))
}
)
答案 0 :(得分:0)
以下是使用mapply
函数的一个选项:
library('data.table')
quantiles <- function(data, group, v.names, quantile = c(.25, 0.5, .75)){
data <- as.data.table(data)
gLevels <- levels(data[, get(group)])
quantileDT <- as.data.table(
expand.grid(v.name = v.names, grp = gLevels, quantile = quantile,
stringsAsFactors = FALSE))
quantileDT[, Value:=
mapply(function(v, g, q) quantile(data[get(group) == g, get(v)], q),
v = v.name,
g = grp,
q = quantile)]
dcast(quantileDT, grp ~ v.name + quantile, value.var = 'Value')
}
quantiles(data = iris, group = 'Species', v.names = c('Sepal.Length', 'Petal.Width'))
也许可以使用一些清理方法-例如使用data
和quantile
作为变量名并不是一个好主意。这是您得到的输出:
grp Petal.Width_0.25 Petal.Width_0.5 Petal.Width_0.75 Sepal.Length_0.25 Sepal.Length_0.5 Sepal.Length_0.75
1: setosa 0.2 0.2 0.3 4.800 5.0 5.2
2: versicolor 1.2 1.3 1.5 5.600 5.9 6.3
3: virginica 1.8 2.0 2.3 6.225 6.5 6.9