我需要计算包含许多组的 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
Run Code Online (Sandbox Code Playgroud)
但到目前为止,我已经成功地完成了半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']
)
Run Code Online (Sandbox Code Playgroud)
它给出了相同的结果,但我怀疑应该有一个更优雅的解决方案。
如果您使用列表作为摘要输出,则可以使用tidyrunnest()包中的函数。
新版本的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]>
Run Code Online (Sandbox Code Playgroud)
接下来就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
Run Code Online (Sandbox Code Playgroud)
您可以跳过命名步骤,但您需要在最后命名列。
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
Run Code Online (Sandbox Code Playgroud)
旧版本的tidyr(1.0.0 之前)仍然可以在这里提供帮助,尽管这项工作需要执行更多步骤。由于列表名称在当前中丢失,因此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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3053 次 |
| 最近记录: |