[英]run deSolve multiple times varying a time-varying parameter
我想让此代码重复运行,为每个运行创建一个具有不同列变量的单个输出数据集。 现在,该代码可以正常工作,并允许我在不同的时间插入不同的事件。 但是,我希望能够更改事件的规模,
IPT <- ifelse (t<210, IPT, 0.35*exp(-(t-209)/21))
将0.35调整为0.4、0.5、0.6等。我尝试了For循环,但根本无法正常工作。 我的代码如下:
library(deSolve)
##Simple parameter list
params <- c(b = 0.477, bs = .4, bsv = 0.1, nets = 0.4767, betah = 0.2,
rhos = 179, Bthetas = 0.2, psi = 14,phis = 0.5, gamma =14,
thetas = 0.79,piv = 1/19, betav = 0.09122, nu = 0.2085, sigma = 12,
muv = 1/19, IPT = 0, IPT2 = 0, IPT3 = 0)
dt <- seq(0, 5000, 7)
inits <- c(Ss = 30000, Is = 0, As = 0, Rs = 0,
Sv = 29999, Ev = 0, Iv = 1)
Nh <- 30000
Nv <- 30000
## Create an SIR function
sir1 <- function(t, x, params) {
with(as.list(c(params, x)), {
IPT <- ifelse (t<210, IPT, 0.35*exp(-(t-209)/21))
dSs <- -((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss /Nh + As*(1/rhos)*(1-Bthetas) + Rs*(1/psi)
dIs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*(1-phis)/Nh - 1/gamma * Is - Is*(IPT + IPT2 + IPT3)
dAs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*( phis)/Nh + 1/gamma * Is*(1-thetas) - As*(1/rhos)*(1-Bthetas) - As*(2/rhos)*Bthetas - As*(IPT + IPT2 + IPT3)
dRs <- 1/gamma * Is*( thetas) + As*(2/rhos)*Bthetas + Is*(IPT2 + IPT3+ IPT) + As*(IPT + IPT2 + IPT3) - Rs*(1/psi)
dSv <- piv*Nv - Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Sv*muv
dEv <- Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Ev*(1/sigma + muv)
dIv <- Ev*(1/sigma)- Iv*muv
der <- c(dSs, dIs, dAs, dRs,
dSv, dEv, dIv)
list(der)
})
}
out <- as.data.frame(lsoda(inits, dt, sir1, parms = params))
out$prev <- with(out, Is+As/Nh)
我希望最终数据集具有多个prev列,每个列用于具有不同事件值的每次运行。
任何帮助,将不胜感激,谢谢!
潜在的解决方案是将幅度作为参数而不是常数(在这里我将其称为mag
)。
library(deSolve)
##Simple parameter list
params <- c(b = 0.477, bs = .4, bsv = 0.1, nets = 0.4767, betah = 0.2,
rhos = 179, Bthetas = 0.2, psi = 14,phis = 0.5, gamma =14,
thetas = 0.79,piv = 1/19, betav = 0.09122, nu = 0.2085, sigma = 12,
muv = 1/19, IPT = 0, IPT2 = 0, IPT3 = 0, mag=0.35)
dt <- seq(0, 5000, 7)
inits <- c(Ss = 30000, Is = 0, As = 0, Rs = 0,
Sv = 29999, Ev = 0, Iv = 1)
Nh <- 30000
Nv <- 30000
然后我们可以调整sir1
函数以使用mag
参数...
## Create an SIR function
sir1 <- function(t, x, params) {
with(as.list(c(params, x)), {
IPT <- ifelse (t<210, IPT, mag*exp(-(t-209)/21))
dSs <- -((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss /Nh + As*(1/rhos)*(1-Bthetas) + Rs*(1/psi)
dIs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*(1-phis)/Nh - 1/gamma * Is - Is*(IPT + IPT2 + IPT3)
dAs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*( phis)/Nh + 1/gamma * Is*(1-thetas) - As*(1/rhos)*(1-Bthetas) - As*(2/rhos)*Bthetas - As*(IPT + IPT2 + IPT3)
dRs <- 1/gamma * Is*( thetas) + As*(2/rhos)*Bthetas + Is*(IPT2 + IPT3+ IPT) + As*(IPT + IPT2 + IPT3) - Rs*(1/psi)
dSv <- piv*Nv - Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Sv*muv
dEv <- Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Ev*(1/sigma + muv)
dIv <- Ev*(1/sigma)- Iv*muv
der <- c(dSs, dIs, dAs, dRs,
dSv, dEv, dIv)
list(der)
})
}
...,然后我们可以在循环中修改params
向量,该循环也可以运行模型,获取输出,计算prev
并将其存储在out
data.frame中。
out <- as.data.frame(lsoda(inits, dt, sir1, parms = params))
magz <- seq(0.2, 0.5, length.out=10)
for(i in 1:length(magz)){
params['mag'] <- magz[i]
tmp <- as.data.frame(lsoda(inits, dt, sir1, parms = params))
nm <- paste('prev', round(params['mag'],2), sep='')
out[,nm] <- with(tmp, Is+As/Nh)
}
可能有更好的方法来做您想做的事情,但这是一个潜在的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.