Reordering A Bar Graph in R Using the GGPLOT2 Package In Tidy Verse

Hey everyone, beginner to R. I'm trying to reorder these bars in ascending order (or vice-versa) for the "starwars" dataset, but I'm not sure what I' doing wrong because I keep getting an error printed to my console when I run the code. I followed the exact syntax for the "msleep" dataset, and everything worked out fine in ascending and descending order. I can't get either order to work with the starwars dataset, however. Can someone explain what's wrong? Thank you.

MY CODE:

starwars %>%
mutate(name = fct_reorder(name, height)) %>%
filter(name %in% c("Luke Skywalker","Han Solo","Greedo")) %>%
ggplot(aes(name, height, fill = name)) +
geom_bar(stat = "identity")

RESULTS IN CONSOLE AFTER RUNNING CODE:

MY PLOTS SECTION (REMAINS SAME AND DOESN'T CHANGE ANY SORT OF ORDERING):

Maybe update your packages? It seems to run fine for me:

> sessionInfo()

R version 4.1.2 (2021-11-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)

Matrix products: default

locale:
[1] LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252    LC_MONETARY=English_Australia.1252 LC_NUMERIC=C                       LC_TIME=English_Australia.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] forcats_0.5.2    stringr_1.5.0    purrr_1.0.1      readr_2.1.2      tidyr_1.3.0      tibble_3.2.1     ggplot2_3.4.3    tidyverse_1.3.2  dplyr_1.1.3      leaflet_2.2.1   
[11] champ_0.0.0.9000 shiny_1.7.2   
1 Like

You get the error

Error in `mutate()`:
ℹ In argument: `name = fct_reorder(name, rev(height))`.
Caused by error in `lvls_reorder()`:
! `idx` must contain one integer for each level of `f`
Run `rlang::last_trace()` to see where the error occurred.

because your dataset contains multiple observations (rows) with the same height. Either filter first (and hope you've eliminated the duplicates), or order by height, make a new variable from row_number() and use that as the value to reorder the name factor.

starwars %>%
  select(name, height) %>%
  arrange(desc(height)) %>%
  mutate(name = fct_reorder(name, row_number())) %>%
  ggplot(aes(name, height, fill = name)) +
  geom_bar(stat = "identity", show.legend = F)
1 Like

Also, the default for as_factor() is to create levels by the order of appearance

starwars %>%
  arrange(height) %>%
  mutate(name = as_factor(name)) %>%
  filter(name %in% c("Luke Skywalker","Han Solo","Greedo")) %>%
  ggplot(aes(name, height, fill = name)) + 
  geom_bar(stat = "identity", show.legend = F)
1 Like

Putting the filter function before mutate worked! Thank you!

It will work as long as some of your chosen Star Wars characters do not have the same height. You did not get an error because Luke Skywalker, Han Solo, and Greedo have different heights.

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.