在R

时间:2015-11-06 04:30:55

标签: r optimization

我是R的新手,完全即兴创作(最好的学习方式)

我有一个13年的耦合ODE系统,18个参数和现实世界数据。

ODEs,y是初始条件的向量,t是时间步长,parms是参数:

    Pdot <- function(t, y, parms){
  with(as.list(c(parms, y)), {

dS <- ro*N + z1*phi1*I1 + z4*phi4*I4 - q*t1*lambda*S*I1/N - q*t4*lambda*S*I4/N - mu0*S + (1-l)*alpha*N 
dE1 <- (1-p)*q*t1*lambda*S*I1/N - vL*E1 + (1-y1)*(1-z1)*phi1*I1 - mu0*E1 + (1-r4)*l*alpha*N
dI1 <- p*q*t1*lambda*S*I1/N + vL*E1 - phi1*I1 - mu*I1 - mu0*I1
dE4 <- (1-p)*q*t4*lambda*S*I4/N - vL*E4 + (1-z4)*phi4*I4 - mu0*E4 + r4*l*alpha*N + y1*(1-z1)*phi1*I1
dI4 <- p*q*t4*lambda*S*I4/N + vL*E4 - phi4*I4 - mu*I4 - mu0*I4
dN <- ro*N + alpha*N - mu*(I1 + I4) - mu0*N
dD <- mu*(I1 + I4)

return (list(c(dD, dN, dE1, dE4, dI1, dI4, dS)))
})}

我正在用

解决这些ODE
lsoda(initial.cond, t, Pdot, parms)

我制作了一个目标函数,将lsoda结果与现实世界数据进行比较并返回差异;通过更改参数,我希望尽量减少这种差异。

objective <- function(parms){
s <- lsoda(initial.cond, 1:13, Pdot, parms)
for (i in 2:13){
diffs <-  diffs + abs(s[i,2] - TBDeaths[i]) + abs(s[i,3] - USPopulation[i]) + abs(s[i,6] + s[i,7] - TBCases[i]) + abs(+ s[i,6] - MDRCases[i])}
return(diffs)}

's'有13行7列(每个D,N,E1,E4等),我从第2行开始,将它与真实世界数据进行比较以找出错误,并在每年给出循环我最后的标量差异。我只有4个数据变量,因此我确保在s中调用与该数据相对应的正确列。

此时,使用任何参数集调用目标都有效。

Gen.out <- DEoptim(fn = objective, lower = bound1, upper = bound2)
Gen.out <- GenSA(parms, fn = objective, lower = bound1, upper = bound2)

尝试这两种方法都会给我带来同样的错误:

 Error in eval(expr, envir, enclos) : object 'ro' not found

ro是Pdot中使用的第一个参数。出于某种原因,我可以将任何参数集传递给目标,获得精细结果,但这两个包都无法将其参数集传递给目标。

bound1,bound2和parms是相同的长度,包含相同的参数等。任何帮助将非常感激。

1 个答案:

答案 0 :(得分:1)

优化例程不会创建命名向量并将其传递给目标函数,因此with语句不起作用。

R> with(list(ro=1, b=3), ro + b)
[1] 4
R> with(list(1, 3), ro + b)
Error in eval(expr, envir, enclos) : object 'ro' not found

一个简单但效率较低的解决方案是使用setNames为参数向量添加名称:

R> with(setNames(list(1, 3), c("ro", "b")), ro + b)
[1] 4

更有效的解决方案是直接引用参数向量的元素(例如,在函数体中用ro替换params[1]的所有实例。