I am trying to fit very simple exponential decay using R. However, I have a problem achieving that task using R.
koff_dat <- tribble(
~incu_time, ~perc_binding,
179.20634920634922, 3.94736842105263,
120.47619047619048, 10.197368421052616,
91.11111111111111, 18.09210526315789,
60.95238095238095, 35.526315789473685,
45.87301587301587, 31.25,
30.793650793650798, 55.921052631578945,
16.50793650793652, 68.75,
0.6349206349206398, 99.34210526315789
)
fit2 <- nls(perc_binding ~ exp(-k*incu_time),
data = koff_dat,
start = list(k = 0.001))
plot(koff_dat$incu_time, koff_dat$perc_binding)
lines(koff_dat$incu_time, predict(fit2))
As you can tell from there the fit is very off for k. pleas advise
1) The model needs a multiplying constant: A * exp(-k * incu_time). Using the plinear algorithm which will add a multiplying constant without needing another starting value. We have also added an automatic starting value for k but the one in the question would also work.
(continued after graph)
k.start <- -coef(lm(log(perc_binding) ~ incu_time, koff_dat))[[2]]
fit3 <- nls(perc_binding ~ cbind(A = exp(-k*incu_time)),
data = koff_dat, start = list(k = k.start), alg = "plinear")
plot(koff_dat)
lines(fitted(fit3) ~ incu_time, koff_dat)
2) drc Also the drc package has such a model. No starting values are needed.
library(drc)
fit4 <- drm(perc_binding ~ incu_time, data = koff_dat, fct = EXD.2())
Its e
parameter is the reciprocal of k
coef(fit3)
## k .lin.A
## 0.0197362 98.6532169
c(1/coef(fit4)[2], coef(fit4)[1])
## e:(Intercept) d:(Intercept)
## 0.01973619 98.65319125
3) units A way to resolve this while using the model in the question without any modification is change the units used in koff_data
. This gives a fit which is visually very similar to the graph above.
koff_dat2 <- transform(koff_dat, perc_binding = perc_binding / 100)
fit5 <- nls(perc_binding ~ exp(-k*incu_time), data = koff_dat2,
start = list(k = 0.001))
plot(koff_dat2)
lines(fitted(fit5) ~ incu_time, koff_dat2)