web-dev-qa-db-fra.com

Changer l'ordre d'une échelle x discrète

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?

123
lokheart

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

ggplot of the cars dataset with factor levels automatically determined

# 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()

ggplot of the cars dataset with factor levels reordered manually

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

ggplot of the cars dataset with factor levels reordered using the reorder function

97
Richie Cotton

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

enter image description here

181
Yuriy Petrovskiy

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!

38
James

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

enter image description here

26
jazzurro

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.

2
eflores89