geom_abline似乎不尊重facet_grid中的组[ggplot2]

时间:2013-11-14 18:39:18

标签: r ggplot2

试着了解geom_abline如何在ggplot中与facet一起使用。

我有一个学生考试成绩的数据集。它们位于包含4列的数据表dt中:

student: unique student ID
cohort:  grouping factor for students (A, B, … H)
subject: subject of the test (English, Math, Science)
score:   the test score for that student in that subject

目标是比较同龄人。以下代码段创建了一个示例数据集。

library(data.table)
## cohorts: list of cohorts with number of students in each
cohorts <- data.table(name=toupper(letters[1:8]),size=as.numeric(c(8,25,16,30,10,27,13,32)))
## base: assign students to cohorts
base    <- data.table(student=c(1:sum(cohorts$size)),cohort=rep(cohorts$name,cohorts$size))
## scores for each subject
english <- data.table(base,subject="English", score=rnorm(nrow(base), mean=45, sd=50))
math    <- data.table(base,subject="Math",    score=rnorm(nrow(base), mean=55, sd=25))
science <- data.table(base,subject="Science", score=rnorm(nrow(base), mean=70, sd=25))
## combine
dt      <- rbind(english,math,science)
## clip scores to (0,100)
dt$score<- (dt$score>=0) * dt$score
dt$score<- (dt$score<=100)*dt$score + (dt$score>100)*100

以下显示按群组划分的平均得分为95%CL,按主题划分,并包括(蓝色,虚线)参考线(使用geom_abline)。

library(ggplot2)
library(Hmisc)
ggp <- ggplot(dt,aes(x=cohort, y=score)) + ylim(0,100)
ggp <- ggp + stat_summary(fun.data="mean_cl_normal")
ggp <- ggp + geom_abline(aes(slope=0,intercept=mean(score)),color="blue",linetype="dashed")
ggp <- ggp + facet_grid(subject~.)
ggp

问题是参考线(来自geom_abline)在所有方面都是相同的(=所有学生和所有科目的平均得分)。因此stat_summary似乎尊重facet_grid中暗示的分组(例如,通过主题),但是abline没有。 任何人都可以解释原因吗?

注意:我意识到这个问题可以通过创建一个单独的组表格并将其用作geom_abline(下面)中的数据源来解决,但为什么这是必要的?

means <- dt[,list(mean.score=mean(score)),by="subject"]
ggp <- ggplot(dt,aes(x=cohort, y=score)) + ylim(0,100)
ggp <- ggp + stat_summary(fun.data="mean_cl_normal")
ggp <- ggp + geom_abline(data=means, aes(slope=0,intercept=mean.score),color="blue",linetype="dashed")
ggp <- ggp + facet_grid(subject~.)
ggp

2 个答案:

答案 0 :(得分:3)

这应该做你想要的。 stat_*函数为每个方面使用不同的数据集合。我认为aes函数的geom_*中的任何表达式都是用于转换每个y值。

ggplot(dt,aes(x=cohort, y=score)) +
       stat_summary(fun.data="mean_cl_normal") + 
       stat_smooth(formula=y~1,aes(group=1),method="lm",se=FALSE) +
       facet_grid(subject~.) + ylim(0,100)

enter image description here

答案 1 :(得分:0)

正如golbasche所说,我可能会做更像这样的事情:

dt <- dt[,avg_score := mean(score),by = subject]

ggplot(dt,aes(x=cohort, y=score)) + 
    facet_grid(subject~.) + 
    stat_summary(fun.data="mean_cl_normal") +
    geom_hline(aes(yintercept = avg_score),color = "blue",linetype = "dashed") + 
    ylim(0,100)