Difficulty running an ODE model in R including a parameter that varies by time (forcing function)

风格不统一 提交于 2021-01-28 14:22:16

问题


I am trying to fit a reasonably basic ODE model using deSolve, including within the model a parameter that varies by time (force of infection; FOI). While running the model without this parameter works fine, inclusion of the time dependent parameter gives an error (see below).

I am relatively new to R and mathematical modelling, and have been trying to solve this problem for some time now.

I have created the FOI parameter as a matrix of values and then used the approxfun function for interpolation (as I have seen this works with forcing functions, e.g. https://rdrr.io/rforge/deSolve/man/forcings.html).

The model without this time-dependent parameter runs without any errors, but attempting to include it gives the error:

Error in checkFunc(Func2, times, y, rho) : 
  The number of derivatives returned by func() (200) must equal the 
length of the initial conditions vector (2)

I cannot figure out how to fix this error, since I only have 2 initial conditions and it seems that including this time-dependent FOI parameter generates many more derivatives.

I am aware that others have asked a similar question, but I have not found this question posed with respect to forcing functions.

Many thanks in advance for any advice.

# Forcing function data

foi <- matrix(ncol=2,byrow=TRUE,data=c(
  0, 0.003, 2, 0.03, 3, 0.08, 4,0.1,  5, 0.12, 6, 0.15, 
  8, 0.16, 10, 0.14,12, 0.12,14,0.08,15, 0.06,16, 0.03,
  17, 0.01,18,0.003,19,0.003,20,0.003,30,0.003,40,0.003,
  50,0.003,60,0.003,65,0.01, 70,0.08,  72,0.095,74,0.10, 
  76,0.1, 78,0.08,  80,0.06))

age <- seq(0, 80, by = 1)

input <- approxfun(x = foi[,1], y = foi[,2], method = "constant", rule = 2)

# Function
ab <- function(time, state, pars) {
  with(as.list(c(state, pars)), {

import<-c(input(t))

diggP<- (import *iggN) - iggR*iggP   
diggN<- (-import*iggN) + iggR*iggP

return(list(c(diggP, diggN))) 
  })
}


# Initial values
yini  <- c(iggP=0, iggN=1) 

# Parameters
pars  <- c(iggR = 0, import)

# ODE solver
results<- ode(y=yini, times=age, func=foi_model, pars)

I am hoping to make a model in which at each point in time (or in this case age), FOI varies according to the values I have inputted in the FOI matrix. Thus I would like to see how changing FOI over age influences the output of the differential equations.


回答1:


Your main problem was that you were passing an argument t to input, but that variable doesn't exist in your code. Time is passed to your model as an argument called time. (Also, your model is called ab not foi_model, as is stated in the call to ode, plus pars doesn't need import and should be passed to ode.)

# Load library
library(deSolve)

# Create FOI matrix
foi <- matrix(ncol=2,byrow=TRUE,data=c(
  0, 0.003, 2, 0.03, 3, 0.08, 4,0.1,  5, 0.12, 6, 0.15, 
  8, 0.16, 10, 0.14,12, 0.12,14,0.08,15, 0.06,16, 0.03,
  17, 0.01,18,0.003,19,0.003,20,0.003,30,0.003,40,0.003,
  50,0.003,60,0.003,65,0.01, 70,0.08,  72,0.095,74,0.10, 
  76,0.1, 78,0.08,  80,0.06))

# Times for model solution
age <- seq(0, 80, by = 1)

# Linear interpolation function from FOI data
input <- approxfun(x = foi[,1], y = foi[,2], method = "constant", rule = 2)

# Model to be integrated
ab <- function(time, state, parms) {
  with(as.list(c(state, parms)), {

    ##### IMPORTANT #####
    import<-input(time) #<- 'time' was previously 't'
    #####################

    # Derivatives
    diggP<- (import *iggN) - iggR*iggP   
    diggN<- (-import*iggN) + iggR*iggP

    # Return results
    return(list(c(diggP, diggN))) 
  })
}

# Initial values
yini  <- c(iggP=0, iggN=1) 

# Parameters
pars  <- c(iggR = 0)

# Solve model
results<- ode(y=yini, times=age, func=ab, parms = pars)

# Plot results
plot(results)

Created on 2019-03-27 by the reprex package (v0.2.1)



来源:https://stackoverflow.com/questions/55379901/difficulty-running-an-ode-model-in-r-including-a-parameter-that-varies-by-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!