2
votes

I am trying to graph the following data:

to_graph <- structure(list(Teacher = c("BS", "BS", "FA"
), Level = structure(c(2L, 1L, 1L), .Label = c("BE", "AE", "ME", 
"EE"), class = "factor"), Count = c(2L, 25L, 28L)), .Names = c("Teacher", 
"Level", "Count"), row.names = c(NA, 3L), class = "data.frame")

and want to add labels in the middle of each piece of the bars that are the percentage for that piece. Based on this post, I came up with:

ggplot(data=to_graph, aes(x=Teacher, y=Count, fill=Level), ordered=TRUE) + 
    geom_bar(aes(fill = Level), position = 'fill') + 
    opts(axis.text.x=theme_text(angle=45)) + 
    scale_y_continuous("",formatter="percent") + 
    opts(title = "Score Distribution") + 
    scale_fill_manual(values = c("#FF0000", "#FFFF00","#00CC00", "#0000FF")) + 
    geom_text(aes(label = Count), size = 3, hjust = 0.5, vjust = 3, position = "stack")

But it

  1. Doesn't have any effect on the graph
  2. Probably doesn't display the percentage if it did (although I'm not entirely sure of this point)

Any help is greatly appreciated. Thanks!

1

1 Answers

3
votes

The y-coordinate of the text is the actual count (2, 25 or 28), whereas the y-coordinates in the plot panel range from 0 to 1, so the text is being printed off the top.

Calculate the fraction of counts using ddply (or tapply or whatever).

graph_avgs <- ddply(
  to_graph, 
  .(Teacher), 
  summarise, 
  Count.Fraction = Count / sum(Count)
)

to_graph <- cbind(to_graph, graph_avgs$Count.Fraction)

A simplified version of your plot. I haven't bothered to play about with factor orders so the numbers match up to the bars yet.

ggplot(to_graph, aes(Teacher), ordered = TRUE) + 
  geom_bar(aes(y = Count, fill = Level), position = 'fill') + 
  scale_fill_manual(values = c("#FF0000", "#FFFF00","#00CC00", "#0000FF")) + 
  geom_text(
    aes(y = graph_avgs$Count.Fraction, label = graph_avgs$Count.Fraction),  
    size = 3
  )