How to plot the output from an nls model fit in ggplot2

前端 未结 1 1508
悲&欢浪女
悲&欢浪女 2021-01-15 23:01

I have some data where I would like to fit a nonlinear model to each subset of the data using nls, then superimpose the fitted models onto a graph of the data points using g

相关标签:
1条回答
  • 2021-01-15 23:22

    The ideal solution would plot the results of nls() using ggplot, but here's a "quick and dirty" solution based on a couple of observations.

    First, you can be sure that if you use the same formula for nls() and geom_smooth(method = "nls"), you will get the same coefficients. That's because the latter is calling the former.

    Second, using your example data, nls() converges to the same values of Vmax and Km (different for each drug), regardless of start value. In other words, there's no need to build models using start values in the range for each individual drug. Any of the following give the same result for drug 1 (and similarly for drug 2):

    library(dplyr)
    # use maximum as start
    df1 %>% 
      filter(drug == 1) %>% 
      nls(rate ~ Vm * Concentration/(K + Concentration), 
          data = ., 
          start = list(K = max(.$Concentration), Vm = max(.$rate)))
    
    # use minimum as start
    df1 %>% 
      filter(drug == 1) %>% 
      nls(rate ~ Vm * Concentration/(K + Concentration), 
          data = ., 
          start = list(K = min(.$Concentration), Vm = min(.$rate)))
    
    # use arbitrary values as start
    df1 %>% 
      filter(drug == 1) %>% 
      nls(rate ~ Vm * Concentration/(K + Concentration), 
          data = ., 
          start = list(K = 50, Vm = 2))
    

    So the quickest way to plot the curves is simply to map the drug to a ggplot aesthetic, such as color. This will construct separate nls curves from the same start values and you can then go back to nls() if required to get the coefficients, knowing that the models should be the same as the plot.

    Using your example data file (but don't call it file, I used df1):

    library(ggplot2)
    df1 <- structure(list(Concentration = c(500, 250, 100, 62.5, 50, 25, 12.5, 5, 
                                            500, 250, 100, 62.5, 50, 25, 12.5, 5), 
                          drug = c(1, 1, 1, 1, 1, 1, 1, 1, 
                                   2, 2, 2, 2, 2, 2, 2, 2), 
                          rate = c(1.88922, 1.4265, 0.86472, 0.66221, 0.56434, 0.34314, 
                                   0.18112, 0.07717, 3.995055, 3.0118, 1.824505, 1.397237, 
                                   1.190078, 0.723637, 0.381865, 0.162771)),
                          .Names = c("Concentration", "drug", "rate"), 
                          row.names = c(NA, -16L), 
                          class = "data.frame")
    
    # could use e.g. Km = min(df1$Concentration) for start
    # but here we use arbitrary values
    ggplot(df1, aes(Concentration, rate)) + 
      geom_point() + 
      geom_smooth(method = "nls", 
                  method.args = list(formula = y ~ Vmax * x / (Km + x),
                                     start = list(Km = 50, Vmax = 2)), 
                  data = df1,
                  se = FALSE,
                  aes(color = factor(drug)))
    

    0 讨论(0)
提交回复
热议问题