1

I am new to R and totally improvising here (best way to learn)

I have a system of coupled ODEs, 18 parameters, and real world data over 13 years.

ODEs, y is a vector of initial conditions, t are the time steps, parms are parameters:

    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)))
})}

I am solving these ODEs with

lsoda(initial.cond, t, Pdot, parms)

I have made an objective function that compares lsoda results with real world data and returns the difference; By changing the parameters, I am hoping to minimize this difference.

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' has 13 rows and 7 columns (for each D, N, E1, E4, etc) and I start at row 2, compare it to the real world data to find the error, and loop for each year giving me a final scalar difference. I only have 4 variables of data, so I make sure to call the correct columns in s that correspond to that data.

At this point, calling objective with any set of parameters works.

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

Trying both these methods gives me the same error:

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

ro is the first parameter used in Pdot. For some reason, I can pass any parameter set into objective, get fine results, but both these packages are unable to pass their parameter sets into objective.

bound1, bound2, and parms are the same length, contain the same parameters, etc. Any help would be much appreciated.

1 Answer 1

1

The optimization routines do not create and pass named vectors to your objective function, so your with statement doesn't work.

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

A simple, but less efficient solution is to use setNames to add names to the parameter vector:

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

A more efficient solution would be to reference the elements of the parameter vector directly (e.g. replace all instances of ro with params[1] in your function body.

Sign up to request clarification or add additional context in comments.

1 Comment

You know, I have just been introduced to this website, and then someone like you comes, answers my super specific question very quickly, makes my life a ton easier, and now I get to watch DEoptim minimize my function while finding the correct parameters. Thank you so much. Maybe you'd like to help me once more. I have the function being minimized, but the 'bestval' as reported by DEoptim is never related to the value I get when putting the parameters in my objective function manually. Gen.out$optim$bestval [1] 0.2887569 objective(Gen.out$optim$bestmem) [1] 278.3751

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.