4

My chart currently consists of multiple x-axis items that get 2 y-axis values each (one per group, means using stat_summary). However, the chart is flipped for the sake of stat_summary's mean function (but that is not the point here).

df <- data.frame(
  value = c(0, 0, -2, 1, 2, -2, 3, 1, 2, 3, 2, -1),
  type = c('P', 'P', 'E', 'P', 'E', 'E', 'P', 'E', 'E', 'E', 'P', 'P'),
  item = c('well-written', 'concise', 'well-written', 'clear', 'concise', 'clear', 'lively', 'fair', 'lively', 'pleasing', 'pleasing', 'fair')
)

ggplot(df, aes(x=item, y=value, colour=type)) +
  stat_summary(fun.y=mean, geom='point', size=3) + 
  scale_y_continuous(limits=c(-3, 3), breaks=c(-3, -2, -1, 1, 2, 3), minor_breaks=c(0)) +
  scale_linetype_discrete() +
  coord_flip()

See my current plot, without any arrows (status quo): enter image description here

What I want is, for every single item ("well-written", "concise", ...) to draw an arrow from E (the red point) to P (the blue point). Hence, I want multiple horizontal arrows, one for each item.

How?

Just one little addition here: I know that I would not need the mean function in this example but my actual data is much larger and contains multiple P/well-written, E/concise, etc. values so that the mean function makes sense

zx8754
  • 52,746
  • 12
  • 114
  • 209
Mario
  • 63
  • 6
  • Just one little addition here: I know that I would not need the mean function in this example but my actual data is much larger and contains multiple P/well-written, E/concise, etc. values so that the mean function makes sense :) – Mario May 04 '16 at 06:16

1 Answers1

2

Here's an approach, which however requires a second data frame to be created first:

library(tidyr)
df2 <- df %>% spread(type, value)

Then you can add geom_segment like so:

ggplot(df, aes(x=item, y=value, colour=type)) +
  stat_summary(fun.y=mean, geom='point', size=3) + 
  scale_y_continuous(limits=c(-3, 3), breaks=c(-3, -2, -1, 1, 2, 3), minor_breaks=c(0)) +
  scale_linetype_discrete() +
  coord_flip() +
  geom_segment(data = df2, aes(x = item, xend = item, y = E, yend = P, group = item), 
               colour = "black", 
               arrow = arrow())

enter image description here

erc
  • 10,113
  • 11
  • 57
  • 88
  • 1
    Great, thanks. Another approach I just found is to, first, do the mean calculation into a separate data frame and then, second, show the points using geom_point. This way, `geom_line(arrow=arrow())` and `group=item` (within ggplot-aes, see http://stackoverflow.com/a/11405077/2332153) can be added. – Mario May 04 '16 at 07:31