如何使函数内计算的根可用于函数外

How to make the roots calculated within the function available to be used outside the function

我正在尝试执行以下代码,其中主函数 (LV) 包含另一个函数 (fun_sp),用于在每个时间点查找根。根称为 p。根据我的理解,p 取决于变量 C,它是一个向量并且在每个时间点都会发生变化,因此 p 也应该是一个在每个时间点都发生变化的向量。但是当我输出 p 时,我只得到一个值。我理解错了吗? 任何输入都会有帮助吗?


library(deSolve)

library(rootSolve)

ka = 0.1; CL = 0.2; Ke = 0.3; R = 10; KD = 0.1

LV <- function(time,state, params)

{
C <- state[1]

P <- state[2]

fun_sp <- function(p){p + ((C/R)*p/(p+(KD/R))) -1}

p <<- uniroot.all(fun_sp, c(0,1))

fb <- p/(p+(KD/R))

dC <- fb*ka*C - CL*C + P*CL - Ke*C

dP <- CL*C - P*CL 

list(c(dC, dP))
}

state_ini = c(C=100,P=0)

time = c(seq(1, 24 , 1))

fv <- ode(state_ini, time, LV, parms, method = "lsoda", rtol=1e-6, atol=1e-6, verbose=FALSE)

p

fv = as.data.frame(fv)

str(fv)

您的变量 "p" 将在 LV 函数的每次迭代中被覆盖。好消息是,内部结果可以存储在输出矩阵中,方法是将它们添加到 return 值(即列表)作为导数向量之后的附加参数(例如 root=p)(在您的case c(dC, dP)) 如下:

list(c(dC, dP), root=p)

您的示例可能如下所示,不再需要全局赋值运算符 <<- :

library(deSolve)
library(rootSolve)

ka <- 0.1; CL <- 0.2; Ke <- 0.3; R <- 10; KD <- 0.1

LV <- function(time,state, params) {
  C <- state[1]
  P <- state[2]

  fun_sp <- function(p){p + ((C/R)*p/(p+(KD/R))) -1}

  p <- uniroot.all(fun_sp, c(0,1))
  fb <- p/(p+(KD/R))
  dC <- fb*ka*C - CL*C + P*CL - Ke*C
  dP <- CL*C - P*CL 
  list(c(dC, dP), root=p)
}

state_ini = c(C=100,P=0)
time = c(seq(1, 24 , 1))
fv <- ode(state_ini, time, LV, parms, method = "lsoda", rtol=1e-6, atol=1e-6)

fv

但是请注意,uniroot.all 可能 return 多个值,因此您可以考虑使用统计包中的 'basic' uniroot 函数(没有 .all)。

希望对您有所帮助,托马斯