我正在尝试使用多个时间序列来估计模型参数,其中时间序列之间的常数值不同。为了便于说明,我将使用逻辑增长模型作为示例。
我已经能够从多个时间序列(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”。
答案 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))