Search code examples
rdifferential-equationsmodel-fittingmle

Why does fitting a very simple ODE in the R package fitode result in an "optim" error?


I am hoping to use the R package fitode to fit a differential equation model of tumor growth. Following the fitode vignette, I built my model and attempted to fit its parameters, but instead I encountered an error like this:

Error in optim(par = c(log.r1 = 0, log.X0 = 0), fn = function (p)  : 
  initial value in 'vmmin' is not finite

To diagnose, I gradually decreased the complexity of the model until it was nearly identical to the vignette's first example. However, the error persists, even in the simplest case, which is given below.

First, I call on the fitode package and simulate some data. These data could represent the cell counts for a dividing mass of cells over 14 days.

library(fitode)
days <- c(1, 3, 6, 8, 9, 11, 13, 14)
data_test <- data.frame(day = days, size = rpois(length(days), exp(days)))

Plotting these data shows simple exponential growth.

Plot of data alone

Next, I specify the exponential growth model.

model_test <- odemodel(
  name="test",
  model=list(
    X1 ~ r1 * X1
  ),
  observation=list(
    size ~ dpois(lambda=X1)
  ),
  initial=list(
    X1 ~ X0
  ),
  par=c("r1", "X0")
)

Because I simulated these data, I know that the growth parameter is 1, and the initial cell count is also 1. Indeed, plugging in these parameters and simulating the model gives a very nice fit.

start_test <- c(r1=1, X0=1)
sim_test <- simulate(model_test, parms = start_test, times = seq(0,14,by=0.1))

Plot of data with model

Because this is such a simple example, in which I can ensure that my initial guess at the parameters is perfect, fitting should be easy.

fit_test <- fitode(
  model=model_test,
  data=data_test,
  start=start_test
)

And yet, I receive: Fitting ode ... Error in optim(par = c(log.r1 = 0, log.X0 = 0), fn = function (p) : initial value in 'vmmin' is not finite

To me, this error usually indicates a bad initial guess, perhaps one that is incompatible with the model's link function. However, in this simulated example, my initial guess is perfect and is perfectly compatible with the default log link used in fitode. What is more, this simple example mirrors the first example of the vignette quite closely, except that I am simulating my own small data set.

What is going wrong here?


Solution

  • tl;dr you need tcol = "day" to tell the function where to look for the time variable.

    fit_test <- fitode(
      model=model_test,
      data=data_test,
      start=start_test, tcol ="day")
    

    This is in some sense not your fault, though — fitode could definitely be providing a more informative error message in this case ...

    Since this answer was posted, the package has been changed to produce a more informative error message.