我有三个由ExperimentCohort
因素确定的学生队列。对于每个学生,我有LetterGrade
,也是一个因素。我想为每个LetterGrade
绘制一个类似直方图的条形图ExperimentCohort
。使用
ggplot(df, alpha = 0.2,
aes(x = LetterGrade, group = ExperimentCohort, fill = ExperimentCohort))
+ geom_bar(position = "dodge")
让我非常接近,但三个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))
感谢。
答案 0 :(得分:19)
您可以使用stat_bin()
和y=..density..
来获取每个组的百分比。
ggplot(df, alpha = 0.2,
aes(x = LetterGrade, group = ExperimentCohort, fill = ExperimentCohort))+
stat_bin(aes(y=..density..), position='dodge')
正如@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
现在使用这个新的数据框进行绘图。已经计算了比例 - 将它们作为y
值提供,并在stat="identity"
内添加geom_bar
。
ggplot(df.new,aes(LetterGrade,prop,fill=ExperimentCohort))+
geom_bar(stat="identity",position='dodge')
答案 1 :(得分:5)
您也可以通过为每个组创建一个总计为1的weight
列来执行此操作:
ggplot(df %>%
group_by(ExperimentCohort) %>%
mutate(weight = 1 / n()),
aes(x = LetterGrade, fill = ExperimentCohort)) +
geom_histogram(aes(weight = weight), stat = 'count', position = 'dodge')
答案 2 :(得分:1)
我最近尝试过此操作,并在调用ddply时遇到错误:Column prop must be length 1 (a summary value), not 6
。花了一些时间与ddply但是无法使解决方案正常工作所以我提供了一个替代方案(注意这仍然使用plyr
):
df.new <- df2 %>%
group_by(ExperimentCohort,LetterGrade) %>%
summarise (n = n()) %>%
mutate(freq = n / sum(n))
然后你可以像@ didzis-elferts提到的那样绘制它:
ggplot(df.new,aes(LetterGrade,freq,fill=ExperimentCohort))+
geom_bar(stat="identity",position='dodge')