2010-11-22 23 views
19
library(ggplot2) 

orderX <- c("A" = 1, "B" = 2, "C" = 3) 
y <- rnorm(20) 
x <- as.character(1:20) 
group <- c(rep("A", 5), rep("B", 7), rep("C", 5), rep("A", 3)) 
df <- data.frame(x, y, group) 
df$lvls <- as.numeric(orderX[df$group]) 

ggplot(data = df, aes(x=reorder(df$x, df$lvls), y=y)) + 
geom_point(aes(colour = group)) + 
geom_line(stat = "hline", yintercept = "mean", aes(colour = group)) 

Quiero crear un gráfico de la siguiente manera: graph with averages for each groupggplot2: añadir la línea de media por grupo

Esto funciona, cuando no es necesario reordenar los valores de X, sin embargo, cuando lo haga use reordenar, ya no funciona.

+0

creo que el uso por parte de reordenación se confunde aquí, ya simplemente reordenará X, no grupos o Y. Esto trazará la x incorrecta con la y incorrecta. –

+0

A menos que X no signifique nada más que índice, en cuyo caso, no lo use en el gráfico (¿usar jitter en su lugar?) –

+0

Entonces mi uso de reorden es erróneo. En mis datos reales, los valores en x son etiquetas para cada medida individual, que sí quiero ver. El orden de estas etiquetas dentro de los grupos no importa. – wligtenberg

Respuesta

3

Como de g gplot2 2.x este enfoque lamentablemente está roto.

El siguiente código proporciona exactamente lo que quería, con algunos cálculos adicionales en la delantera:

library(ggplot2) 
library(data.table) 

orderX <- c("A" = 1, "B" = 2, "C" = 3) 
y <- rnorm(20) 
x <- as.character(1:20) 
group <- c(rep("A", 5), rep("B", 7), rep("C", 5), rep("A", 3)) 
dt <- data.table(x, y, group) 
dt[, lvls := as.numeric(orderX[group])] 
dt[, average := mean(y), by = group] 
dt[, x := reorder(x, lvls)] 
dt[, xbegin := names(which(attr(dt$x, "scores") == unique(lvls)))[1], by = group] 
dt[, xend := names(which(attr(dt$x, "scores") == unique(lvls)))[length(x)], by = group] 

ggplot(data = dt, aes(x=x, y=y)) + 
    geom_point(aes(colour = group)) + 
    facet_grid(.~group,space="free",scales="free_x") + 
    geom_segment(aes(x = xbegin, xend = xend, y = average, yend = average, group = group, colour = group)) 

La imagen resultante:

enter image description here

+3

No estoy seguro de si esto ayudará en su situación exacta, pero la La nueva solución que encontré con ggplot2 v2.1.0 para un problema similar es 'stat_summary (fun.y =" mean ", fun.ymin =" mean ", fun.ymax =" mean ", size = 0.3, geom =" crossbar ") '. –

+0

Lo intenté, eso crea líneas horizontales por artículo en el eje x. La razón para eso es que el eje x es discreto. – wligtenberg

16

De su pregunta, no es esto df$x es relevante para sus datos en absoluto, especialmente si puede reordenarlo. ¿Qué hay de simplemente usando group como x, y jitter la posición real x para separar los puntos:

ggplot(data=df, aes(x=group,y=y,color=group)) + geom_point() + 
geom_jitter(position = position_jitter(width = 0.4)) + 
geom_errorbar(stat = "hline", yintercept = "mean", 
    width=0.8,aes(ymax=..y..,ymin=..y..)) 

he utilizado errorbar en lugar de h_line (y colapsado el ymax y ymin a y) desde hline es compleja. Si alguien tiene una mejor solución para esa parte, me encantaría verla.

alt text


actualización

Si desea conservar el orden de X, intente esta solución (con X modificada)

df$x = factor(df$x) 

ggplot(data = df, aes(x, y, group=group)) + 
facet_grid(.~group,space="free",scales="free_x") + 
geom_point() + 
geom_line(stat = "hline", yintercept = "mean") 

alt text

+0

Esto es de hecho casi lo que quiero, sin embargo, quiero poder ver los valores x originales en la escala x. – wligtenberg

+0

Cuando haces el reordenamiento anterior, tus datos se mezclan. Debe ordenar el marco de datos original, no solo los valores x. ¿Deseas que los valores x estén intercalados en tu gráfico? Si lo son, ¿dónde quieres ubicar los valores promedio? –

+0

¿dónde encontraste la documentación en geom_line (stat = "hline", yintercept = "mean")? Eso es genial y no lo he visto antes. –

Cuestiones relacionadas