求解R中的manipulate()内的微分方程

时间:2014-01-24 17:07:29

标签: r ode

我试图分析一组微分方程中的变化起始条件和变量值(描述疾病通过群体的进展)如何影响系统的动态(如图所示)。我编写了代码并且它运行得很好,但强制我更改一个值,然后重新运行整个代码。

因此我试图将这些代码放在manipulate()中,这样我就可以操作变量并立即看到生成的图形上的效果:

library(deSolve)
library(manipulate)

xyz <- function(time, state, parameters) {
  with(as.list(c(state, parameters)), {
    dt <- 1
    dv <- v0*v1*cos(2*pi*t/33)
    dX <- (v*N-B*X*Y-(mu+N/K)*X)
    dY <- (B*X*Y-(mu+m+g+N/K)*Y)
    dZ <- (g*Y-(mu+N/K)*Z)
    dN <- (v-mu-N/K)*N-m*Y

    return(list(c(dt,dv,dX, dY, dZ, dN)))
  })
}

times <- seq(0,365*3,by = 1)
init <- c(t=0,v=0.02,X=995,Y=5,Z=0,N=1000)
parameters <- c(B=0.14,mu=.01,m=.075,g=.025,K=10000,v0=.02,v1=.5)


manipulate(
  out <- as.data.frame(ode(y = init, times = seq(0,365*3,by=1), func = xyz, parms = parameters)),
  matplot(times,out[4:6],type="l",xlab="Time",ylab="Susceptibles and Recovereds",main="SIR Model",lwd=1,lty=1,bty="l",col=2:4),
  B=slider(0,1,initial=0.14,step=0.01)
)

我不断收到错误消息,无论我是在handleulate()中包含全部或部分代码,在其外部或内部定义变量,还是其他任何内容。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

当我第一次运行代码时,我遇到的错误是:

Error in manipulate(out <- as.data.frame(ode(y = init, times = seq(0,  : 
all controls passed to manipulate must be named

发生此错误是因为操作的第二个参数是matplot()命令而不是命名控件参数(例如滑块)。所以我将前两行放在花括号中,使它们成为单个表达式:

manipulate( {
    out <- as.data.frame(ode(y = init, times = seq(0,365*3,by=1), func = xyz, parms = parameters))
    matplot(times,out[4:6],type="l",xlab="Time",ylab="Susceptibles and Recovereds",main="SIR Model",lwd=1,lty=1,bty="l",col=2:4)
  }, B=slider(0,1,initial=0.14,step=0.01)
)

这消除了错误,但移动滑块对绘图没有任何作用。为什么?因为名为B的滑块未引用传递给manipulate()的表达式中的任何内容。我通过将parameters <- ...行移动到操纵表达式然后更改该行以便存在变量B(不仅仅是列表中的名称)来解决这个问题;换句话说,我们需要B=B而不是B=0.14。现在,当您移动滑块时,情节会发生变化,我相信这就是您想要的:

manipulate( {
    parameters <- c(B=B,mu=.01,m=.075,g=.025,K=10000,v0=.02,v1=.5)
    out <- as.data.frame(ode(y = init, times = seq(0,365*3,by=1), func = xyz, parms = parameters))
    matplot(times,out[4:6],type="l",xlab="Time",ylab="Susceptibles and Recovereds",main="SIR Model",lwd=1,lty=1,bty="l",col=2:4)
  }, B=slider(0,1,initial=0.14,step=0.01)
)

答案 1 :(得分:1)

times <- seq(0,365*3,by = 1)
init <- c(t=0,v=0.02,X=995,Y=5,Z=0,N=1000)

plot.ode <- function(B.param) {
  parameters <- c(B=B.param,mu=.01,m=.075,g=.025,K=10000,v0=.02,v1=.5)
  out <- as.data.frame(ode(y = init, times = seq(0,365*3,by=1), func = xyz, parms = parameters))
  matplot(times,out[4:6],type="l",xlab="Time",ylab="Susceptibles and Recovereds",main="SIR Model",lwd=1,lty=1,bty="l",col=2:4, ylim=c(0,200))
}
manipulate(plot.ode(B), B=slider(0,1,initial=0.14,step=0.01))

似乎有点奇怪,只有红色曲线会受到改变B的影响。