2012-07-02 12 views
15
df <- structure(list(ID = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 
5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L), .Label = c("1", 
"2", "3", "4", "5", "6", "7"), class = "factor"), TYPE = structure(c(1L, 
2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 
1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 
5L, 6L, 1L, 2L, 3L), .Label = c("1", "2", "3", "4", "5", "6", 
"7", "8"), class = "factor"), TIME = structure(c(2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 
1L, 1L, 1L), .Label = c("1", "5", "15"), class = "factor"), VAL = c(0.937377670081332, 
0.522220720537007, 0.278690102742985, 0.967633064137772, 0.116124767344445, 
0.0544306698720902, 0.470229141646996, 0.62017166428268, 0.195459847105667, 
0.732876230962574, 0.996336271753535, 0.983087373664603, 0.666449476964772, 
0.291554537601769, 0.167933790013194, 0.860138458199799, 0.172361251665279, 
0.833266809117049, 0.620465772924945, 0.786503327777609, 0.761877260869369, 
0.425386636285111, 0.612077651312575, 0.178726130630821, 0.528709076810628, 
0.492527724476531, 0.472576208412647, 0.0702785139437765, 0.696220921119675, 
0.230852259788662, 0.359884874196723, 0.518227979075164, 0.259466265095398, 
0.149970305617899, 0.00682218233123422, 0.463400925742462, 0.924704828299582, 
0.229068386601284)), .Names = c("ID", "TYPE", "TIME", "VAL"), row.names = c(NA, 
-38L), class = "data.frame") 

Si creo la figura siguiente:ggplot2: Caída de los factores utilizados en un diagrama de barras facetas pero no tienen diferentes anchos de las barras entre las facetas

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_wrap(~ TIME, ncol=1) + 
    geom_bar(position="stack") + 
    coord_flip() 

plot

que luego decido que lo ideal sería como para suprimir cualquier factor que se muestra en una faceta donde no tienen ningún dato. Me he referido varias preguntas y respuestas que dicen que el método scale="free" es el camino a seguir (en contraposición a drop=TRUE cual se reduciría facetas vacíos correspondientes a valores no utilizados en TIME), así que la próxima:

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_wrap(~TIME, ncol=1, scale="free") + 
    geom_bar(position="stack") + 
    coord_flip() 

plot

Mi pregunta es cómo evitar el cambio de escala de las barras que se produce para la faceta que tiene 4 barras frente a la faceta con 3 barras. El efecto es sutil en este ejemplo artificial, mucho peor con mis datos reales. La salida ideal tendría la faceta inferior con los factores ID 1,4, y 6 en el eje vertical con barras que tienen el mismo ancho que la faceta superior, y así se reduciría la dimensión vertical general de la faceta.

puntos de bonificación si usted me puede ayudar con eso los recuentos se apilan en lugar de los valores numéricos (fijar ahora)

actualización Recompensa:

Como se mencionó en mi seguimiento question se ve como una solución mejor podría implicar el uso de ggplot_build y ggplot_table y modificar el objeto tablable. Estoy bastante seguro de que podría resolverlo con el tiempo, pero espero que una recompensa motive a otra persona para que me ayude. Koshke ha publicado algunos ejemplos de this.

+2

Para el punto de bonificación: tal vez una minúscula 'y' en lugar de' y', junto con 'stat = "identidad"'? – joran

+0

¡Gracias! Sin embargo, la identidad arg no era necesaria. –

+0

también existe el argumento 'space = 'free'' para' facet_wrap' que podría ser lo que estás buscando. Hubo una pregunta perfecta con respecto a esto antes, pero el usuario lo borró ... – Justin

Respuesta

14

¿Qué tal esto:

df$w <- 0.9 
df$w[df$TIME == 5] <- 0.9 * 3/4 
ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_wrap(~TIME, ncol=1, scale="free") + 
    geom_bar(position="stack",aes(width = w),stat = "identity") + 
    coord_flip() 

enter image description here

No estoy seguro si me dieron la aritmética allí mismo, pero se entiende la idea.

+0

¡listo! Visualmente eso se ve bien y estoy siguiendo lo que hiciste. El problema que veo es que el ancho de las barras se ajusta manualmente para compensar la diferente cantidad de factores entre las facetas. Sin embargo, esto parece problemático una vez que lo diferente es mucho mayor, por ejemplo, ¿qué pasaría si sus 7 facetas vs. 2? En este caso, me estoy imaginando que la faceta inferior tendría dos barras con el ancho correcto, pero una gran cantidad de espacios en blanco. Esto consigue el deseo de ajustar el tamaño total de la faceta, pero esto parece imposible. –

+0

@ mindless.panda Sí, parece que estás buscando un argumento de 'espacio' pero para 'facet_wrap' que no creo que exista (todavía). – joran

+0

Gracias - con ajustes manuales esto hará por ahora, con suerte 'facet_wrap' obtiene' espacio' así como 'etiquetadora'. Para la perfección, probablemente generaría trazados separados y los alinearía (a través de la cuadrícula o el paisaje de impresión, supongo, ya que en realidad nunca lo hice). –

10

Si estás bien con barras verticales, facet_grid funciona perfectamente:

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_grid(.~TIME, scale="free_x", space = "free_x") + 
    geom_bar(position="stack") 

enter image description here

Para ir un poco más lejos, a continuación, puede girar todos los elementos de la tabla. Ahora que tiene lo que desea si gira la cabeza en un 90 ° :-)

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_grid(.~TIME, scale="free_x", space = "free_x") + 
    geom_bar(position="stack") + 
    opts(legend.text = theme_text(angle=90), 
     legend.title = theme_text(angle=90), 
     strip.text.x = theme_text(angle=90), 
     axis.text.x = theme_text(angle=90), 
     axis.text.y = theme_text(angle=90), 
     axis.title.x = theme_text(angle=90) 
     ) 

enter image description here

2

lo largo de cinco años desde la pregunta original, así que pensé que debería proporcionar una más hasta la fecha y la versión más limpia de hacer estoEsto sigue en líneas generales el consejo dado aquí: http://ggplot2.tidyverse.org/reference/facet_grid.html

Los dos argumentos clave son space="free_y" que permite que la altura de cada panel sea proporcional a la longitud de la escala y scales="free_y" que permite que las escalas para varían para cada columna.

coord_flip() permite trazar las barras en sentido horizontal, y como preferencia personal la etiqueta a la faceta se gira dentro de las opciones theme.

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    geom_bar(stat="identity") + 
    coord_flip() + 
    facet_grid(TIME~., scales = "free_y", space = "free_y") + 
    theme(strip.text.y = element_text(angle = 0)) 

enter image description here

Cuestiones relacionadas