Fitting a Michaelis-Menten model and drawing the results in R

The below code will demonstrate how to fit a Michaelis-Menten model and draw the result. First part will use a package drc and its function drm (dose response model). Second part will demonstrate how to fit this model “out of the box” with function nls. The code used can be also found in a book by Ritz and Streinbig Nonlinear regression with R (see pages 10 and 11).

The model

The model we’re trying to fit is a 2 parameter model (see page 10 of the above mentioned book)

\[f(x, (K, V_m)) = \frac{V_m x}{K+x}\]

where \(V_m\) is the asymptote and \(K\) is half way between 0 and the asymptote.

First, let’s find some data (kindly provided by Martin M.).

mm <- structure(list(S = c(3.6, 1.8, 0.9, 0.45, 0.225, 0.1125, 3.6, 
                           1.8, 0.9, 0.45, 0.225, 0.1125, 3.6, 1.8, 0.9, 0.45, 0.225, 0.1125, 
                           0), v = c(0.004407692, 0.004192308, 0.003553846, 0.002576923, 
                                     0.001661538, 0.001064286, 0.004835714, 0.004671429, 0.0039, 0.002857143, 
                                     0.00175, 0.001057143, 0.004907143, 0.004521429, 0.00375, 0.002764286, 
                                     0.001857143, 0.001121429, 0)), .Names = c("S", "v"), class = "data.frame", row.names = c(NA, 
                                                                                                                              -19L))

We will use package drm to fit the model and package ggplot2 to draw the result. We load the neccessary libraries.

library(drc) # for fitting Michaelis Menten model
library(ggplot2) # for drawing

We fit the data using function drm. We are saying that v depends on S, and the model that should be fitted is a two parameter Michaelis-Menten model (coded in functoin MM.2). After the model has been fitted, we predict the values in order to get a smooth fitted line.

model.drm <- drm (v ~ S, data = mm, fct = MM.2())

mml <- data.frame(S = seq(0, max(mm$S), length.out = 100))
mml$v <- predict(model.drm, newdata = mml)

Using the below code, we can visualize the result.

ggplot(mm, aes(x = S, y = v)) +
  theme_bw() +
  xlab("Concentration [mM]") +
  ylab("Speed [dE/min]") +
  ggtitle("Michaelis-Menten kinetics") +
  geom_point(alpha = 0.5) +
  geom_line(data = mml, aes(x = S, y = v), colour = "red")

plot of chunk visualize

To save the result in a nifty pdf, use the below command.

ggsave("mm.pdf", width = 6, height = 4)

Using nls()

We need to provide the starting values \(V_m\) and \(K\). See introduction on explanation of what the parameters represent. It should be obvious why the following choice.

model.nls <- nls(v ~ Vm * S/(K+S), data = mm, 
                 start = list(K = max(mm$v)/2, Vm = max(mm$v)))

We notice that the estimated parameters are identical for practical purposes.

summary(model.drm)
## 
## Model fitted: Michaelis-Menten (2 parms)
## 
## Parameter estimates:
## 
##               Estimate Std. Error  t-value p-value
## d:(Intercept) 5.43e-03   1.18e-04 4.61e+01       0
## e:(Intercept) 4.40e-01   3.05e-02 1.44e+01       0
## 
## Residual standard error:
## 
##  0.0001727 (17 degrees of freedom)
summary(model.nls)
## 
## Formula: v ~ Vm * S/(K + S)
## 
## Parameters:
##    Estimate Std. Error t value Pr(>|t|)    
## K  0.439802   0.031161    14.1  8.1e-11 ***
## Vm 0.005425   0.000119    45.5  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.000173 on 17 degrees of freedom
## 
## Number of iterations to convergence: 7 
## Achieved convergence tolerance: 4.67e-07