4

The answers to this question were extremely helpful for me, too. There is just one thing I still need a hint to:

How do I get rid of the sign in the y-scale-Labels if I iterate the plot over a set of districts with varying y-values?

This is my code so far:

for (district in DISTRICTS) {
HW.dist <- subset(HW,DISTRICT==district)
  py <- ggplot(data=HW.dist,aes(x=as.numeric(AGE),fill=SEX))
  py <- py +
    geom_bar(subset=.(SEX=="F"), binwidth=1) +
    geom_bar(subset=.(SEX=="M"), binwidth=1,aes(y=..count..*(-1))) +
    scale_fill_grey(guide = guide_legend(title = NULL)) +
    scale_x_discrete(breaks=seq(0,120,by=5),labels=abs(seq(0,120,by=5))) +
    labs(y = "Count", x = "Age") +
    labs(title = "Random title text") +
    theme(plot.title = element_text(size = rel(1.5))) +
    coord_flip()
  print(py)
}

(DISTRICT obviously is just a list with the 16 districts.)

Sample data (HW):

SEX  AGE            DISTRICT 
 M   048          Innenstadt
 M   022          Innenstadt
 M   029            Neustift
 M   053            Neustift
 F   044             Heining
 F   017             Heining
 F   056            Neustift
 M   054            Neustift
 M   030            Altstadt
 M   029           Schalding
 F   029            Altstadt

RESULTS:

Including the help I got here and some fiddling with the y-axis-breaks, this is the relevant part of the final code (with some comments):

# How broad will the pyramid be?
f <- max(table(as.numeric(HW$AGE),HW$SEX)) 
# Round that up to the next power of 10 (eg 557 -> 600)
f <- ceiling(f/10^floor(log10(f)))*10^floor(log10(f)) 
# Use that power of 10 as breaks
l <- 10^floor(log10(f))
# f and l will be used in the 'scale_y_discrete' statement below

py <- ggplot(data=HW,aes(x=as.numeric(AGE),fill=MW))  
py +
  geom_bar(subset=.(SEX=="F"), binwidth=1) +
  geom_bar(subset=.(SEX=="M"), binwidth=1 ,aes(y=..count..*(-1))) +
  scale_fill_grey(guide = guide_legend(title = NULL)) +
  scale_x_continuous(breaks=seq(0,120,by=10),labels=abs(seq(0,120,by=10))) +
  scale_y_discrete(breaks=seq(-f,f,by=l),labels=abs) +
  labs(y = "Count", x = "Age") +
  labs(title = "Random title text") + theme(plot.title = element_text(size = rel(2))) +
  # Tell ggplot not to allocate drawing space for the negative (=male) on top (flipped: right) of the positive (=female) part of the graph
  coord_flip(xlim = c(0,110), ylim = c(-f, f))

This works perfect for me, even within a Loop through the districts.

Thanks a lot!

Community
  • 1
  • 1
user3205756
  • 43
  • 1
  • 6
  • 1
    I got several errors and the one I'm stuck on is a missing value for `MW`. There nothing in the data to give a clue. Post code that runs when pasted into a console session if you want it to be improved. – IRTFM Jan 18 '14 at 20:36
  • Sorry for that, I translated the code from German to English, and that one variable seems to have slipped through. I corrected it to "SEX". – user3205756 Jan 18 '14 at 21:59

1 Answers1

4

Since you are doing a coord_flip you have to change the labels of your y-axis values (which becomes the x-axis when flipped).

Add the following line, but instead of (-5 to +5) set them to be whatever is the maximum +ve and -ve values that your geom_bars can be, depending on the data. We are just making the axis value labels to be the abs values of the breaks.

+ scale_y_discrete(breaks=seq(-5,5,by=1),labels=abs(seq(-5,5,by=1)))     

I don't have your full data, but adding the line above took care of the minus sign and produced: enter image description here

Update based on OP's clarification

Looks like Hadley has already thought of this. Without specifying the breaks, just make the values to be absolute numbers so that it doesn't print negative values. Try adding:

+ scale_y_discrete(labels=abs)
Community
  • 1
  • 1
Ram Narasimhan
  • 22,341
  • 5
  • 49
  • 55
  • Thanks for that hint, but using "...labels=**abs**(seq..." requires me to set a fixed breaks width for every pass of the loop - which is exactly what I am trying to avoid. We're talking about some 50k observations, with districts varying from app. 1,200 to 12,000. – user3205756 Jan 19 '14 at 05:11
  • Updated response without fixed breaks, just to take care of the negative sign. – Ram Narasimhan Jan 19 '14 at 16:51
  • Thanks a lot, I'm absolutely happy with the solution you pointed me to. I added it above. – user3205756 Jan 20 '14 at 07:08
  • 1
    Very good. Please mark the question as complete when you get the chance. – Ram Narasimhan Jan 20 '14 at 16:16