Gráfico de barras ggplot con orden de categorías dependiente de las facetas

He visto muchas preguntas (a menudo vinculadas a Ordenar barras en ggplot2 gráfico de barras ) sobre cómo (re) ordenar categorías en un diagtwig de barras.

Lo que busco es solo un toque diferente, pero no he encontrado una buena manera de hacerlo: tengo un gráfico de barras multifacético, y quiero ordenar el eje x para cada faceta de forma independiente, de acuerdo con otra variable ( en mi caso, esa variable es solo el valor y en sí mismo, es decir, solo quiero que las barras vayan aumentando en longitud en cada faceta).

Ejemplo simple, siguiendo, por ejemplo, barras de orden en el gráfico de barras ggplot2 :

df <- data.frame(name=c('foo','bar','foo','bar'),period=c('old','old','recent','recent'),val=c(1.23,2.17,4.15,3.65)) p = ggplot(data = df, aes(x = reorder(name, val), y = val)) p = p + geom_bar(stat='identity') p = p + facet_grid(~period) p 

Lo que obtenemos es lo siguiente: enter image description here

Mientras que lo que quiero es: enter image description here

Ok, así que aparte de filosofar, y en caso de que alguien esté interesado, aquí hay un truco feo para hacerlo. La idea es usar tags diferentes (creo que paste(period, name) excepto que reemplazo el período en 0-espacio, 1-espacio, etc. para que no se muestren). Necesito esta ttwig y no quiero organizar grobs ni cosas así, porque me gustaría compartir una leyenda común, etc.

El ejemplo atómico dado anteriormente se convierte en:

 df <- data.frame(name=c('foo','bar','foo','bar'), period=c('old','old','recent','recent'), val=c(1.23,2.17,4.15,3.65), stringsAsFactors=F) df$n = as.numeric(factor(df$period)) df = ddply(df,.(period,name),transform, x=paste(c(rep(' ',n-1), name), collapse='')) df$x = factor(df$x, levels=df[order(df$val), 'x']) p = ggplot(data = df, aes(x = x, y = val)) p = p + geom_bar(stat='identity') p = p + facet_grid(~period, scale='free_x') p 

enter image description here Otro ejemplo, aún un poco tonto pero más cercano a mi caso de uso real, sería:

 df <- ddply(mpg, .(year, manufacturer), summarize, mixmpg = mean(cty+hwy)) df$manufacturer = as.character(df$manufacturer) df$n = as.numeric(factor(df$year)) df = ddply(df, .(year,manufacturer), transform, x=paste(c(rep(' ',n-1), manufacturer), collapse='')) df$x = factor(df$x, levels=df[order(df$mixmpg), 'x']) p = ggplot(data = df, aes(x = x, y = mixmpg)) p = p + geom_bar(stat='identity') p = p + facet_grid(~year, scale='free_x') p = p + theme(axis.text.x=element_text(angle=90,hjust=1,vjust=.5,colour='gray50')) p 

enter image description here Cierra los ojos, piensa en el Imperio y trata de disfrutar.

Esta es una vieja pregunta, pero está siendo utilizada como un objective engañado. Por lo tanto, valdría la pena sugerir una solución que utilice las mejoras recientes del paquete ggplot2 , a saber, el parámetro labels a scale_x_discrete() . Esto evita utilizar niveles duplicados que están en desuso o manipular las tags de factores anteponiendo un número variable de espacios .

Preparar datos

Aquí, el conjunto de datos de mpg se utiliza para tener una comparación con esta respuesta . Para la manipulación de datos, el paquete data.table se usa aquí pero puede usar cualquier paquete que prefiera para este fin.

 library(data.table) # version 1.10.4 library(ggplot2) # version 2.2.1 # aggregate data df <- as.data.table(mpg)[, .(mixmpg = mean(cty + hwy)), by = .(year, manufacturer)] # create dummy var which reflects order when sorted alphabetically df[, ord := sprintf("%02i", frank(df, mixmpg, ties.method = "first"))] 

Crear ttwig

 # `ord` is plotted on x-axis instead of `manufacturer` ggplot(df, aes(x = ord, y = mixmpg)) + # geom_col() is replacement for geom_bar(stat = "identity") geom_col() + # independent x-axis scale in each facet, # drop absent factor levels (actually not required here) facet_wrap(~ year, scales = "free_x", drop = TRUE) + # use named character vector to replace x-axis labels scale_x_discrete(labels = df[, setNames(as.character(manufacturer), ord)]) + # replace x-axis title xlab(NULL) + # rotate x-axis labels theme(axis.text.x = element_text(angle = 90, hjust=1, vjust=.5)) 

enter image description here

Prueba esto, es muy simple (solo ignora las advertencias)

 df <-data.frame(name = c('foo', 'bar', 'foo', 'bar'), period = c('old', 'old', 'recent', 'recent'), val = c(1.23, 2.17, 4.15, 3.65)) d1 <- df[order(df$period, df$val), ] sn <- factor(x = 1:4, labels = d1$name) d1$sn <- sn p <- ggplot(data = d1, aes(x = sn, y = val)) p <- p + geom_bar(stat = 'identity') p <- p + facet_wrap(~ period, scale = 'free_x') p 
    Intereting Posts