评估R中可变数量的表达式

时间:2013-11-26 16:25:56

标签: r differential-equations

我试图解析XML中的表达式,然后在deSolve的ode函数中使用它们。

定义费率的XML位如下所示:

<model name="Lorenz">
    <state_variables>
        <variable id="X" name="x" value="1"/>
        <variable id="Y" name="y" value="1"/>
        <variable id="Z" name="z" value="1"/>
    </state_variables>
    <parameters>
        <variable id="a" name="a" value="-2.66"/>
        <variable id="b" name="b" value="-10"/>
        <variable id="c" name="c" value="28"/>
    </parameters>
    <rates>
        <variable id="dX" name="xchange" value="a*X+Y*Z"/>
        <variable id="dY" name="ychange" value="b*(Y-Z)"/>
        <variable id="dZ" name="zchange" value="-X*Y+c*Y-Z"/>
    </rates>
</model>

在解析变量leafs后,我的R对象看起来像这样:

rates
expression(dX = a * X + Y * Z, dY = b * (Y - Z), dZ = -X * Y +  c * Y - Z)

我的目标是在这样的函数中获取这些表达式,但不是硬编码:

differentialRates= function(t, states, parameters){
  with(as.list(c(states, parameters)),{
    # This works but is still hardcoded:
    dX <- eval(rates[1])
    dY <- eval(rates[2])
    dZ <- eval(rates[3])
    # return the rate of change
    list(c(dX, dY, dZ))
  })
}
out <- ode(y = states, times = times, func = differentialRates, parms = parameters)

因此,如果rates向量因为加载了其他XML而发生更改,则不必更改函数differentialRates

非常感谢任何见解。

编辑正如Justin所要求的那样,我的代码解析了XML,我还将上面的XML扩展为更具包容性。

extractVars = function(doc, model, node, key = "id", value = "value", numeric = FALSE, expression = FALSE){
  path = paste("/models/model[@name='",model, "']/", node, "/variable", sep="") #   Construct xpath
  xvars = xpathSApply(doc, path)  # Retrieve variable leafs
  xvars = sapply(xvars, xmlAttrs) # Retrieve attributes
  vars = as.vector(t(xvars[value,])) # Turn matrix (svars) into vector (vars)
  if(numeric){
    vars = as.numeric(vars)
  }
  if(expression){
    vars = mapply(parse, vars, text=vars)    
  }
  names(vars) = xvars[key,] # Apply names from matrix to vector
  return(vars)
}

检索这样的变量:

parameters = extractVars(doc, model="Lorenz", node="parameters", numeric=TRUE)
states = extractVars(doc, model="Lorenz", node="state_variables", numeric=TRUE)
rates = extractVars(doc, model="Lorenz", node="rates", expression=TRUE)

我的猜测是这样的函数:

differentialRates <- function(t, y, parameters){
  return(lapply(rates, eval))
}

但是这会返回错误:

Error in split.default(rep_len(as.vector(e2), prod(dim(e1))), rep.int(seq_len(ncol(e1)),  : unimplemented type 'expression' in 'split'

0 个答案:

没有答案