1

I can't figure out how to get the fill order to reverse. Basically, I'm trying to get the guide and the fill to match an intrinsic order of the words from positive to negative:

The guide, and the fill order, from top to bottom should be:

  • "Far better than I expected", (Filled at very top, at top of legend)
  • "A little better than I expected",
  • "About what I expected",
  • "A little worse than I expected",
  • "Far worse than I expected" (Filled at very bottom, at bottom of legend)

You'll need sample data:

dat <- structure(list(Banner = structure(c(2L, 2L, 2L, 2L, 2L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L), .Label = c("Other", "Some Company"
), class = "factor"), Response = structure(c(1L, 2L, 3L, 4L, 
5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 
1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L),
 .Label = c(
"Far better than I expected", 
"A little better than I expected", 
"About what I expected", 
"A little worse than I expected", 
"Far worse than I expected"), class = "factor"), Frequency = c(1L, 
6L, 9L, 0L, 0L, 29L, 71L, 149L, 32L, 6L, 1L, 7L, 16L, 1L, 0L, 
38L, 90L, 211L, 24L, 6L, 0L, 0L, 8L, 1L, 1L, 6L, 13L, 109L, 35L, 
9L), Proportion = c(6, 38, 56, 0, 0, 10, 25, 52, 11, 2, 4, 28, 
64, 4, 0, 10, 24, 57, 7, 2, 0, 0, 80, 10, 10, 3, 8, 63, 20, 5
), Phase = c("Phase 1", "Phase 1", "Phase 1", "Phase 1", "Phase 1", 
"Phase 1", "Phase 1", "Phase 1", "Phase 1", "Phase 1", "Phase 2", 
"Phase 2", "Phase 2", "Phase 2", "Phase 2", "Phase 2", "Phase 2", 
"Phase 2", "Phase 2", "Phase 2", "Phase 3", "Phase 3", "Phase 3", 
"Phase 3", "Phase 3", "Phase 3", "Phase 3", "Phase 3", "Phase 3", 
"Phase 3")), .Names = c("Banner", "Response", "Frequency", "Proportion", 
"Phase"), 
row.names = c(NA, 30L), 
sig = character(0), 
comment = "Overall, my experience was...  by  Company", q1 = "", q2 = "", 
class = c("survcsub", "data.frame"))

Position labels

dat <- ddply(dat, .(Banner, Phase), function(x) {
   x$Pos <- (cumsum(x$Proportion) - 0.5*x$Proportion)
   x
})

Plot

ggplot(dat, aes(Banner, Proportion/100, fill=Response,
  label=ifelse(Proportion > 5, percent(Proportion/100), ""))) + 
  geom_bar(position="fill", stat="identity") + 
  geom_text(aes(Banner, Pos/100)) + 
  facet_grid(~Phase) + 
  scale_y_continuous(labels=percent) +
  labs(x="\nCompany", y="\nProportion")

What I've tried:

dat$Response <- factor(dat$Response, levels=rev(dat$Response)) 
# No dice, reverses the colour of the scale but not the position of the fill
Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255

1 Answers1

1

To change the order of values in stacked barplot you should use argument order= in aes() of geom_bar() and set name of column necessary for ordering (in this case Response). With function desc() you can set reverse order of bars.

Using your original data frame (without last line of factor()).

ggplot(dat, aes(Banner, Proportion/100, fill=Response,
                label=ifelse(Proportion > 5, percent(Proportion/100), ""))) + 
  geom_bar(position="fill", stat="identity",aes(order=desc(Response))) + 
  geom_text(aes(Banner, Pos/100)) + 
  facet_grid(~Phase) + 
  scale_y_continuous(labels=percent) +
  labs(x="\nCompany", y="\nProportion")

To get correct placement of labels, changed calculation of positions:

dat <- ddply(dat, .(Banner, Phase), function(x) {
  x$Pos <- (100-cumsum(x$Proportion) + 0.5*x$Proportion)
  x
})

enter image description here

Didzis Elferts
  • 95,661
  • 14
  • 264
  • 201