ggplot2 - 具有组内比例而非频率的多组直方图

And*_*ier 19 r ggplot2

我有三个ExperimentCohort因素确定的学生群体.对于每个学生,我有一个LetterGrade,也是一个因素.我想LetterGrade为每个人绘制一个类似直方图的条形图ExperimentCohort.运用

ggplot(df, alpha = 0.2, 
       aes(x = LetterGrade, group = ExperimentCohort, fill = ExperimentCohort))                                                                                                                                                       
  + geom_bar(position = "dodge")
Run Code Online (Sandbox Code Playgroud)

让我非常接近,但这三个ExperimentCohorts学生的数量并不相同.为了在更均匀的场上比较这些,我希望y轴是每个字母等级的队列中的比例.到目前为止,还没有计算这个比例,并在绘图之前将其放在一个单独的数据框中,我还没有找到办法做到这一点.

SO和其他地方的类似问题的每个解决方案都涉及aes(y = ..count../sum(..count..)),但sum(.. count ..)在整个数据帧中执行,而不是在每个队列中执行.有人有建议吗?这是创建示例数据帧的代码:

df <- data.frame(ID = 1:60, 
        LetterGrade = sample(c("A", "B", "C", "D", "E", "F"), 60, replace = T),
        ExperimentCohort = sample(c("One", "Two", "Three"), 60, replace = T))
Run Code Online (Sandbox Code Playgroud)

谢谢.

Did*_*rts 19

错误的解决方案

您可以使用stat_bin()y=..density..获取每组中的百分比.

ggplot(df, alpha = 0.2,
      aes(x = LetterGrade, group = ExperimentCohort, fill = ExperimentCohort))+
      stat_bin(aes(y=..density..), position='dodge')
Run Code Online (Sandbox Code Playgroud)

更新 - 正确的解决方案

正如@rpierce所指出的,y=..density..将计算每组的密度值而不是百分比(它们不相同).

要获得百分比的正确解决方案,一种方法是在绘图之前计算它们.对于ddply()库中使用的这个函数plyr.在每个ExperimentCohort计算出的比例中使用函数prop.table()并将table()其保存为prop.随着names()table()回来了LetterGrade.

df.new<-ddply(df,.(ExperimentCohort),summarise,
              prop=prop.table(table(LetterGrade)),
              LetterGrade=names(table(LetterGrade)))

 head(df.new)
  ExperimentCohort       prop LetterGrade
1              One 0.21739130           A
2              One 0.08695652           B
3              One 0.13043478           C
4              One 0.13043478           D
5              One 0.30434783           E
6              One 0.13043478           F
Run Code Online (Sandbox Code Playgroud)

现在使用这个新的数据框进行绘图.已经计算了比例 - 将它们作为y值提供并添加stat="identity"到内部geom_bar.

ggplot(df.new,aes(LetterGrade,prop,fill=ExperimentCohort))+
  geom_bar(stat="identity",position='dodge')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • (+1)我最近尝试了这个,并且大部分回家了,但需要在调用`as.numeric`时包装这个`prop = prop.table(table(LetterGrade))`,所以,`prop = as.数字(prop.table(表(LetterGrade)))`. (8认同)

sir*_*len 5

您还可以通过weight为每个组创建一个总计为1 的列来做到这一点:

ggplot(df %>%
         group_by(ExperimentCohort) %>%
         mutate(weight = 1 / n()),
       aes(x = LetterGrade, fill = ExperimentCohort)) +
  geom_histogram(aes(weight = weight), stat = 'count', position = 'dodge')
Run Code Online (Sandbox Code Playgroud)