使用优化估计具有不同常数的多个时间序列的参数

时间:2019-06-20 21:23:40

标签: r ode

我正在尝试使用多个时间序列来估计模型参数,其中时间序列之间的常数值不同。为了便于说明,我将使用逻辑增长模型作为示例。

我已经能够从多个时间序列(N1和N2)中使用相同的常数K来估计参数(r)。

#Data; needs to be matrix instead of data frame
 dat <- as.matrix(cbind(time=seq(0,166,by=16),
         N1=c(0.020,0.030,0.060,0.100,0.160,0.26,0.360,0.50,0.70,0.800,0.90),
         N2=c(0.015,0.033,0.062,0.106,0.162,0.26,0.306,0.51,0.76,0.821,0.91)))

 #dynamical model to estimate r
 dNdt.model=function(t,x,params){
   N <- x
   with(as.list(c(params)), {
     dN <- r*N*(1-(N/K))
     list(c(dN))
   })
 }

 #sse objective function
 sse.dNdt=function(dNparams, data, Kfix=1){
   t <- data[,1]
   N <- data[,-1]
   N0 <- data[1,-1] 
   K <- Kfix
   r0 <- dNparams
   out <- as.data.frame(ode(y=N0, times=t, func=dNdt.model, parms=c(r=r0, K=K)))
   sse <- sum((out[2]-N)^2) + sum((out[3]-N)^2) #SSE needs to be sum of all trajectories
 }

 #run optim
 dNparams <- c(.3) #initial value of r
 optim(dNparams, sse.dNdt, data=dat) #estimate r based on N1 and N2 trajectories

哪个返回预期的输出:

$ par [1] 0.0637207

$ value [1] 4.279062

$个 功能梯度       32 NA

$收敛 [1] 0

$条消息 NULL

如何将这段代码转换为每个时间序列取不同的K值?将Kfix转换为2个值的向量会返回错误:找不到对象“ K”。

1 个答案:

答案 0 :(得分:0)

这是一个使用purrr::map2_dfc为每个时间序列和K值运行模型并返回一个数据帧的解决方案,其中每一列都对应一个时间序列。

# Load package
library(deSolve)

# Data for fitting
dat <- data.frame(time = seq(0, 166, by=16),
                  N1 = c(0.020, 0.030, 0.060, 0.100, 0.160, 
                         0.26, 0.360, 0.50, 0.70, 0.800, 0.90),
                  N2 = c(0.015, 0.033, 0.062, 0.106, 0.162, 
                         0.26, 0.306, 0.51, 0.76, 0.821, 0.91))

# Model
dNdt_model <- function(t, x, params){
  # State variable
  N <- x

  with(as.list(c(params)), {
    # Rate of change
    dN <- r*N*(1-(N/K))

    #Return list
    list(c(dN))
  })
}

下面的代码是唯一真正更改的部分(除了我的强制性整理)。 purrr::map2_dfc遍历每个初始条件和K的值并运行模型。结果绑定到一个数据帧中。最后,从模型结果中减去观测值,然后计算平方和。

#sse objective function
sse_dNdt <- function(dNparams, data, K){
  # Output times
  t <- data[,1]

  # Time series
  N <- data[,-1]

  # Run for each time series (different initial condition, different K value)
  out <- purrr::map2_dfc(.x = data[1,-1], .y = K, 
                         ~ ode(y = .x, times = t, func = dNdt_model, parms = c(r = dNparams, K = .y))[, 2])

  #SSE needs to be sum of all trajectories
  sum((out - N)^2) 
}

但是purrr::map2_dfc的作用是什么?顾名思义,它映射两个变量(map2),它们是初始条件和K值,并返回由绑定列产生的数据帧(df) (c,而不是r行)。

# Initial value of r
dNparams <- c(.3) 

下面,我用optim个值的数组调用K

# Run with different K values for time series N1 and N1
optim(dNparams, sse_dNdt, data = dat, K = c(1, 2))