1

The following R script:

library(ggplot2)

data <- read.csv(text="x,value,version
foo,10,one
foo,12,two
bar,8,one
bar,7,two
baz,11,one
baz,14,two", header=TRUE)

png(filename="so.png")
ggplot(data,aes(data$x,data$value,fill=data$version)) + 
  geom_bar(stat="identity",position="dodge") + 
  scale_fill_brewer(palette="Set1") + 
  labs(x = "x",y="value") + 
  guides(fill=guide_legend(title="version"))
dev.off()

Produces the following graph:

enter image description here

They appear left to right according to the "x" column (foo, bar, baz) alphabetically. However, I'd like the "x" column-grouped bars to appear according one of the versions, left most being the highest "value" column value. E.g. left to right according to values of "one" version. Thus:

  • left most: baz (one:11,two:14)
  • middle: foo (one:10,two:12)
  • right most: bar (one:8,two:7)

How can I achieve this?

Z.Lin
  • 28,055
  • 6
  • 54
  • 94
Rob Stewart
  • 1,812
  • 1
  • 12
  • 25
  • Have you seen [this](https://stackoverflow.com/q/5208679/324364)? – joran May 18 '18 at 21:37
  • @joran I have. That answer does not consider grouped bar plots, as being asked here: grouped by "version", then ordered high to low according to one of those "version"s. – Rob Stewart May 18 '18 at 21:41
  • The principle is always the same. Order the levels in the desired order. – joran May 18 '18 at 21:47
  • 1
    Possible duplicate of [ggplot2, geom\_bar, dodge, order of bars](https://stackoverflow.com/questions/33127081/ggplot2-geom-bar-dodge-order-of-bars) – camille May 18 '18 at 21:51
  • 1
    You don't need the `data$` part inside the `aes`. – Jaap May 19 '18 at 06:32

1 Answers1

2

The general principle at the question I cited always holds: you control order by setting the factor level order. Many people get tripped up because the answer at that question doesn't always tell you in precise detail how to reorder your factor in every single circumstance. But the idea is always the same. Here are a variety of ways to approach setting the factor levels in that order:

#Cleverly
library(forcats)
data$x <- fct_reorder2(.f = data$x,
                       x = data$value,
                       y = data$version,
                       fun = function(x,y) x[y == "one"])

#Manually
data$x <- factor(data$x,levels = c("baz","foo","bar"))

#Tortuously
levels(data$x) <- data$x[data$version == "one"][order(data$value[data$version == "one"],decreasing = TRUE)]

#tidily
library(dplyr)
levels(data$x) <- data %>%
  filter(version == "one") %>%
  arrange(desc(value)) %>%
  pull(x)
joran
  • 169,992
  • 32
  • 429
  • 468
  • Thanks! For the first option, `fct_reorder2`, I'm getting the error: `Error in check_factor(.f) : argument ".f" is missing, with no default Calls: fct_reorder2 -> check_factor Execution halted` – Rob Stewart May 18 '18 at 22:27
  • @RobStewart Looks like I have an old version of forcats installed where the first argument was `f` rather than `.f`. Sorry about that. – joran May 18 '18 at 23:00