【发布时间】:2019-07-22 10:29:44
【问题描述】:
我需要从一个数字向量中计算几个分位数并为此使用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 参数。
我尝试了以下方法,但没有成功:
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))
}
)
【问题讨论】:
-
我建议你使用
purrr包。有很多地图功能,它们与dplyr配合得很好。 -
谢谢,我尝试了一些将函数映射到参数并返回部分的方法,它确实有效但有点幸运..
-
不是一个骗子,但我不久前问了一个类似的question 并得到了很好的答案
-
谢谢,我看了一下,确实很接近,主要区别在于我使用了不同的 mutate/summarise 函数而不是一个,不是吗?我将深入研究您提供的解决方案,我很可能会在那里找到解决方案