使用stat_summary绘制中位数位置的图表

5

我希望有一种方法可以在直方图上为每个组中位数所在的位置画出一条垂直线。我可以通过首先按组分组,变异一个新列为中位数,然后按组进行平铺来实现该功能。以下是实现此目标的代码:

library(tidyverse)

N = 1000
m = c(1,5,10)
z = c('A','B','C')

d<-map2_dfr(m,z, ~data.frame(x = rbeta(N,shape1 =.x, shape2 = 20), z = .y))


d %>% 
  group_by(z) %>% 
  mutate(med = median(x)) %>% 
  ungroup %>% 
  ggplot(aes(x, fill = z))+
  geom_histogram(aes(y = ..density..),bins = 10,color = 'black')+
  geom_vline(aes(xintercept = med))+
  facet_wrap(~z)

由于中位数是一个统计摘要,我能否使用 stat_summarystat_functiongeom="vline" 来实现相同的结果?

1个回答

13

可以的;只需要一些诀窍。

由于 stat_summary 在每个 x 上计算 y 的汇总值,我们需要通过提供一个虚拟的 x 变量并将直方图的输入作为 y 来欺骗该函数。我发现最好是给一个在数据范围内的虚拟 x,因为它不会影响轴限制。

在下面的代码中,假设 d 是使用您的代码生成的。

ggplot(d, aes(x, fill = z)) +
  geom_histogram(aes(y = ..density..), bins = 10, colour = "black") +
  stat_summary(aes(x = 0.1, y = x, xintercept = stat(y), group = z), 
               fun.y = median, geom = "vline") +
  facet_wrap(~ z)

这里输入图片描述

与原始情节相比:

d %>% 
  group_by(z) %>% 
  mutate(med = median(x)) %>% 
  ungroup %>% 
  ggplot(aes(x, fill = z))+
  geom_histogram(aes(y = ..density..),bins = 10,color = 'black')+
  geom_vline(aes(xintercept = med))+
  facet_wrap(~z)

在这里输入图片描述


1
哇,这应该不难。我会选择原始方法,它更清晰易懂。 - jtr13
1
我同意。也许有人会有更直接的方法,但在stat_summary中,这是我能想到的。 - teunbrand
我设置了y=4, 并使用+stat_summary(fun="median", geom="point")为每个面创建了一个点(median,4),但在将其转换成垂直线时遇到了困难。 - jtr13
出人意料的是,使用rnorm()而不是rbeta()将无法正常工作,因为实际值将远离1。有什么想法可以纠正这个问题吗? - Dan Chaltiel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接