0

Is there a way to facet_wrap() by the slope of a geom_line in R or ggplot, such that for each geom_line, all regions of that line with positive slope are placed in one facet, all regions with negative slope are placed in another facet, and all regions with no slope are placed in a third facet?

In the following minimal example, for instance, the target would be to place the rising segments of lines a and b in the positive slope facet, the falling segments of lines a and b in the negative facet, and the segments of a and b with no slope in the no slope facet:

library(ggplot2)
a.df <- data.frame(matrix(c('A',0,2,'A',1,6,'A',2,6,'A',3,4,'B',0,5,'B',1,4,'B',2,4,'B',3,6),ncol=3,byrow=TRUE))

a.df$X2 <- as.numeric(as.character(a.df$X2))
a.df$X3 <- as.numeric(as.character(a.df$X3))

ggplot(a.df, aes(x=X2,y=X3,colour=X1)) +
  geom_line()

enter image description here

I tried your response MrFlick, but it looks like its placing lines in the positive or negative slope category if their global slope is positive or negative. I'm wondering if it would be possible to place all of the subregions of each line that have positive or negative slope into different facets. Is there a way to modify your code to accomplish this task? I would be grateful for any help you can offer on this question.

duhaime
  • 25,611
  • 17
  • 169
  • 224
  • There's nothing in ggplot to do this. You would need to pre-calculate a slope per group before plotting. I would be more specific but your example seems needlessly complex. It helps to provide a [*minimal* reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) that doesn't involve downloading large data file. – MrFlick Apr 11 '15 at 00:18

1 Answers1

1

Now that you want to treat each change as a separate segment that you can relocated to a different facet, you'll need to transform your data accordingly. Here's a method using dplyr

library(dplyr)

b.df <- a.df %>% group_by(X1) %>% arrange(X2) %>% 
    mutate(X4=lead(X2), X5=lead(X3), slopesign=sign(X5-X3))

ggplot(subset(b.df, !is.na(slopesign))) +
  geom_segment(aes(x=X2,y=X3, xend=X4, yend=X5, color=X1)) + 
  facet_wrap(~slopesign)

enter image description here

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Thanks so much MrFlick, and sorry my question is less streamlined than it could have been. You've helped me get closer, but when I adapt the code to my lengthier lines and plot the trends over time, some of the lines in the positive facet move downwards and vice versa. If you have a second, I would be very thankful for thoughts you can offer on the edit above. – duhaime Apr 11 '15 at 00:57
  • I've updated my answer accordingly. It would have been nice if your question was like that from the beginning. – MrFlick Apr 11 '15 at 01:57
  • This is fantastic! I'm very grateful for your assistance, and will use more minimal datasets in future questions. Thanks again for reaching out. – duhaime Apr 11 '15 at 02:04
  • MrFlick, sorry to ping you again, but I've just tried your snipped on my use case, and it's only returning negative slopes and NA values, even when the slope of the segment is positive. Do you know why that might be the case? – duhaime Apr 11 '15 at 12:15