这里有一个使用 data.table
的解决方案(虽然没有明确要求,但它显然是 aggregate
或 ddply
的明显补充或替代品)。除了代码稍微长一些之外,反复调用 quantile
也会效率低下,因为每次调用都需要对数据进行排序。
library(data.table)
Tukeys_five <- c("Min","Q1","Med","Q3","Max")
IRIS <- data.table(iris)
lengthBySpecies <- IRIS[,as.list(fivenum(Sepal.Length)), by = Species]
setnames(lengthBySpecies, paste0('V',1:5), Tukeys_five)
lengthBySpecies
Species Min Q1 Med Q3 Max
1: setosa 4.3 4.8 5.0 5.2 5.8
2: versicolor 4.9 5.6 5.9 6.3 7.0
3: virginica 4.9 6.2 6.5 6.9 7.9
或者,使用适当的prob
参数一次调用quantile
函数。
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
请注意,创建的列名在语法上无效,尽管您可以使用类似的重命名方法使用
setnames
进行更改。
编辑
有趣的是,如果设置names = TRUE
,quantile
将设置结果向量的名称,并且这将复制(减慢计算速度和消耗内存-甚至在帮助文件中发出警告!)
因此,您应该使用
IRIS[,as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25), names = FALSE)), by = Species]
或者,如果您想返回指定的列表而不是在 R
内部进行复制
IRIS[,{quant <- as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25), names = FALSE))
setattr(quant, 'names', Tukeys_five)
quant}, by = Species]
data.frame
。它与matrix
无关。也许如果您展示一下您期望的结果,回答这个问题会更容易些。 - nograpeslength()
包装示例代码行。 - mlt