我需要计算具有许多组的data.frame的箱线图统计。
我理想地需要的是:
library(dplyr)
iris %>%
group_by(Species) %>%
summarise(boxplot=boxplot.stats(Sepal.Length))) # + some kind of magic
# A tibble: 3 x 6
Species lower_whisker lower_hinge median upper_hinge upper_whisker
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 4.3 4.8 5 5.2 5.8
2 versicolor 4.9 5.6 5.9 6.3 7
3 virginica 5.6 6.2 6.5 6.9 7.9
但是到目前为止,我已经完成了一半purrr
的映射工作,并且无法解压缩它。
boxplot.stats2 <- function(x, ...) {
res <- boxplot.stats(x, ...)
res <- res$stats
names(res) <- c('lower_whisker','lower_hinge','median','upper_hinge','upper_whisker')
#t(as.data.frame(res))
res
}
iris %>%
group_by(Species) %>%
summarise(boxplot=list(boxplot.stats2(Sepal.Length)),
#manual unpacking
lower_whisker = boxplot[[1]]['lower_whisker'],
lower_hinge = boxplot[[1]]['lower_hinge'],
median = boxplot[[1]]['median'],
upper_hinge = boxplot[[1]]['upper_hinge'],
upper_whisker = boxplot[[1]]['upper_whisker']
)
它给出的结果相同,但是我怀疑应该有一个更优雅的解决方案。
答案 0 :(得分:2)
如果您将列表用作摘要输出,则可以使用软件包 tidyr 中的unnest()
函数。
tidyr 的开发版本具有一些新功能,其中包括unnest_wider()
,这是适合您情况的便捷工具。
在这里,我将只获得5个箱线图统计数字,并将它们放在summarise()
中的列表中,就像您开始做的那样。我也为它们命名,因为boxplot.stats()
的统计信息没有任何识别信息。
新列是一个列表列,其中包含每个物种5个值的命名向量。
library(dplyr)
library(tidyr) # development version, tidyr_0.8.3.9000
iris %>%
group_by(Species) %>%
summarise(boxplot= list( setNames(boxplot.stats(Sepal.Length)$stats,
c('lower_whisker','lower_hinge','median','upper_hinge','upper_whisker') ) ) )
# A tibble: 3 x 2
Species boxplot
<fct> <list>
1 setosa <dbl [5]>
2 versicolor <dbl [5]>
3 virginica <dbl [5]>
紧跟unnest_wider()
之后,将为您提供所需的结果。
iris %>%
group_by(Species) %>%
summarise(boxplot= list( setNames(boxplot.stats(Sepal.Length)$stats,
c('lower_whisker','lower_hinge','median','upper_hinge','upper_whisker') ) ) ) %>%
unnest_wider(boxplot)
# A tibble: 3 x 6
Species lower_whisker lower_hinge median upper_hinge upper_whisker
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 4.3 4.8 5 5.2 5.8
2 versicolor 4.9 5.6 5.9 6.3 7
3 virginica 5.6 6.2 6.5 6.9 7.9
您可以跳过命名步骤,但是您需要在末尾命名列。
iris %>%
group_by(Species) %>%
summarise(boxplot= list( boxplot.stats(Sepal.Length)$stats ) ) %>%
unnest_wider(boxplot)
# A tibble: 3 x 6
Species ...1 ...2 ...3 ...4 ...5
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 4.3 4.8 5 5.2 5.8
2 versicolor 4.9 5.6 5.9 6.3 7
3 virginica 5.6 6.2 6.5 6.9 7.9
tidyr 的非开发版本在这里仍然可以提供帮助,尽管这项工作还需要很多步骤。由于列表名称在当前unnest()
中丢失,因此您需要在取消嵌套之前手动添加这些名称,以便spread()
进入新列。
iris %>%
group_by(Species) %>%
summarise(boxplot= list( boxplot.stats(Sepal.Length)$stats),
stat = list( c('lower_whisker','lower_hinge','median','upper_hinge','upper_whisker') ) ) %>%
unnest(stat, boxplot) %>%
spread(stat, boxplot)
# A tibble: 3 x 6
Species lower_hinge lower_whisker median upper_hinge upper_whisker
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 4.8 4.3 5 5.2 5.8
2 versicolor 5.6 4.9 5.9 6.3 7
3 virginica 6.2 5.6 6.5 6.9 7.9