Modifier l'ordre d'une échelle x discrète
Je fais un diagramme à barres esquivé en utilisant ggplot avec une échelle X discrète, les axes x sont maintenant disposés dans l'ordre alphabétique, mais je dois le réorganiser pour qu'il soit ordonné par la valeur de l'axe y (c'est-à-dire que la barre la plus haute sera positionnée sur la gauche).
J'ai essayé order ou sort, mais le résultat est de trier l'axe des x, mais pas les barres respectivement.
Qu'ai-je fait de mal?
5 réponses
Essayez de régler manuellement les niveaux du facteur sur l'axe des abscisses. 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 façon 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 était d'utiliser vector avec des catégories dans l'ordre dont j'ai besoin en tant que 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")
Modifier:
Pour avoir la barre la plus haute à gauche, il faut utiliser un peu d'un kludge:
qplot(reorder(factor(cyl),factor(cyl),function(x) length(x)*-1),
data=mtcars,geom="bar")
Je m'attendrais à ce que cela ait aussi des hauteurs négatives, mais ce n'est pas le cas, donc ça marche!
Hadley a développé un paquet appelé forcats
. Ce paquet rend la tâche beaucoup plus facile. Vous pouvez exploiter fct_infreq()
lorsque vous souhaitez modifier l'ordre de l'axe des abscisses par la fréquence d'un facteur. Dans le cas de la mtcars
exemple dans ce post, vous souhaitez réorganiser les niveaux de cyl
par la fréquence de chaque niveau. Le niveau qui apparaît le plus souvent reste sur le côté gauche. Tout ce dont vous avez besoin est le fct_infreq()
.
library(ggplot2)
library(forcats)
ggplot(mtcars, aes(fct_infreq(factor(cyl)))) +
geom_bar() +
labs(x = "cyl")
Si vous voulez aller dans l'autre sens, vous pouvez utiliser fct_rev()
avec fct_infreq()
.
ggplot(mtcars, aes(fct_rev(fct_infreq(factor(cyl))))) +
geom_bar() +
labs(x = "cyl")
Je me rends compte 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 voir, la fonction order_axis
crée un autre dataframe avec une nouvelle colonne nommée la même mais avec un _o
à la fin. Cette nouvelle colonne a des niveaux dans l'ordre croissant, donc ggplot2 trace automatiquement dans cet ordre.
Ceci est quelque peu limité (ne fonctionne que pour le caractère ou le facteur et des combinaisons numériques de colonnes et dans l'ordre croissant) mais je trouve toujours très utile pour tracer sur la route.