Changing the order of dodged bars in ggplot2 barplot

I think df.all$number needs to be an ordered factor. Try df.all$number <- ordered(df.all$number)


Hadley has provided a solution. Here's a replication of the problem and the solution.

The goal is to get the bars labeled "S" to come before the bars labeled "P". This doesn't happen by default because R orders levels alphabetically.

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

As Hadley commented in another answer, "you need to reorder based on the x variables, not the y variable". Though I'm not sure why this works.

To flip the order of the factors in this example, you can convert the factor to numeric and multiply by -1.

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

I'd still like some more explanation about why df <- with(df, df[order(gram, -as.numeric(number)), ]) works.


In some cases I don't think this is possible:

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"))

correct order in stacked:
g+geom_bar(stat="identity",position="stack") enter image description here

incorrect order in dodge:

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

enter image description here

let's try to reverse the order in 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 dice

let's try to reorder the data frame

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")

nope

Tags:

R

Ggplot2