[英]Adding sample size to a box plot at the min or max of the facet in ggplot
关于如何用样本大小标记箱形图,有很多解释,包括这一很好的解释。 他们似乎都使用max(x)
或median(x)
来定位样本大小。
我想知道是否有一种方法可以轻松地将标签放置在图形的顶部或底部,尤其是在facet中使用scale = "free_y"
命令时,其中会针对每个facet自动选择轴的最大值和最小值通过ggplot。
原因是我正在创建多个构面,其中分布狭窄且构面很小。 如果样本大小位于图的顶部或底部,则读取样本大小会更容易...但是我想使用“ free_y”,因为在某些方面中,有意义的差异会被具有数据跨度大得多。
使用链接文章中经过稍微修改的示例:
# function for number of observations
give.n <- function(x){
return(c(y = median(x)*1.05, label = length(x)))
# experiment with the multiplier to find the perfect position
}
# function for mean labels
mean.n <- function(x){
return(c(y = median(x)*0.97, label = round(mean(x),2)))
# experiment with the multiplier to find the perfect position
}
# plot
ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
geom_boxplot(fill = "grey80", colour = "#3366FF") +
stat_summary(fun.data = give.n, geom = "text", fun.y = median) +
stat_summary(fun.data = mean.n, geom = "text", fun.y = mean, colour = "red") +
facet_grid(cyl~., scale="free_y")
有了这种设置,我如何才能找到每个构面的x轴的最小值或最大值,并在此处放置样本大小,而不是每个盒须的中值,最小值或最大值?
编辑
我正在使用下面RS答复中的信息更新问题。 仍然没有答案,但是他们的建议为找到此信息提供了一种解决方案。
ggplot_build(gg)$layout$panel_ranges[[order(levels(factor(mtcars$cyl)))[1]]]$y.range[1]
给出mtcars $ cyl的第一个因子的y范围的最小值。 因此,按照我的逻辑,我们需要构建没有stat_summary
语句的图,然后使用give.n
函数查找样本大小和最小y范围。 之后,我们可以将stat_summary
语句添加到绘图中,如下所示:
# plot
gg = ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
geom_boxplot(fill = "grey80", colour = "#3366FF") +
facet_grid(cyl~., scale="free_y")
# function for number of observations
give.n <- function(x){
return(c(y = ggplot_build(gg)$layout$panel_ranges[[order(levels(factor(mtcars$cyl)))[x]]]$y.range[1], label = length(x)))
# experiment with the multiplier to find the perfect position
}
gg +
stat_summary(fun.data = give.n, geom = "text", fun.y = "median")
但是...上面的代码不起作用,因为我不太了解give.n
函数正在迭代什么。 用[[x]]
1:3 [[x]]
替换[[x]]
绘制该方面最小的所有样本大小,这就是进展。
这是使用[[2]]
,因此所有样本大小都绘制在第二个构面范围的最小值17.62处。
您可以使用ggplot_build
检查ggplot对象的结构,尤其是x和y面板范围存储在布局中。 将图分配给一个对象并查看结构:
gg <- ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
geom_boxplot(fill = "grey80", colour = "#3366FF") +
stat_summary(fun.data = give.n, geom = "text", fun.y = median) +
stat_summary(fun.data = mean.n, geom = "text", fun.y = mean, colour = "red") +
facet_grid(cyl~., scale="free_y")
ggplot_build(gg)
特别是您将对以下内容感兴趣:
ggplot_build(gg)$layout$panel_ranges
3个面板的ylim给出为c(ymin,ymax)并存储在:
ggplot_build(gg)$layout$panel_ranges[[1]]$y.range
ggplot_build(gg)$layout$panel_ranges[[2]]$y.range
ggplot_build(gg)$layout$panel_ranges[[3]]$y.range
编辑以回应评论以及如何将此布局信息合并到绘图中。 在这里,我们使用dplyr分别计算按cyl
分组的stat摘要,并创建单独的数据帧以合并到ggplot2中,而不是使用stat_summary
。
library(dplyr)
gg.summary <- group_by(mtcars, cyl) %>% summarise(mean=mean(mpg), median=median(mpg), length=length(mpg))
解析ylim范围并将其包括在统计摘要df中,统计摘要df按cyl分组,这是我们要分析的变量:
gg.summary$panel.ylim <- sapply(order(levels(factor(mtcars$cyl))), function(x) ggplot_build(gg)$layout$panel_ranges[[x]]$y.range[1])
# # A tibble: 3 x 5
# cyl mean median length panel.ylim
# <dbl> <dbl> <dbl> <int> <dbl>
# 1 4 26.66364 26.0 11 20.775
# 2 6 19.74286 19.7 7 17.620
# 3 8 15.10000 15.2 14 9.960
在ggplot中使用,我相信这是您想要的绘图:
gg + geom_text(data=gg.summary, (aes(x=factor(cyl), y=panel.ylim, label=paste("n =",length)))) +
geom_text(data=gg.summary, (aes(x=factor(cyl), y=median*0.97, label=format(median, nsmall=2))))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.