2009-11-12 9 views
9

J'ai un dataframe df.all et je suis tracé dans un terrain de bar avec ggplot2 en utilisant le code ci-dessous. Je voudrais faire en sorte que l'ordre des barres esquivées soit inversé. C'est-à-dire, de sorte que les barres étiquetées "Singulier" viennent avant les barres étiquetées "Pluriel".Changer l'ordre des barres esquivé dans ggplot2 barplot

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

J'ai essayé de faire levels(df.all$number) = c("S", "P") penser que peut-être ggplot utilise l'ordre des niveaux de décider tracer l'ordre, mais cela ne fonctionne pas. Je ne suis pas sûr de quoi d'autre essayer. Des idées?

Le contenu de df.all, dans le cas où il est utile:

> 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

Je pense que c'est un bug dans ggplot2 - il devrait respecter l'ordre des données (ou l'ordre esthétique) en esquivant les barres mais je pense que non. Difficile à dire sans un exemple reproductible. – hadley

+0

Hadley, puis-je vous envoyer des données et du code? Je suis très bon à reproduire cette erreur :) – pealco

Répondre

4

Hadley a fourni une solution. Voici une réplication du problème et de la solution.

Le but est d'obtenir les barres étiquetés « S » à venir avant que les barres étiquetés « P ». Cela ne se produit pas par défaut car R commande les niveaux par ordre alphabétique.

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

Comme Hadley a commenté dans une autre réponse, "vous devez modifier l'ordre sur la base des variables x, pas la variable y". Bien que je ne sois pas sûr pourquoi cela fonctionne.

Pour inverser l'ordre des facteurs dans cet exemple, vous pouvez convertir le facteur numérique et multiplier par -1.

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

Le tracé à nouveau montre que ses travaux.

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

Je voudrais encore si plus d'explications sur les raisons df <- with(df, df[order(gram, -as.numeric(number)), ]) œuvres.

4

Je pense que df.all$number a besoin d'être un facteur commandé. Essayez df.all$number <- ordered(df.all$number)

+1

Oui et alors vous pouvez changer manuellement la commande en utilisant l'option 'levels = c()' –

4

Dans certains cas, je ne pense pas que ce soit 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")) 

ordre dans empilés:
g + geom_bar (stat = "identité", position = "pile") enter image description here

ordre incorrect Dodge:

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

enter image description here

essayons d'inverser l'ordre 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") 

pas de dés

essayons de réorganiser la trame de données

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

0

vraiment changer les niveaux de facteur ne changez l'ordre des barres évitées! Piège commun: les couleurs restent toujours à une certaine position, donc en jetant un coup d'œil rapide, on dirait que l'ordre n'a pas changé. Mais si vous regardez les valeurs, vous verrez que l'ordre a vraiment changé.

Modifier: Ma précédente réponse ci-dessous ne change que l'ordre des couleurs donné aux barres. Ceci est toujours utile, car nous pouvons souvent vouloir inverser le schéma de couleurs en même temps que changer l'ordre des barres:

J'utilisais scale_fill_manual parce que je voulais remplir manuellement les couleurs de mes barres.

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

Passé 5 heures à bricoler en changeant les niveaux de facteur et en organisant le dataframe, cela aide quelqu'un!

Questions connexes