如何绘制适合ggplot2的nls模型的输出 [英] How to plot the output from an nls model fit in ggplot2

查看:114
本文介绍了如何绘制适合ggplot2的nls模型的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些数据,我想使用nls将非线性模型拟合到数据的每个子集,然后使用ggplot2将拟合的模型叠加到数据点的图形上.具体来说,模型的形式为

y~V*x/(K+x)

您可能会认为是Michaelis-Menten.一种方法是使用geom_smooth,但是如果我使用geom_smooth,我将没有任何方法来检索模型拟合的系数.或者,我可以使用nls拟合数据,然后使用geom_smooth拟合绘制线,但是我怎么知道geom_smooth绘制的曲线与我的nls fit给出的曲线相同呢?我无法将nls fit中的系数传递给geom_smooth并告诉其使用它们,除非我可以使geom_smooth仅使用数据的一个子集,然后我可以指定起始参数,这样就可以使用,但是...每个尝试读取错误的时间如下:

Aesthetics must be either length 1 or the same as the data (8): x, y, colour

这是我一直在使用的一些样本虚构数据:

Concentration <- c(500.0,250.0,100.0,62.5,50.0,25.0,12.5,5.0,
                   500.0,250.0,100.0,62.5,50.0,25.0,12.5,5.0)

drug <- c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2)

rate <- c(1.889220,1.426500,0.864720,0.662210,0.564340,0.343140,0.181120,0.077170,
          3.995055,3.011800,1.824505,1.397237,1.190078,0.723637,0.381865,0.162771)

file<-data.frame(Concentration,drug,rate)

在我的图中,浓度为x,速率为y;药物将是颜色变量.如果我写以下内容,则会出现该错误:

plot <- ggplot(file,aes(x=file[,1],y=file[,3],color=Compound))+geom_point()

plot<-plot+geom_smooth(data=subset(file,file[,2]==drugNames[i]),method.args=list(formula=y~Vmax*x/(Km+x),start=list(Vmax=coef(models[[i]])[1],Km=coef(models[[i]])[2])),se=FALSE,size=0.5)

其中models [[]]是nls返回的模型参数的列表.

关于如何在geom_smooth中子集数据框的任何想法,以便可以使用nls fit的起始参数分别绘制曲线?

解决方案

理想的解决方案是使用ggplot绘制nls()的结果,但这是基于几个观察结果的快速而肮脏的"解决方案. /p>

首先,可以确保如果对nls()geom_smooth(method = "nls")使用相同的公式,则将获得相同的系数.那是因为后者正在呼叫前者.

第二,使用您的示例数据,nls()收敛到相同的Vmax和Km值(每种药物不同),而不管起始值如何.换句话说,无需使用每种药物范围内的起始值来构建模型.以下任何一项对药物1的结果相同(对于药物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))

因此绘制曲线的最快方法是简单地将药物映射到ggplot美学上,例如颜色.这样将从相同的起始值构造出单独的nls曲线,然后在需要获取系数的情况下返回到nls(),知道模型应该与图相同.

使用示例数据file(但不要使用file,我使用的是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)))

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 ggplot2. Specifically the model is of the form

y~V*x/(K+x)

which you may recognize as Michaelis-Menten. One way to do this is using geom_smooth, but if I use geom_smooth I don't have any way to retrieve the coefficients for the model fit. Alternatively I could fit the data using nls then plot lines fitted using geom_smooth, but then how do I know that the curves which geom_smooth plotted are the same as those given by my nls fit? I can't pass the coefficients from my nls fit to geom_smooth and tell it to use them unless I can get geom_smooth to only use a subset of the data, then I can specify the starting parameters so that would work, but... Every time I've tried that I get an error reading as follows:

Aesthetics must be either length 1 or the same as the data (8): x, y, colour

Here's some sample made-up data I have been using:

Concentration <- c(500.0,250.0,100.0,62.5,50.0,25.0,12.5,5.0,
                   500.0,250.0,100.0,62.5,50.0,25.0,12.5,5.0)

drug <- c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2)

rate <- c(1.889220,1.426500,0.864720,0.662210,0.564340,0.343140,0.181120,0.077170,
          3.995055,3.011800,1.824505,1.397237,1.190078,0.723637,0.381865,0.162771)

file<-data.frame(Concentration,drug,rate)

where Concentration will be x in my plot and rate will be y; drug will be the color variable. If I write the following I get that error:

plot <- ggplot(file,aes(x=file[,1],y=file[,3],color=Compound))+geom_point()

plot<-plot+geom_smooth(data=subset(file,file[,2]==drugNames[i]),method.args=list(formula=y~Vmax*x/(Km+x),start=list(Vmax=coef(models[[i]])[1],Km=coef(models[[i]])[2])),se=FALSE,size=0.5)

where models[[]] is a list of model parameters returned by nls.

Any ideas on how I can subset a data frame in geom_smooth so I can individually plot curves using starting parameters from my nls fit?

解决方案

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)))

这篇关于如何绘制适合ggplot2的nls模型的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆