facet_wrap labels mixed up when factor is not in alphabetic order and... (R 3.1.0 ggplot2 0.9.3.1)

1,036 views
Skip to first unread message

Jacqueline Tay

unread,
Apr 21, 2014, 8:53:28 AM4/21/14
to ggp...@googlegroups.com
Hi Everyone,

I'm using ggplot on a dataframe to make a histogram, faceted by a variable that has two levels.  I will explain my problem and then add reproducible code below.

When I call aes(x = variable)..., everything is okay (see the correct.pdf attached).  When I call aes(x= df$variable) or aes(x= df[,col]), I get the incorrect graph (see incorrect.pdf).  In the incorrect pdf, the legend and header label are mixed up (legend has labeled pink as a when it is showing b data and header label labels a as b and vice versa).  Also, this problem only happens if my factor is not in alphabetical order.  If it is in alphabetical order, the legends and labels match up okay with the data.

I have seen in other posts that calling df$variable is bad form if I've already specified the df.  However, I would like to use df[,col] in a loop where I am looping through certain columns to plot.  I guess my question is why am I getting this error?  I am just worried that I may be plotting other things (under other circumstances) and I won't catch the flip flop. Does this mean I just should not/cannot use df[,col] at all? 

Below is my example of reproducible code (but it does not include multiple columns for simplicity).  I'm sorry if the above was confusing, this is my first time posting to a forum for help!

##test data for my plots
a = rnorm(10)
b = rnorm(10,10)
data = cbind(b,a) # if you cbind(a,b), then the error won't occur
d_melt = melt(data)
names(d_melt)[2] = "type"
plot(ggplot(d_melt, aes(x=value, fill=type)) + geom_histogram()+ facet_wrap(~type))
plot(ggplot(d_melt, aes(x=d_melt[,3], fill=type)) + geom_histogram()+ facet_wrap(~type))
correct.pdf
incorrect.pdf

Allan Just

unread,
Apr 21, 2014, 11:18:21 AM4/21/14
to ggp...@googlegroups.com
Hi Jacqueline,
  your post was reproducible and your question was well written. ggplot2 works with data.frame objects and your issue is arising because in your call to aes you are passing in data from outside of your call to data and thus breaking the connection between the two columns (value and type). ggplot2 would let you call any vector that is the right length within the aes() but it wouldn't have the correct relation with your other variables.
It sounds like you want flexibility in assigning which column from your dataset to map to an aesthetic. You should try the aes_string function:
  ?aes_string
  plotvar <- "value" #you can assign this within a loop, for example
  ggplot(data = d_melt, aes_string(x=plotvar, fill="type")) + geom_histogram()+ facet_wrap(~type)
  # note that the first parameter of ggplot2 is for a data.frame
  # this is the only place you need to call for those data
  # and that you don't need to wrap your call with plot()

Hope that clarifies,
Allan

Jacqueline Tay

unread,
Apr 21, 2014, 1:45:54 PM4/21/14
to ggp...@googlegroups.com
Hi Allan,
The aes_string function is exactly what I need.  Thanks for your explanation!

Jacqueline
Reply all
Reply to author
Forward
0 new messages