2

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

Cameron
  • 164
  • 14
  • Maybe this could fix the range of values on x axis? https://stackoverflow.com/questions/47667994/ggplot-x-axis-labels-with-all-x-axis-values –  Dec 03 '21 at 16:37

1 Answers1

1

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.

caldwellst
  • 5,719
  • 6
  • 22
  • This looks great, and I really appreciate the help. Unfortunately when I run this code, it gives the following error: Error: `mapping` must be created by `aes()` Run `rlang::last_error()` to see where the error occurred. > rlang::last_error() `mapping` must be created by `aes()` Backtrace: 1. ggplot2::geom_point(data_1, size = 0.5) 2. ggplot2::layer(...) 3. ggplot2:::validate_mapping(mapping) – Cameron Dec 03 '21 at 17:49
  • Whoops, forgot to add the `data = data1` in `geom_point()` after a last minute change. Fixed @Cameron. – caldwellst Dec 03 '21 at 17:51