2009-11-12 13 views
9

Tengo un dataframe df.all y lo estoy trazando en un diagrama de barras con ggplot2 usando el siguiente código. Me gustaría hacerlo de modo que el orden de las barras esquivas sea invertido. Es decir, de modo que las barras con la etiqueta "Singular" aparecen delante de las barras con la etiqueta "Plural".Cambiando el orden de las barras esquivas en la barra de barras ggplot2

ggplot(df.all, aes(gram, V1, fill=number)) + 
    geom_bar(stat="identity", position="dodge") + 
    scale_x_discrete(labels=c("Grammatical","Ungrammatical")) + 
    scale_y_continuous(formatter="percent", limits=c(0,1)) + 
    facet_grid(. ~ experiment) + 
    scale_fill_hue("Attractor", breaks=c("S","P"), labels=c("Singular","Plural")) 

He intentado hacer levels(df.all$number) = c("S", "P") pensando que tal vez ggplot utiliza el orden de los niveles de decidir para el trazado, pero que no funcionó. No estoy seguro de qué más probar. ¿Algunas ideas?

El contenido de df.all, en caso de que sea útil:

> df.all 
    number gram  experiment  V1 
1  S G BERIMBAU_AGR_A 0.8133333 
2  S G BERIMBAU_AGR_B 0.8658537 
3  S U BERIMBAU_AGR_A 0.5436242 
4  S U BERIMBAU_AGR_B 0.4597701 
5  P G BERIMBAU_AGR_A 0.8580645 
6  P G BERIMBAU_AGR_B 0.8536585 
7  P U BERIMBAU_AGR_A 0.3087248 
8  P U BERIMBAU_AGR_B 0.3975904 

> str(df.all) 
'data.frame': 8 obs. of 4 variables: 
$ number : Factor w/ 2 levels "S","P": 2 2 2 2 1 1 1 1 
    ..- attr(*, "scores")= num [1:2(1d)] 0 -1 
    .. ..- attr(*, "dimnames")=List of 1 
    .. .. ..$ : chr "P" "S" 
$ gram  : Factor w/ 2 levels "G","U": 1 1 2 2 1 1 2 2 
$ experiment: Factor w/ 4 levels "BERIMBAU_AGR_A",..: 1 4 1 4 1 4 1 4 
$ V1  : num 0.813 0.866 0.544 0.46 0.858 ... 
+3

Creo que esto es un error en ggplot2 - debe respetar el orden de los datos (o el orden estético) al esquivar las barras, pero creo que no. Difícil de decir sin un ejemplo reproducible. – hadley

+0

Hadley, ¿puedo enviarle algunos datos y códigos? Soy muy bueno para reproducir este error :) – pealco

Respuesta

4

Hadley ha proporcionado una solución. Aquí hay una réplica del problema y la solución.

El objetivo es que las barras con la etiqueta "S" estén antes que las barras con la etiqueta "P". Esto no ocurre de manera predeterminada porque R ordena los niveles alfabéticamente.

df <- read.csv("http://pealco.net/code/ggplot_dodge/df.txt") 
ggplot(df, aes(gram, V1, fill=number)) 
    + geom_bar(stat="identity", position="dodge") 

alt text http://pealco.net/code/ggplot_dodge/wrongorder.png

Como Hadley comentado en otra respuesta, "necesita reordenar basado en las variables x, no la variable". Aunque no estoy seguro de por qué esto funciona.

Para invertir el orden de los factores en este ejemplo, puede convertir el factor en numérico y multiplicar por -1.

df <- with(df, df[order(gram, -as.numeric(number)), ]) 

Trazando de nuevo muestra que sus obras.

alt text http://pealco.net/code/ggplot_dodge/rightorder.png

todavía me gustaría por lo que más explicación sobre por qué df <- with(df, df[order(gram, -as.numeric(number)), ]) obras.

4

creo df.all$number tiene que ser un factor de pedido. Pruebe df.all$number <- ordered(df.all$number)

+1

Sí y luego puedes cambiar manualmente el orden usando la opción 'levels = c()' –

4

En algunos casos no creo que esto es posible:

layerCake<-data.frame(group=c(rep("normal",4),rep("tumor",4)), 
         class=factor(rep(c("exon","intron","intergenic","unmapped"),2),levels=rev(c("exon","intron","intergenic","unmapped")),ordered=TRUE), 
         fraction=c(.02,.25,.50,.23,.015,.20,.555,.23) 
) 
layerCake[layerCake$group=='normal',"reads"]<-130948403*layerCake[layerCake$group=='normal',"fraction"] 
layerCake[layerCake$group=='tumor',"reads"]<-200948403*layerCake[layerCake$group=='tumor',"fraction"] 
g<-ggplot(layerCake, aes(x=factor(group),y=reads, fill=factor(class),order = as.numeric(class)))+xlab("Group")+scale_fill_discrete(name="Anno Class",breaks=c("exon","intron","intergenic","unmapped")) 

orden correcto en apilada:
g + geom_bar (STAT = "identidad", la posición = "pila") enter image description here

orden incorrecto en dodge:

g+geom_bar(stat="identity",position="dodge") 

enter image description here

vamos a tratar de revertir el orden en ggplot:

g<-ggplot(lc, aes(x=factor(group),y=reads, fill=factor(class),order = -as.numeric(class)))+xlab("Group")+scale_fill_discrete(name="Anno Class",breaks=c("exon","intron","intergenic","unmapped")) 
g+geom_bar(stat="identity",position="dodge") 

no dados

vamos a tratar de cambiar el orden de la trama de datos

lc <- with(lc, lc[order(-as.numeric(class)), ]) 
g<-ggplot(lc, aes(x=factor(group),y=reads, fill=factor(class),order = -as.numeric(class)))+xlab("Group")+scale_fill_discrete(name="Anno Class",breaks=c("exon","intron","intergenic","unmapped")) 
g+geom_bar(stat="identity",position="dodge") 

nop

0

Cambio de los niveles de factor realmente tiene cambia el orden de las barras esquivas! Una trampa común: los colores aún se mantienen en cierta posición, por lo que echar un rápido vistazo hace que parezca que el orden no ha cambiado. Pero si miras los valores, verás que el orden realmente ha cambiado.

Editar: Mi respuesta anterior a continuación solo cambia el orden del esquema de color dado a las barras. Esto sigue siendo útil, ya que a menudo podemos invertir el esquema de color al mismo tiempo que cambiamos el orden de las barras:

Estaba usando scale_fill_manual porque quería llenar manualmente los colores de mis barras.

ggplot(data, aes_string(x = "countries", y = "population", fill = "agegroups")) + 
scale_fill_manual(values = CustomColorFunction(), limits = (levels(data$agegroups))) 

Pasé 5 horas jugando con cambiar los niveles de factor y organizar el marco de datos. Espero que esto ayude a alguien.

Cuestiones relacionadas