Je réalise un diagramme à barres en utilisant ggplot avec une échelle x discrète, les axes x sont maintenant classés par ordre alphabétique, mais je dois le réorganiser de manière à ce qu'il soit classé par la valeur de l'axe des y (c'est-à-dire que la barre la plus haute être positionné à gauche).
J'ai essayé l'ordre ou le tri, mais le résultat est de trier l'axe des x, mais pas les barres, respectivement.
Qu'est ce que j'ai mal fait?
Essayez de définir manuellement les niveaux du facteur sur l’axe des x. Par exemple:
library(ggplot2)
# Automatic levels
ggplot(mtcars, aes(factor(cyl))) + geom_bar()
# Manual levels
cyl_table <- table(mtcars$cyl)
cyl_levels <- names(cyl_table)[order(cyl_table)]
mtcars$cyl2 <- factor(mtcars$cyl, levels = cyl_levels)
# Just to be clear, the above line is no different than:
# mtcars$cyl2 <- factor(mtcars$cyl, levels = c("6","4","8"))
# You can manually set the levels in whatever order you please.
ggplot(mtcars, aes(cyl2)) + geom_bar()
Comme James l'a souligné dans sa réponse, reorder
est la manière idiomatique de réorganiser les niveaux de facteurs.
mtcars$cyl3 <- with(mtcars, reorder(cyl, cyl, function(x) -length(x)))
ggplot(mtcars, aes(cyl3)) + geom_bar()
La meilleure façon pour moi consistait à utiliser des vecteurs avec des catégories dans l’ordre dont j’avais besoin comme paramètre limits
à scale_x_discrete
. Je pense que c'est une solution assez simple et directe.
ggplot(mtcars, aes(factor(cyl))) +
geom_bar() +
scale_x_discrete(limits=c(8,4,6))
Vous pouvez utiliser reorder
:
qplot(reorder(factor(cyl),factor(cyl),length),data=mtcars,geom="bar")
Edit:
Pour avoir la barre la plus haute à gauche, vous devez utiliser un peu de kludge:
qplot(reorder(factor(cyl),factor(cyl),function(x) length(x)*-1),
data=mtcars,geom="bar")
Je m'attendrais à ce que cela ait également des hauteurs négatives, mais ce n'est pas le cas, donc ça marche!
Hadley a développé un paquet nommé forcats
. Ce paquet rend la tâche tellement plus facile. Vous pouvez exploiter fct_infreq()
lorsque vous souhaitez modifier l'ordre des abscisses en fonction de la fréquence d'un facteur. Dans le cas de l'exemple mtcars
de cet article, vous souhaitez réorganiser les niveaux de cyl
en fonction de la fréquence de chaque niveau. Le niveau qui apparaît le plus souvent reste du côté gauche. Tout ce dont vous avez besoin est la fct_infreq()
.
library(ggplot2)
library(forcats)
ggplot(mtcars, aes(fct_infreq(factor(cyl)))) +
geom_bar() +
labs(x = "cyl")
Si vous voulez faire l'inverse, vous pouvez utiliser fct_rev()
avec fct_infreq()
.
ggplot(mtcars, aes(fct_rev(fct_infreq(factor(cyl))))) +
geom_bar() +
labs(x = "cyl")
Je réalise que c'est vieux, mais peut-être que cette fonction que j'ai créée est utile à quelqu'un:
order_axis<-function(data, axis, column)
{
# for interactivity with ggplot2
arguments <- as.list(match.call())
col <- eval(arguments$column, data)
ax <- eval(arguments$axis, data)
# evaluated factors
a<-reorder(with(data, ax),
with(data, col))
#new_data
df<-cbind.data.frame(data)
# define new var
within(df,
do.call("<-",list(paste0(as.character(arguments$axis),"_o"), a)))
}
Maintenant, avec cette fonction, vous pouvez tracer interactivement avec ggplot2, comme ceci:
ggplot(order_axis(df, AXIS_X, COLUMN_Y),
aes(x = AXIS_X_o, y = COLUMN_Y)) +
geom_bar(stat = "identity")
Comme on peut le constater, la fonction order_axis
crée une autre trame de données avec une nouvelle colonne portant le même nom, mais avec un _o
à la fin. Cette nouvelle colonne a des niveaux dans l'ordre croissant, ainsi ggplot2 trace automatiquement dans cet ordre.
Ceci est quelque peu limité (ne fonctionne que pour les combinaisons de caractères ou de facteurs et numériques de colonnes et par ordre croissant) mais je le trouve toujours très utile pour tracer sur le pouce.