web-dev-qa-db-fra.com

ggplot2: trier une parcelle

J'ai un data.frame, qui est trié du plus haut au plus bas. Par exemple: 

x <- structure(list(variable = structure(c(10L, 6L, 3L, 4L, 2L, 8L, 
9L, 5L, 1L, 7L), .Label = c("a", "b", "c", "d", "e", "f", "g", 
"h", "i", "j"), class = c("ordered", "factor")), value = c(0.990683229813665, 
0.975155279503106, 0.928571428571429, 0.807453416149068, 0.717391304347826, 
0.388198757763975, 0.357142857142857, 0.201863354037267, 0.173913043478261, 
0.0496894409937888)), .Names = c("variable", "value"), row.names = c(10L, 
6L, 3L, 4L, 2L, 8L, 9L, 5L, 1L, 7L), class = "data.frame")

ggplot(x, aes(x=variable,y=value)) + geom_bar(stat="identity") + 
 scale_y_continuous("",label=scales::percent) + coord_flip() 

Maintenant, les données sont belles et triées, mais lorsque je trace, elles sont triées par facteur. C'est agaçant, comment puis-je résoudre ce problème?

48
Brandon Bertelsen

Voici quelques façons.

Le premier ordonnera les choses en fonction de l'ordre vu dans le bloc de données:

x$variable <- factor(x$variable, levels=unique(as.character(x$variable)) )

La deuxième commande les niveaux en fonction d'une autre variable (valeur dans ce cas):

x <- transform(x, variable=reorder(variable, -value) ) 
56
Greg Snow

Cela semble être ce que vous cherchez:

g <- ggplot(x, aes(reorder(variable, value), value))
g + geom_bar() + scale_y_continuous(formatter="percent") + coord_flip()

La fonction reorder() réorganisera vos éléments d'axe x en fonction de la value de variable.

69
djmuseR

J'ai récemment eu du mal à résoudre un problème connexe, dont nous avons longuement discuté ici: Ordre des entrées de légende dans les diagrammes à barres ggplot2 avec coord_flip () .

En l'occurrence, la raison pour laquelle j'ai eu du mal à expliquer clairement mon problème, impliquait la relation entre (l'ordre des) facteurs et coord_flip (), comme cela semble être le cas ici.

J'obtiens le résultat souhaité en ajoutant + xlim(rev(levels(x$variable))) à l'instruction ggplot:

ggplot(x, aes(x=variable,y=value)) + geom_bar() + 
scale_y_continuous("",formatter="percent") + coord_flip() 
+  xlim(rev(levels(x$variable)))

Cela inverse l'ordre des facteurs tels qu'ils se trouvent dans le bloc de données d'origine sur l'axe des x, qui deviendra l'axe des y avec coord_flip (). Notez que dans cet exemple particulier, la variable se trouve également dans l'ordre alphabétique, mais la spécification d'un ordre arbitraire de niveaux dans xlim() devrait fonctionner en général.

9
MatteoS

Vous devez transformer le facteur x en un facteur ordered avec l'ordre souhaité, par exemple

x <- data.frame("variable"=letters[1:5], "value"=rnorm(5)) ## example data
x <- x[with(x,order(-value)), ] ## Sorting
x$variable <- ordered(x$variable, levels=levels(x$variable)[unclass(x$variable)])

ggplot(x, aes(x=variable,y=value)) + geom_bar() +
   scale_y_continuous("",formatter="percent") + coord_flip()

Je ne connais pas de meilleur moyen de procéder à la commande. Ce que j'ai là ne fonctionnera que s'il n'y a pas de niveaux en double pour x$variable.

2
zwol

Je ne sais pas pourquoi cette question a été rouverte mais voici une option tidyverse.

x %>% 
  arrange(desc(value)) %>%
  mutate(variable=fct_reorder(variable,value)) %>% 
ggplot(aes(variable,value,fill=variable)) + geom_bar(stat="identity") + 
  scale_y_continuous("",label=scales::percent) + coord_flip() 
1
NelsonGon