タイトルのまんまです。
ざっくり作ってみました。
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
d_quant <- function(x, var, probs = seq(0, 1, 0.25)) {
if(length(var)!=1){
stop("length(var) must 1.", call. = FALSE)
}
if(!is.character(var)){
stop("var must be a charactor.", call. = FALSE)
}
dots <- lapply(sprintf("~quantile(%1$s, probs = %2$s)", as.character(var), probs), as.formula)
summarise_(x, .dots = setNames(dots, probs))
}
注意した点は、「dplyr::summarise()で使える関数は長さ1を返さないとだめ」という点です。なので、そのままquantile関数を適用しようとすると怒られました。
仕方ないので「引数で複数列を返してくるように記述」することになるのですが、何個も同じように記述するのは実に面倒です。かといって単純にsplintf()で持ってきてもうまくいきませんでした。そこでsummarise_()を使うこととし、引数部分はリストで渡してみました。
多分大したものではないのですが、NSEとかeval(parse())とか自分にとってはいい勉強になりました。
こんな感じです。
d_quant(iris, "Sepal.Length")
## 0 0.25 0.5 0.75 1
## 1 4.3 5.1 5.8 6.4 7.9
iris %>% d_quant("Sepal.Length", probs = c(0.25, 0.5, 0.75))
## 0.25 0.5 0.75
## 1 5.1 5.8 6.4
iris %>% group_by(Species) %>% d_quant("Sepal.Length", probs = c(0.25, 0.5, 0.75))
## Source: local data frame [3 x 4]
##
## Species 0.25 0.5 0.75
## (fctr) (dbl) (dbl) (dbl)
## 1 setosa 4.800 5.0 5.2
## 2 versicolor 5.600 5.9 6.3
## 3 virginica 6.225 6.5 6.9
わりとやっつけなので、変数名をcharactorで指定しないといけなかったりしますが、このようにpipeでつないでもOKです。
多分この関数自体の需要は少ないですが、「dplyr::summarise()で使える関数は長さ1を返さないとだめ」をクリアできるのは嬉しいかなと思います。要するにlapplyを利用して作ったformula型のものを、summarise_()の.dots =にぶち込めば、いい感じに評価して戻してくれます。もうちょっといい方法もありそうだけど、私ではこの程度でした。
Enjoy!