使用包解析 - 状态可以由矩阵定义吗?

时间:2014-10-07 15:53:04

标签: r ode

我试图使用具有相当多状态的deSolve创建模型。其中一个州,#foo'实际上由15个不同的状态组成,包括foo [1,1:5],foo [2,1:5]和foo [3,1:5]所以我认为最简单的方法是将函数传递给状态矩阵而不是单独输入,然后我可以用索引来引用它们:

  par <- rep(NA,3)
  par_names <- c('alpha','prog','death_rate')
  names(par) <-par_names
  par['alpha'] <- 0.7
  par['prog'] <- 0.8
  par['death_rate'] <- 0.3

  foo <- matrix(0,nrow = 3,ncol = 5)

  states <- foo

  my_func <- function(t,states,par){
    with(as.list(c(states,par)),{

      for (j in 1:5){
        dfoo[1,j] <-  par['alpha']*par['prog']*foo[1,j] - par['death_rate']*foo[1,j]
        dfoo[2,j] <- par['prog']*foo[1,j] - par['prog']*foo[2,j] - par['death_rate']*foo[2,j]
        dfoo[3,j] <- par['prog']*foo[2,j] - par['prog']*foo[3,j] - par['death_rate']*foo[3,j]
      }


      list(c(
        dfoo[]
      ))
    })
  }

  times <- seq(1,365,by=1)

  library(deSolve)

  alldata <- as.data.frame(ode(y=states,times=times,func=my_func,parms=par))

我已经尝试修复它,但我一直都遇到同样的错误:

 Error in dfoo[1, j] <- par["alpha"] * par["prog"] * foo[1, j] - par["death_rate"] *  : 
  object 'dfoo' not found  

所以有人知道这可能会如何使用或更简单的方法吗?

1 个答案:

答案 0 :(得分:1)

是的,您可以将矩阵作为状态传递。但每次ode调用您的函数时(第一次除外),它都会传递vector而不是matrix。但您可以在函数开头将其转换为矩阵。

您使用不必要的扭曲来创建数据。此外,正如评论中所指出的,您的函数似乎不会初始化dfoo。最后,使用一些矢量化操作可以更清晰地处理函数中的for循环。这是一个例子:

my_func <- function(t,states,par){
    foo <- matrix(states, nrow = 3, ncol = 5)
    dfoo <- with(as.list(par), rbind(    
      (prog * alpha * foo[1,]) - (death_rate * foo[1,]),
      (prog * foo[-nrow(foo),]) - (prog * foo[-1,]) - (death_rate * foo[-1,])
    ))
    list(dfoo)
}

library(deSolve)
par <- c(alpha = 0.7, prog = 0.8, death_rate = 0.3)
states <- matrix(0,nrow = 3,ncol = 5)
ode <- ode(y=states, times=1:365, func=my_func, parms=par)
alldata <- as.data.frame(ode)