【发布时间】:2022-01-22 05:14:05
【问题描述】:
我希望建立一个人口动态模型,其中每个参数值对应于当天的温度。例如
简单模型
library(deSolve)
set.seed(1)
pars <- c(alpha = 1, beta = 0.2, delta = 0.5, gamma = 0.2)
lv_model <- function(pars, times = seq(0, 50, by = 1)) {
# initial state
state <- c(x = 1, y = 2)
# derivative
deriv <- function(t, state, pars) {
with(as.list(c(state, pars)), {
d_x <- alpha * x - beta * x * y
d_y <- delta * beta * x * y - gamma * y
return(list(c(x = d_x, y = d_y)))
})
}
# solve
ode(y = state, times = times, func = deriv, parms = pars)
}
lv_results <- lv_model(pars = pars, times = seq(0, 50, by = 1))
我现在想使用一系列每日温度
DailyTemperature<-floor(runif(50,0,40))
并使参数值成为温度的函数
TraitTemperature<-seq(1,40,1)
#trait responses to temperature
alpha<- abs(rnorm(40,mean = 0.5,sd=1))
beta<- abs(rnorm(40,mean = 0.2,sd=0.5))
delta<-abs(rnorm(40,mean=1,sd=2))
gamma<- seq(0.025,1,0.025)
parameters<-as.data.frame(cbind(TraitTemperature,alpha,beta,delta,gamma))
这样对于迭代的每个时间步,它都会查看每日温度,然后在参数数据框中找到相应的温度值。
回顾档案,我看到 if/else 语句用于在特定时间步更改单个参数和使用强制函数,但我认为它们不适用于这里。
我希望这是有道理的,我对如何使它起作用的想法很感兴趣。到目前为止,我还尝试使用 for loop 遍历每日温度列表,然后使用 match 函数来识别值,但这并没有利用每日时间步长。
【问题讨论】:
-
对
deSolve没有太多经验,但我确实使用迭代方法进行了很多此类动态建模。因此,解决此问题的另一种方法可能是将您的 DE 转换为一种格式,其中y在时间t的值是时间t-1的函数。然后在循环中迭代函数。如果速度是个问题,最好在 Rcpp 中进行此迭代,因为 R 在这种情况下会变得有点慢。 -
如果我理解正确的话,这就是我们所说的强制。您可以在 deSolve 帮助页面
?forcings或例如以下页面中找到更多相关信息:tpetzoldt.github.io/deSolve-forcing/deSolve-forcing.html -
有几种方法可以做到这一点。一种想法是根据温度为参数创建 4 个信号,但如果信号的索引(例如温度)与时间向量完全对应,也可以通过索引访问来实现(见下文)。另一种方法是使用 simecol 包中的
approxTime1,它能够一次返回整个参数值向量。最后,它也可以通过回调来完成,其中parms是一个进行任意插值的函数。
标签: r for-loop iteration ode desolve