Here is a solution using data.table (while not specifically requested, it is an obvious compliment or replacement for aggregate or ddply . Also, being a bit long for the code, calling quantile multiple times will be inefficient, since for each call you will sort the data
library(data.table) Tukeys_five <- c("Min","Q1","Med","Q3","Max") IRIS <- data.table(iris)
Or, using a single quantile call with the appropriate prob argument.
IRIS[,as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25))), by = Species] Species 0% 25% 50% 75% 100% 1: setosa 4.3 4.800 5.0 5.2 5.8 2: versicolor 4.9 5.600 5.9 6.3 7.0 3: virginica 4.9 6.225 6.5 6.9 7.9
Note that the names of the generated columns are not syntactically valid, although you can go through a similar renaming with setnames
EDIT
Interestingly, quantile will set the names of the resulting vector if you set names = TRUE and this will copy (it will slow down the number of crunches and consumes memory - it even warns you in the help system, you like it!)
So you should probably use
IRIS[,as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25), names = FALSE)), by = Species]
Or, if you want to return a named list, without R copying inside
IRIS[,{quant <- as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25), names = FALSE)) setattr(quant, 'names', Tukeys_five) quant}, by = Species]