Search code examples
rggplot2data-visualizationfacet-wrap

Plotting different models for different x value ranges in ggplot()


I am attempting to display a linear model for low x values and a non-linear model for higher x values. To do this, I will use DNase as an example:

library(ggplot2)

#Assinging DNase as a new dataframe:

data_1 <- DNase

#Creating a column that can distinguish low and high range values:

data_1$range <- ifelse(data_1$conc <5, "low", "high")

#Attempting to plot separate lines for low and high range values, and also facet_wrap by run:

ggplot(data_1, aes(x = conc, y = density, colour = range)) +
  geom_point(size = 0.5) + stat_smooth(method = "nls", 
                                       method.args = list(formula = y ~ a*exp(b*x),
                                                          start = list(a = 0.8, b = 0.1)), 
                                       data = data_1,
                                       se = FALSE) + 
  stat_smooth(method = 'lm', formula = 'y~0+x') + 
  facet_wrap(~Run) 



However, as you can see, it seems to plot both the linear model and the non-linear model for both, and I can't quite figure out where to put information that would tell it to only plot one for each. Also, if possible, can I extend these models out to the full range of values on the x axis?

enter image description here


Solution

  • You can provide specific data to each geom. In this case use subset data_1 using range to only provide the relevant data to each stat_smooth() call (and the whole frame to geom_point()

    ggplot(NULL, aes(x = conc, y = density, colour = range)) +
      geom_point(data = data_1, size = 0.5) + 
      stat_smooth(data = subset(data_1, range == "high"),
                  method = "nls", 
                  method.args = list(formula = y ~ a*exp(b*x),
                                     start = list(a = 0.8, b = 0.1)), 
                  se = FALSE) + 
      stat_smooth(data = subset(data_1, range == "low"), method = 'lm', formula = 'y~0+x') + 
      facet_wrap(~Run)
    

    enter image description here

    If you want to fit both models on all the data, then just calculate those manually in data_1 and plot manually.