Adicionar uma linha vertical com intercepção diferente para cada painel em ggplot2
-
10-07-2019 - |
Pergunta
Eu estou usando ggplot2 para criar painéis de histogramas, e eu gostaria de ser capaz de adicionar uma linha vertical no meio de cada grupo. Mas geom_vline () usa o mesmo interceptação para cada painel (ou seja, a média global):
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")
Como posso obtê-lo para usar média do grupo de cada painel como a intersecção de x? (Os pontos de bónus se você também pode adicionar um rótulo de texto pela linha com o valor da média.)
Solução
Uma maneira é a de construir o data.frame com os valores médios antes da mão.
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")
Outras dicas
Eu acho que essa é uma reformulação da @ eduardo é realmente, mas em uma linha.
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 texto http://www.imagechicken.com/uploads/1264782634003683000.png
ou usando plyr
(require(plyr)
um pacote pelo autor do 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)
Parece insatisfatório que vline não é cortado nas facetas, eu não sei por que.