0
votes

Suppose I have a LOESS regression plot where the x-axis correspond to a categorical variable:

library(ggplot2)

b <- structure(list(Expression = c(16.201081535896, 16.5138880401065, 
16.4244615700828, 1.62923743262849, 3.35379087562868, 6.99935683212696, 
4.81932543877313, 3.85300704208448, 7.32436891427261, 4.23627699164079, 
6.95731601433845, 4.33315521361287, 5.50596153247422, 13.0788494583573, 
13.6909487566244, 12.9520674350314), stage = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L), .Label = c("A", 
"B", "C", "D", "E"), class = "factor")), row.names = c(NA, 16L
), class = "data.frame")

ggplot(b, aes(as.numeric(stage), Expression)) +
  geom_point() +
  geom_smooth(span = 0.8) +
  scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)

link to plot 1

I want to use 2 different line types at different sections of a LOESS regression.

Specifically, I would like to have a dashed line between A and B, a continuous line between B and D, and a dashed line again between D and E.

So I follow the example in: conditional plot linetype in ggplot2

But the connection in the left and right are lost, and only the central part of the loess regression remains.

line.groups <- plyr::mapvalues(b$stage, 
                from = c("A", "B",  "C", "D", "E"),
                to = c(0, 1, 1, 1, 2))
ggplot(b, aes(as.numeric(stage), Expression)) +
  geom_point() +
  geom_smooth(aes(group=line.groups, linetype=line.groups), span = 0.8) +
  scale_linetype_manual(values=c(2,1,2)) +
  guides(linetype=FALSE) +  
  scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)

Link to image 2

Is there a way to change the linetype of the geom_smooth ggplot, conditional to the x-axis (where x is a factor)?

EDIT:

I tried using three separate calls to geom_smooth for each section as suggested by a comment, but the standard error bounds won't be "smooth" between each call.

ggplot(b, aes(as.numeric(stage), Expression)) +
  geom_point() +
  geom_smooth(data=b[b$stage %in% c("A", "B"),], linetype = "dashed", span = 0.8) +
  geom_smooth(data=b[b$stage %in% c("B", "C", "D"),], linetype = "solid", span = 0.8) +
  geom_smooth(data=b[b$stage %in% c("D", "E"),], linetype = "dashed",span = 0.8) +
  scale_linetype_manual(values=c(2,1,2)) +
  guides(linetype=FALSE) +  
  scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)

Link to sub-optimal solution

Thanks

1
Ah, the issue here might be that you are using geom_smooth whereas the post that you reference uses stat_function. A possible work around is to subset your data (A-B, B-D, D-E) and call 3 separate geom_smooth functions.OTStats
@OTStats, thanks. I tried using 3 calls to geom_smooth, but that would affect how the standard error bounds are computed and displayed, so the boundaries won't match see: link to example 3Borlaug
Another work around could be to use the se = FALSE within geom_smooth for all three of those calls, and then using a fourth geom_smooth call where you try to hide the line and only use the standard error. This isn't the best practice by any means, but it's a way to hack your way to where you want.OTStats
@OTStats: thanks, that was very useful and solves my questionBorlaug

1 Answers

0
votes

For completeness, I will post here the solution offered by user OTStats in the comments above:

ggplot(b, aes(as.numeric(stage), Expression)) +
  geom_point() +
  geom_smooth(data=b[b$stage %in% c("A", "B"),], linetype = "dashed", span = 0.8,se = FALSE) +
  geom_smooth(data=b[b$stage %in% c("B", "C", "D"),], linetype = "solid", span = 0.8, se = FALSE) +
  geom_smooth(data=b[b$stage %in% c("D", "E"),], linetype = "dashed",span = 0.8, se = FALSE) +
  geom_smooth(linetype = "blank",span = 0.4) +
  guides(linetype=FALSE) +  
  scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)

Note that the level of smoothing needs to be adjusted in the fourth call of geom_smooth to produce satisfactory results but, overall, this trick solves the question.

Link to solution