Nothing
#' Add linear indirect response model
#'
#' @param ui rxode2 model
#'
#' @param stim what type of stimulation indirect response model:
#'
#' - `in`: stimulation of input
#'
#' - `out`: stimulation of output
#'
#' @param inhib what type of inhibition indirect response model:
#'
#' - `in`: inhibition of input
#'
#' - `out`: inhibition of output
#'
#' @param ek simulation linear constant
#'
#' @param ik inhibition linear constant
#'
#' @param kin this is the kin parameter name
#'
#' @param kout this is the kout parameter name
#'
#' @param R drug response compartment
#'
#' @param cc the concentration value
#'
#' @param effect the effect variable that will be modeled
#'
#' @return model with linear indirect effect added
#'
#' Note that while linear indirect effects are not common, it allows an easier
#' hook to produce other standard effect curves like Emax/Imax, Hill, etc.
#'
#' @export
#' @author Matthew L. Fidler
#' @family Indirect response
#' @examples
#'
#' readModelDb("PK_2cmt_no_depot") |> addIndirectLin(stim="in")
#'
#' readModelDb("PK_2cmt_no_depot") |> addIndirectLin(stim="out")
#'
#' readModelDb("PK_2cmt_no_depot") |> addIndirectLin(inhib="in")
#'
#' readModelDb("PK_2cmt_no_depot") |> addIndirectLin(inhib="out")
#'
addIndirectLin <- function(ui,
stim=c("in", "out"),
inhib=c("in", "out"),
ek="Ek",
ik="Ik",
kin="kin", kout="kout",
cc="Cc",
R="R",
effect="effect") {
if ((missing(stim) && missing(inhib)) ||
(!missing(stim) && !missing(inhib))) {
stop("need either 'stim' or 'inhib' specified",
call.=FALSE)
}
.doStim <- FALSE
if (!missing(stim)) {
if (missing(ui)) {
return(fakeCc(addIndirectLin, stim=stim,
ek=ek, ik=ik,
kin=kin, kout=kout,
cc=cc,
R=R,
effect=effect))
}
.doStim <- TRUE
stim <- match.arg(stim)
} else {
if (missing(ui)) {
return(fakeCc(addIndirectLin, stim=stim,
ek=ek, ik=ik,
kin=kin, kout=kout,
cc=cc,
R=R,
effect=effect))
}
inhib <- match.arg(inhib)
}
.effectSd <- defaultCombine(effect, "sd")
.ui <- rxode2::assertRxUi(ui)
rxode2::assertExists(.ui, cc)
rxode2::assertVariableNew(.ui, kin)
rxode2::assertVariableNew(.ui, kout)
rxode2::assertCompartmentNew(.ui, R)
rxode2::assertVariableNew(.ui, effect)
rxode2::assertVariableNew(.ui, .effectSd)
.modelLines <- .ui$lstExpr
if (.doStim) {
rxode2::assertVariableNew(.ui, ek)
if (stim == "in") {
.eff <- str2lang(paste0("d/dt(", R, ") <- ", kin,
"*(1+", ek, "*", cc, ") - ", kout, "*", R))
} else {
.eff <- str2lang(paste0("d/dt(", R, ") <- ", kin,
" - ", kout, "*", R, "*(1+", ek, "*", cc, ")"))
}
} else {
rxode2::assertVariableNew(.ui,ik)
if (inhib == "in") {
.eff <- str2lang(paste0("d/dt(", R, ") <- ", kin,
"*(1-", ik, "*", cc, ") - ", kout, "*", R))
} else {
.eff <- str2lang(paste0("d/dt(", R, ") <- ", kin,
" - ", kout, "*", R, "*(1-", ik, "*", cc, ")"))
}
}
.modelLines <- c(list(str2lang(paste0(kin, " <- exp(l", kin,")")),
str2lang(paste0(kout, " <- exp(l", kout,")")),
str2lang(ifelse(.doStim,
paste0(ek, " <- exp(l", ek,")"),
paste0(ik, " <- exp(l", ik,")")))),
.modelLines,
list(str2lang(paste0(R, "(0) <- ", kin, "/", kout)),
.eff,
str2lang(paste0(effect, " <- ", R)),
str2lang(paste0(effect, " ~ add(", .effectSd, ")"))))
.tmp <- .getEtaThetaTheta1(.ui)
.iniDf <- .tmp$iniDf
.theta <- .tmp$theta
.theta1 <- .tmp$theta1
.eta <- .tmp$eta
if(length(.theta$ntheta) == 0) {
.ntheta <- 0
} else {
.ntheta <- max(.theta$ntheta)
}
.thetaKin <- .get1theta(kin, .theta1, .ntheta,
label=paste0("zero order response production(", kin, ")"))
.ntheta <- .ntheta + 1
.thetaKout <- .get1theta(kout, .theta1, .ntheta,
label=paste0("first order rate response loss (", kout, ")"))
.ntheta <- .ntheta + 1
if (.doStim) {
.thetaK <- .get1theta(ek, .theta1, .ntheta,
label=paste0("linear effect constant (", ek, ")"))
} else {
.thetaK <- .get1theta(ik, .theta1, .ntheta,
lower= -Inf, upper=1,
label=paste0("linear inhibition constant (", ik, ")"))
}
.ntheta <- .ntheta + 1
.thetaErr <- .get1theta(.effectSd, .theta1, .ntheta,
lower=0,
label=paste0("additive error for ", effect),
name=.effectSd)
.thetaErr$condition <- effect
.thetaErr$err <- "add"
.ui <- rxode2::rxUiDecompress(.ui)
.ui$iniDf <- rbind(.theta,
.thetaKin,
.thetaKout,
.thetaK,
.thetaErr,
.eta)
if (exists("description", envir=.ui$meta)) {
rm("description", envir=.ui$meta)
}
rxode2::model(.ui) <- .modelLines
.ui
}
#' Add an indirect response model to a PK model
#'
#' @inheritParams addIndirectLin
#' @inheritParams convertEmaxHill
#' @param hill Boolean stating if a hill sigmoid coefficient will be added
#' @param imax maximum inhibitory concentration
#' @param ic50 concentration where half of the Imax occurs
#' @return pk model with indirect response model added
#' @export
#' @author Matthew L. Fidler
#' @family Indirect response
#' @examples
#'
#' readModelDb("PK_2cmt_no_depot") |>
#' addIndirect(stim="in",hill=TRUE)
#'
#' readModelDb("PK_2cmt_no_depot") |>
#' addIndirect(inhib="out", imax=1)
addIndirect <- function(ui,
stim=c("in", "out"),
inhib=c("in", "out"),
hill=FALSE,
ek="Ek",
ik="Ik",
emax="Emax",
ec50="EC50",
imax="Imax",
ic50="IC50",
kin="kin", kout="kout",
g="g",
cc="Cc",
R="R",
effect="effect") {
if ((missing(stim) && missing(inhib)) ||
(!missing(stim) && !missing(inhib))) {
stop("need either 'stim' or 'inhib' specified",
call.=FALSE)
}
.doStim <- FALSE
if (!missing(stim)) {
.doStim <- TRUE
stim <- match.arg(stim)
} else {
inhib <- match.arg(inhib)
}
if (.doStim) {
.mod1 <- addIndirectLin(ui, stim=stim,
ek=ek,
ik=ek,
kin=kin, kout=kout,
cc=cc,
R=R,
effect=effect)
if (hill) {
convertEmaxHill(.mod1, emax=emax, ec50=ec50, g=g,
ek=ek, cc=cc)
} else {
convertEmax(.mod1, emax=emax, ec50=ec50,
ek=ek, cc=cc)
}
} else {
.mod1 <- addIndirectLin(ui, inhib=inhib,
ek=ik,
ik=ik,
kin=kin, kout=kout,
cc=cc,
R=R,
effect=effect)
if (hill) {
convertEmaxHill(.mod1, emax=imax, ec50=ic50, g=g,
ek=ik, cc=cc)
} else {
convertEmax(.mod1, emax=imax, ec50=ic50,
ek=ik, cc=cc)
}
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.