1

I am trying to plot a line over a bunch of points by certain groups. For example, I have:

x = rep(c('fruit', 'vegetable'), 15)
z = c(rep(c(rep('fresh', 2), rep('ripe', 2), rep('rotten', 2)), 5)
s = c(rep('pick1', 6), rep('pick2', 6), rep('pick3', 6), rep('pick4', 6), rep('pick5', 6))

y = runif(30, min=11, max=15)
low = rep(c(0, 1), 15)
y[low == 1] = y[low == 1] - 10
y[low == 0] = y[low == 0] - 5

groceries_df = data.frame(type=x, value=y, age=z, species=s)

where type is either "fruit" or "vegetable", age is either "fresh", "ripe", or "rotten", and species is a unique list of different picks from a store, so there are 2*3 = 6 values for each species. I am grouping these values on a discrete x-axis defined by their age, and they are grouped by their type (and thus dodged by their type).

dodge = position_dodge(width=0.9)
p = ggplot(groceries_df, aes(factor(age), value, color=factor(type), shape=factor(type))) +
           geom_jitter(position=dodge) +
           geom_line(data=groceries_df[groceries_df$type == 'fruit',],     aes(group=factor(species)), position=dodge) +
           geom_line(data=groceries_df[groceries_df$type == 'vegetable',], aes(group=factor(species)), position=dodge)

This code produces a plot extremely close to what I want, but I noticed that geom_line dodges by species, not by type. It seems as though I just need to redirect the dodge, even though I need the actual lines to be grouped by species (so I can see the transition of one species' value from one type to the next at all ages). Is there any way to redirect dodge?

user1104160
  • 305
  • 1
  • 12

1 Answers1

3

One solution would be to add new column to your existing data frame which will contain combination of type and species columns (those two columns are actually needed to group points for lines) (Idea taken from this @joran answer).

groceries_df$comb<-paste(groceries_df$type,groceries_df$species)

Then just use this new column as group=. This way you also need less comandlines.

ggplot(groceries_df,aes(age,value,color=type,shape=type,group=comb))+
  geom_jitter(position=dodge)+geom_line(position=dodge)

enter image description here

Community
  • 1
  • 1
Didzis Elferts
  • 95,661
  • 14
  • 264
  • 201
  • This is very close, but what if I want to also include a boxplot of the data at each type for each age (geom_boxplot(aes(color=factor(regions)), outlier.color=NA, outlier.shape=NA, position=dodge))? The boxes are clumped together in the wrong locations due to the pasting (this misplacing of the points also occurs if I try to draw the mean of the points using errorbar). – user1104160 Mar 06 '13 at 20:20
  • Alright, I have solved this issue by using interaction: geom_boxplot(gorceries_original, aes(color=factor(type), group=interaction(age, type)), outlier.color=NA, outlier.shape=NA, position=dodge) However, as with the errorbar-mean, the jitter points appear on the wrong side. Is there a reason for this occurrence? – user1104160 Mar 06 '13 at 20:41
  • I have also solved this new issue by flipping the levels of the column, so this issue is completely resolved. – user1104160 Mar 06 '13 at 21:17
  • @user1104160 would be awesome if you had posted your answer – bers Mar 07 '22 at 14:11