133 votes

Fixer l'ordre des facettes dans ggplot

Données :

df <- data.frame(
    type   = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"), 
    size   = c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"),
    amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)

J'ai besoin de tracer un graphique à barres des données ci-dessus en utilisant ggplot (axe x -> type , axe y -> amount , groupe par size ). Lorsque j'utilise le code suivant, je n'obtiens pas la variable type et ainsi que size dans l'ordre indiqué dans les données. Veuillez voir la figure. J'ai utilisé le code suivant pour cela.

 ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) + 
  geom_col(width=0.5, position = position_dodge(width=0.6)) + 
  facet_grid(.~size) + 
  theme_bw() + 
  scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"), 
                    labels = c("T", "F", "P"))

enter image description here .

Pour résoudre le problème de l'ordre, j'ai utilisé une méthode factorielle pour la variable "type" en utilisant ce qui suit. Veuillez également consulter la figure.

temp$new = factor(temp$type, levels=c("T","F","P"), labels=c("T","F","P")) 

enter image description here

Cependant, maintenant je ne sais pas comment fixer l'ordre pour la variable size . Il devrait être de 50%, 100%. 150%, et 200%.

183voto

Harpal Points 1834

Faites de votre taille un facteur dans votre dataframe en :

temp$size_f = factor(temp$size, levels=c('50%','100%','150%','200%'))

Ensuite, changez le facet_grid(.~size) a facet_grid(.~size_f)

Puis tracer : enter image description here

Les graphiques sont maintenant dans le bon ordre.

35voto

glenn_in_boston Points 223

Il existe plusieurs bonnes solutions.

Similaire à la réponse de Harpal, mais à l'intérieur de la facette, donc ne nécessite pas de modification des données sous-jacentes ni de manipulation préalable du tracé. :

# Change this code:
facet_grid(.~size) + 
# To this code:
facet_grid(~factor(size, levels=c('50%','100%','150%','200%')))

Cette méthode est flexible et peut être mise en œuvre pour n'importe quelle variable, car vous changez l'élément à facettes, sans qu'il soit nécessaire de modifier les données sous-jacentes.

21voto

ibm Points 191

Encore moins de manipulation : facet_grid(~fct_relevel(size,'50%','100%','150%','200%'))

9voto

tim.farkas Points 306

Voici une solution qui maintient les choses dans une chaîne de tuyaux dplyr. Vous triez les données à l'avance, puis vous utilisez mutate_at pour convertir en facteur. J'ai légèrement modifié les données pour montrer comment cette solution peut être appliquée de manière générale, avec des données qui peuvent être triées de manière raisonnable :

# the data
temp <- data.frame(type=rep(c("T", "F", "P"), 4),
                    size=rep(c("50%", "100%", "200%", "150%"), each=3), # cannot sort this
                    size_num = rep(c(.5, 1, 2, 1.5), each=3), # can sort this
                    amount=c(48.4, 48.1, 46.8, 
                             25.9, 26.0, 24.9,
                             20.8, 21.5, 16.5,
                             21.1, 21.4, 20.1))

temp %>% 
  arrange(size_num) %>% # sort
  mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>% # convert to factor

  ggplot() + 
  geom_bar(aes(x = type, y=amount, fill=type), 
           position="dodge", stat="identity") + 
  facet_grid(~ size)

Vous pouvez également appliquer cette solution pour disposer les barres dans les facettes, mais vous ne pouvez choisir qu'un seul ordre préféré :

    temp %>% 
  arrange(size_num) %>%
  mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>%
  arrange(desc(amount)) %>%
  mutate_at(vars(type), funs(factor(., levels=unique(.)))) %>%
  ggplot() + 
  geom_bar(aes(x = type, y=amount, fill=type), 
           position="dodge", stat="identity") + 
  facet_grid(~ size)

  ggplot() + 
  geom_bar(aes(x = type, y=amount, fill=type), 
           position="dodge", stat="identity") + 
  facet_grid(~ size)

5voto

jcmb Points 26

Similaire à la réponse de glenn_in_boston, mais sans codage dur dans les niveaux.

# Change this code:
facet_grid(.~size) + 
# To this code:
facet_grid(~factor(size, levels=unique(df$size)))

Cela fonctionne parce que la taille est classée du plus petit au plus grand dans le cadre de données.

Si la taille était déjà un facteur et que vous souhaitez simplement inverser l'ordre lors du traçage, c'est une option :

# Updating dataframe so size is a factor ordered smallest to largest
df <- data.frame(
  type   = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"), 
  size   = factor(c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"), levels=c("50%", "100%","150%","200%"), ordered = TRUE),
  amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)

# Now plotting with facets in the reverse order
ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) + 
  geom_col(width=0.5, position = position_dodge(width=0.6)) + 
  facet_grid(~factor(size, levels=rev(unique(df$size)))) +  #this part updated
  theme_bw() + 
  scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"), 
                    labels = c("T", "F", "P"))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X