如何创建一个具有固定bin宽度的直方图,百分比刻度反映每个面?

时间:2017-11-15 09:37:45

标签: r plot ggplot2 histogram

我想创建一个直方图,其中y轴显示ggplot2中每个面的百分比。我已经看到了几个类似的问题,但是一些答案似乎过时了,或者它们显示了所有观察的百分比而不是每个方面。

我试过了:

library(ggplot2)
library(scales)

ggplot(mtcars, aes(mpg))+
    facet_grid(cyl ~ am)+
    stat_count(aes(y=..prop..)) +
    theme_bw()+
    scale_y_continuous(labels = percent_format())

除了没有修复binwidth之外,这似乎有效。观察很少的方面有很大的条形。

我如何修复binwidth?

编辑:改编自ACNB的解决方案 之前我忽略了这一点,我刚才看到Andrey Kolyadin更快地提供了更简洁的解决方案。

binwidth <- 1
mtcars.stats <- mtcars %>%
    group_by(cyl, am) %>%
    mutate(bin = cut(mpg, breaks=seq(0,35, binwidth), 
                     labels = seq(0 + binwidth, 35, binwidth)-(binwidth/2)),
           n = n()) %>%
    group_by(cyl, am, bin) %>%
    summarise(p = n()/n[1]) %>%
    ungroup() %>%
    mutate(bin = as.numeric(as.character(bin)))

ggplot(mtcars.stats, aes(x = bin, y= p)) + 
    geom_col() + 
    facet_grid(cyl~am)+
    theme_bw()+
    scale_y_continuous(labels = percent_format())

2 个答案:

答案 0 :(得分:3)

总之,我建议不要依赖ggplot2的统计层,并在绘图前计算必要的统计数据:

library('zoo')
library('tidyverse')

# Selecting breaks
breaks <- seq.int(min(mtcars$mpg), max(mtcars$mpg), length.out = 19)

# Calculating densities
mt_hist <- mtcars %>% 
  group_by(cyl, am) %>% 
  summarise(x = list(rollmean(breaks, 2)),
            count = list(hist(mpg, breaks = breaks, plot = FALSE)$counts)) %>% 
  unnest() %>% 
  group_by(cyl, am) %>% 
  mutate(count = count/sum(count))

并策划自己:

ggplot(mt_hist)+
  aes(x = x,
      y = count)+
  geom_col()+
  facet_grid(cyl ~ am)+
  theme_bw()+
  scale_y_continuous(labels = percent_format())

enter image description here

答案 1 :(得分:1)

您是否尝试过添加geom_histogramstat参数,例如......

p <- ggplot(mtcars, aes(mpg))
p <- p + geom_histogram(stat = 'bin')
p <- p + facet_grid(cyl ~ am)
p <- p + stat_count(aes(y=..prop..))
p <- p +   theme_bw()
p <- p +   scale_y_continuous(labels = percent_format())
p