如何使用ddply或aggregate返回向量(如fivenum)的函数?

mlt*_*mlt 8 aggregate r plyr

我想使用几列来分割我的数据框,并fivenum在每个组上调用let .

aggregate(Petal.Width ~ Species, iris, function(x) summary(fivenum(x)))
Run Code Online (Sandbox Code Playgroud)

返回的值是一个只有2列的data.frame,第二个是矩阵.如何将其转换为data.frame的普通列?

更新

我希望使用更少的代码,如下所示 fivenum

ddply(iris, .(Species), summarise,
      Min = min(Petal.Width),
      Q1 = quantile(Petal.Width, .25),
      Med = median(Petal.Width),
      Q3 = quantile(Petal.Width, .75),
      Max = max(Petal.Width)
      )
Run Code Online (Sandbox Code Playgroud)

mne*_*nel 10

这是一个解决方案使用data.table(虽然没有特别要求,但它是一个明显的赞美或替代aggregateddply.除了稍微长的代码,重复调用quantile将是低效的,因为每次调用你将排序数据

library(data.table)
Tukeys_five <- c("Min","Q1","Med","Q3","Max") 

IRIS <- data.table(iris)
# this will create the wide data.table
lengthBySpecies <- IRIS[,as.list(fivenum(Sepal.Length)), by = Species]

# and you can rename the columns from V1, ..., V5 to something nicer

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
Run Code Online (Sandbox Code Playgroud)

或者,使用单个调用来quantile使用适当的prob参数.

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  
Run Code Online (Sandbox Code Playgroud)

请注意,创建的列的名称在语法上不是有效的,尽管您可以使用类似的重命名 setnames


编辑

有趣的是,quantile如果你设置,将设置结果向量的名称names = TRUE,这将复制(减慢数字运算和消耗内存 - 它甚至在帮助中警告你,看上去!)

因此,您应该使用

 IRIS[,as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25), names = FALSE)), by = Species]
Run Code Online (Sandbox Code Playgroud)

或者,如果要返回命名列表,而不在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]
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 5

您可以使用递归do.call调用data.frame每个矩阵元素来获取带有向量元素的data.frame:

dim(do.call("data.frame",dfr))
[1] 3 7

str(do.call("data.frame",dfr))
'data.frame':   3 obs. of  7 variables:
 $ Species            : Factor w/ 3 levels "setosa","versicolor",..: 1 2 3
 $ Petal.Width.Min.   : num  0.1 1 1.4
 $ Petal.Width.1st.Qu.: num  0.2 1.2 1.8
 $ Petal.Width.Median : num  0.2 1.3 2
 $ Petal.Width.Mean   : num  0.28 1.36 2
 $ Petal.Width.3rd.Qu.: num  0.3 1.5 2.3
 $ Petal.Width.Max.   : num  0.6 1.8 2.5
Run Code Online (Sandbox Code Playgroud)