I'm using ggplot2 to create panels of histograms, and I'd like to be able to add a vertical line at the mean of each group. But geom_vline() uses the same intercept for each panel (i.e. the global mean):
我使用ggplot2来创建直方图面板,我希望能够在每个组的均值上添加一条垂直线。但是geom_vline()对每个面板使用相同的截距(即全局平均值):
require("ggplot2")
# setup some sample data
N <- 1000
cat1 <- sample(c("a","b","c"), N, replace=T)
cat2 <- sample(c("x","y","z"), N, replace=T)
val <- rnorm(N) + as.numeric(factor(cat1)) + as.numeric(factor(cat2))
df <- data.frame(cat1, cat2, val)
# draws a single histogram with vline at mean
qplot(val, data=df, geom="histogram", binwidth=0.2) +
geom_vline(xintercept=mean(val), color="red")
# draws panel of histograms with vlines at global mean
qplot(val, data=df, geom="histogram", binwidth=0.2, facets=cat1~cat2) +
geom_vline(xintercept=mean(val), color="red")
How can I get it to use each panel's group mean as the x-intercept? (Bonus points if you can also add a text label by the line with the value of the mean.)
我怎么能让它用每个面板的组均值作为x轴截距?(如果您还可以在一行中添加一个带有平均值的文本标签,则可获得加分。)
2 个解决方案
#1
9
One way is to construct the data.frame with the mean values before hand.
一种方法是用手边的平均值构造data.frame。
library(reshape)
dfs <- recast(data.frame(cat1, cat2, val), cat1+cat2~variable, fun.aggregate=mean)
qplot(val, data=df, geom="histogram", binwidth=0.2, facets=cat1~cat2) + geom_vline(data=dfs, aes(xintercept=val), colour="red") + geom_text(data=dfs, aes(x=val+1, y=1, label=round(val,1)), size=4, colour="red")
#2
13
I guess this is a reworking of @eduardo's really, but in one line.
我猜这是对@eduardo的作品的改编,但在一行中。
ggplot(df) + geom_histogram(mapping=aes(x=val))
+ geom_vline(data=aggregate(df[3], df[c(1,2)], mean),
mapping=aes(xintercept=val), color="red")
+ facet_grid(cat1~cat2)
alt text http://www.imagechicken.com/uploads/1264782634003683000.png
alt文本http://www.imagechicken.com/uploads/1264782634003683000.png
or using plyr
(require(plyr)
a package by the author of ggplot, Hadley):
或者使用plyr(要求(plyr)一个由ggplot作者Hadley编写的包):
ggplot(df) + geom_histogram(mapping=aes(x=val))
+ geom_vline(data=ddply(df, cat1~cat2, numcolwise(mean)),
mapping=aes(xintercept=val), color="red")
+ facet_grid(cat1~cat2)
It seems unsatisfying that vline isn't cut on the facets, I'm not sure why.
我不知道为什么vline没有在切面上切割,这似乎不令人满意。
#1
9
One way is to construct the data.frame with the mean values before hand.
一种方法是用手边的平均值构造data.frame。
library(reshape)
dfs <- recast(data.frame(cat1, cat2, val), cat1+cat2~variable, fun.aggregate=mean)
qplot(val, data=df, geom="histogram", binwidth=0.2, facets=cat1~cat2) + geom_vline(data=dfs, aes(xintercept=val), colour="red") + geom_text(data=dfs, aes(x=val+1, y=1, label=round(val,1)), size=4, colour="red")
#2
13
I guess this is a reworking of @eduardo's really, but in one line.
我猜这是对@eduardo的作品的改编,但在一行中。
ggplot(df) + geom_histogram(mapping=aes(x=val))
+ geom_vline(data=aggregate(df[3], df[c(1,2)], mean),
mapping=aes(xintercept=val), color="red")
+ facet_grid(cat1~cat2)
alt text http://www.imagechicken.com/uploads/1264782634003683000.png
alt文本http://www.imagechicken.com/uploads/1264782634003683000.png
or using plyr
(require(plyr)
a package by the author of ggplot, Hadley):
或者使用plyr(要求(plyr)一个由ggplot作者Hadley编写的包):
ggplot(df) + geom_histogram(mapping=aes(x=val))
+ geom_vline(data=ddply(df, cat1~cat2, numcolwise(mean)),
mapping=aes(xintercept=val), color="red")
+ facet_grid(cat1~cat2)
It seems unsatisfying that vline isn't cut on the facets, I'm not sure why.
我不知道为什么vline没有在切面上切割,这似乎不令人满意。