Nothing
#' Push a future dose or observation event from within an rxode2 model
#'
#' @description
#' `evid_()` is a model-only function that schedules a future dosing or
#' observation event during ODE solving. It is evaluated at each output
#' time point and inserts the requested event into the individual's event
#' timeline for future processing.
#'
#' This function has no meaning outside an rxode2 model block and will
#' throw an error if called directly from R.
#'
#' @param time Numeric. The time at which the event should occur. Must
#' be greater than the current model time `t`; events in the past are
#' silently counted and a warning is issued after solving.
#'
#' @param evid Integer event ID. Follows NONMEM/rxode2 conventions:
#' \describe{
#' \item{`0`}{Observation (adds an output row, no dose).}
#' \item{`1`}{Dose (bolus or infusion depending on `rate`).}
#' \item{`2`}{Other type observation (passed through).}
#' \item{`3`}{Reset all compartments.}
#' \item{`4`}{Reset then dose.}
#' \item{`5`}{Replace compartment amount.}
#' \item{`6`}{Multiply compartment amount.}
#' \item{`7`}{Phantom/transit dose.}
#' \item{`>= 100`}{Classic rxode2 internal evid; passed through verbatim.}
#' }
#'
#' @param amt Numeric dose amount (for dose events) or `0` for
#' observations. When `rate > 0` this is interpreted as the total
#' infusion amount and the infusion duration is `amt / rate`.
#'
#' @param cmt Integer compartment number (1-based) to which the dose is
#' applied. Default is 1
#' @param rate Numeric infusion rate.
#' \describe{
#' \item{`0`}{Bolus dose (default).}
#' \item{`> 0`}{Fixed infusion rate; duration = `amt / rate`.}
#' \item{`-1`}{Rate defined by the model (`rate_<cmt>` variable).}
#' \item{`-2`}{Duration defined by the model (`dur_<cmt>` variable).}
#' }
#' @param ii Numeric inter-dose interval. Used together with `addl` to
#' schedule repeat doses at `time`, `time + ii`, `time + 2*ii`, ...,
#' `time + addl*ii`. Also required when `ss > 0`. Default 0
#' @param addl Integer number of *additional* doses beyond the first.
#' The total number of doses pushed is `addl + 1`, spaced `ii` apart.
#' Each dose is pushed as a standalone event (not as a periodic
#' schedule in the event table).
#' @param ss Integer steady-state flag applied to the *first* dose only
#' (`addl` repetitions always use `ss = 0`).
#' \describe{
#' \item{`0`}{No steady-state (default).}
#' \item{`1`}{Steady-state additive: add SS solution to current state.}
#' \item{`2`}{Steady-state replace: replace current state with SS solution.}
#' }
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `evid_()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time <= t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
#' ## Relationship to NONMEM event columns
#'
#' The argument order and names mirror the standard NONMEM dataset
#' columns: `TIME`, `EVID`, `AMT`, `CMT`, `RATE`, `II`, `ADDL`, `SS`.
#'
#' @seealso [rxSolve()] for the `maxExtra` control argument. Other
#' more convenient ways to interact with adaptive observations and
#' events include [bolus()] [infuse()], [infuseDur()],
#' [reset()].
#'
#' @examples
#' \donttest{
#' # Push a single bolus of 50 mg to compartment 1 at t + 12
#' m <- rxode2({
#' d/dt(depot) <- -ka * depot
#' d/dt(central) <- ka * depot - cl / vd * central
#' cp <- central / vd
#' if (t < 24) {
#' evid_(t + 12, 1, 50, 1, 0, 0, 0, 0)
#' }
#' })
#'
#' # Push three boluses (addl = 2) at t+6, t+18, t+30 (ii = 12)
#' m2 <- rxode2({
#' d/dt(depot) <- -ka * depot
#' d/dt(central) <- ka * depot - cl / vd * central
#' cp <- central / vd
#' if (t < 1) {
#' evid_(t + 6, 1, 50, 1, 0, 12, 2, 0)
#' }
#' })
#' }
#'
#' @export
evid_ <- function(time, evid, amt, cmt=1, rate=0, ii=0, addl=0, ss=0.0) {
stop("'evid_()' can only be used inside an rxode2 model block", call. = FALSE)
}
## Normalize a compartment argument from a matched adaptive-dosing call.
## Accepts the unevaluated `match.call()` element for `cmt` and returns the
## compartment as a bare token for the rxode2 grammar:
## - missing/NULL -> default compartment "1"
## - a string ("depot") -> the bare name `depot` (quotes stripped)
## - a name/number/expr -> its deparsed text
## The string case matters because `deparse1("depot")` keeps the quotes,
## which the grammar then mis-parses (e.g. bolus(50, "depot, 0, 0, 0)).
.rxUdfUiCmt <- function(cmt) {
if (is.null(cmt)) return("1")
if (is.character(cmt)) return(cmt)
deparse1(cmt)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.evid_ <- function(fun) {
.dummy <- function(time, evid, amt, cmt, rate, ii, addl, ss) {}
.mc <- match.call(.dummy, fun)
.time <- deparse1(.mc$time)
.evid <- deparse1(.mc$evid)
.amt <- deparse1(.mc$amt)
.cmt <- .rxUdfUiCmt(.mc$cmt)
.rate <- deparse1(.mc$rate)
if (.rate == "NULL") {
.rate <- "0"
}
.ii <- deparse1(.mc$ii)
if (.ii == "NULL") {
.ii <- "0"
}
.addl <- deparse1(.mc$addl)
if (.addl == "NULL") {
.addl <- "0"
}
.ss <- deparse1(.mc$ss)
if (.ss == "NULL") {
.ss <- "0"
}
list(replace = paste0("evid_(", .time, ",", .evid, ",", .amt, ",", .cmt,
",", .rate, ",", .ii, ",", .addl, ",", .ss, ")"))
}
#' Administer a bolus dose inside a rxode2 model
#'
#' @inheritParams evid_
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `bolus()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
#' @export
#' @author Matthew L. Fidler
bolus <- function(amt, cmt = 1, ii = 0, addl = 0, ss = 0) {
stop("'bolus()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.bolus <- function(fun) {
.dummy <- function(amt, cmt, ii, addl, ss) {}
.mc <- match.call(.dummy, fun)
.amt <- deparse1(.mc$amt)
.cmt <- .rxUdfUiCmt(.mc$cmt)
.ii <- deparse1(.mc$ii)
if (.ii == "NULL") {
.ii <- "0"
}
.addl <- deparse1(.mc$addl)
if (.addl == "NULL") {
.addl <- "0"
}
.ss <- deparse1(.mc$ss)
if (.ss == "NULL") {
.ss <- "0"
}
list(replace = paste0("bolus(", .amt, ",", .cmt, ",", .ii, ",", .addl, ",", .ss, ")"))
}
#' Administer a infusion (with rate being fixed) inside a rxode2 model
#'
#' @inheritParams evid_
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `infuse()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
#' @export
#' @author Matthew L. Fidler
infuse <- function(amt, rate, cmt = 1, ii = 0, addl = 0, ss = 0) {
stop("'infuse()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.infuse <- function(fun) {
.dummy <- function(amt, rate, cmt, ii, addl, ss) {}
.mc <- match.call(.dummy, fun)
.amt <- deparse1(.mc$amt)
.rate <- deparse1(.mc$rate)
.cmt <- .rxUdfUiCmt(.mc$cmt)
.ii <- deparse1(.mc$ii)
if (.ii == "NULL") .ii <- "0"
.addl <- deparse1(.mc$addl)
if (.addl == "NULL") .addl <- "0"
.ss <- deparse1(.mc$ss)
if (.ss == "NULL") .ss <- "0"
list(replace = paste0("infuse(", .amt, ",", .rate, ",", .cmt, ",", .ii, ",", .addl, ",", .ss, ")"))
}
#' Administer a infusion (with duration being fixed) inside a rxode2 model
#'
#' @inheritParams evid_
#'
#' @param dur Numeric infusion duration.
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `infuseDur()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
#' @export
#' @author Matthew L. Fidler
infuseDur <- function(amt, dur, cmt = 1, ii = 0, addl = 0, ss = 0) {
stop("'infuseDur()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.infuseDur <- function(fun) {
.dummy <- function(amt, dur, cmt, ii, addl, ss) {}
.mc <- match.call(.dummy, fun)
.amt <- deparse1(.mc$amt)
.dur <- deparse1(.mc$dur)
.cmt <- .rxUdfUiCmt(.mc$cmt)
.ii <- deparse1(.mc$ii)
if (.ii == "NULL") .ii <- "0"
.addl <- deparse1(.mc$addl)
if (.addl == "NULL") .addl <- "0"
.ss <- deparse1(.mc$ss)
if (.ss == "NULL") .ss <- "0"
list(replace = paste0("infuseDur(", .amt, ",", .dur, ",", .cmt, ",", .ii, ",", .addl, ",", .ss, ")"))
}
#' Reset the rxode2 system in the model
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `reset()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
reset <- function() {
stop("'reset()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' Replace dose the rxode2 system in the model
#'
#' @inheritParams evid_
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `replace()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
replace <- function(amt, cmt = 1) {
stop("'replace()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.replace <- function(fun) {
.dummy <- function(amt, cmt=1) {}
.mc <- match.call(.dummy, fun)
.amt <- deparse1(.mc$amt)
.cmt <- .rxUdfUiCmt(.mc$cmt)
list(replace = paste0("replace(", .amt, ",", .cmt, ")"))
}
#' Multiply dose the rxode2 system in the model
#'
#' @inheritParams evid_
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `multiply()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
multiply <- function(amt, cmt = 1) {
stop("'multiply()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.multiply <- function(fun) {
.dummy <- function(amt, cmt=1) {}
.mc <- match.call(.dummy, fun)
.amt <- deparse1(.mc$amt)
.cmt <- .rxUdfUiCmt(.mc$cmt)
list(replace = paste0("multiply(", .amt, ",", .cmt, ")"))
}
#' Administer a phantom/transit dose inside a rxode2 model
#'
#' @inheritParams evid_
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `phantom()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
#' @export
#' @author Matthew L. Fidler
phantom <- function(amt, cmt = 1, ii = 0, addl = 0, ss = 0) {
stop("'phantom()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.phantom <- function(fun) {
.dummy <- function(amt, cmt, ii, addl, ss) {}
.mc <- match.call(.dummy, fun)
.amt <- deparse1(.mc$amt)
.cmt <- .rxUdfUiCmt(.mc$cmt)
.ii <- deparse1(.mc$ii)
if (.ii == "NULL") {
.ii <- "0"
}
.addl <- deparse1(.mc$addl)
if (.addl == "NULL") {
.addl <- "0"
}
.ss <- deparse1(.mc$ss)
if (.ss == "NULL") {
.ss <- "0"
}
list(replace = paste0("phantom(", .amt, ",", .cmt, ",", .ii, ",", .addl, ",", .ss, ")"))
}
#' Add observations to a model
#'
#'
#' @param ... Numeric values to be added as observations after the
#' current time `t`. They would be added as events with `evid = 0`
#' and `amt = 0` at the specified future time points. The time
#' points are relative to the current model time `t` (i.e.,
#' `obs(12)` adds an observation at `t + 12`). If this is a ui
#' model, you can also specify observations with obs(seq(0, 24,
#' by=0.5)) to add observations every 0.5 time units from t to t+24
#' since it will resolve to the obs() inside of the final rxode2
#' model.
#'
#' @return This function is only meaningful inside an rxode2 model; it
#' returns `NULL` invisibly if called from R directly (after signaling
#' an error).
#'
#' @details
#' ## Behavior inside a model
#'
#' `obs()` is evaluated at every output time point (when the solver is
#' exactly at a scheduled event time). The pushed event is inserted into
#' the individual's event timeline and the solver visits it now or at the
#' specified future time.
#'
#' The number of events that may be pushed per individual is limited by
#' the `maxExtra` argument of [rxSolve()]. When `maxExtra = 0`
#' (the default) there is no limit. Exceeding the limit causes an
#' error.
#'
#' Past-time pushes (where `time < t`) are silently ignored and counted;
#' a warning is issued after solving.
#'
#' @export
#' @author Matthew L. Fidler
obs <- function(...) {
stop("'obs()' can only be used inside an rxode2 model block", call. = FALSE)
}
#' @export
#' @keywords internal
#' @rdname rxUdfUi
rxUdfUi.obs <- function(fun) {
.mc1 <- fun
.mc1[[1]] <- quote(`list`)
.mc1 <- try(eval(.mc1), silent=TRUE)
if (inherits(.mc1, "try-error")) {
list(replace=deparse1(fun))
} else {
.mc1 <- try(unlist(.mc1, recursive=TRUE, use.names=FALSE), silent=TRUE)
if (inherits(.mc1, "try-error")) {
list(replace=deparse1(fun))
} else if (is.numeric(.mc1) || is.integer(.mc1)) {
.obs <- as.character(.mc1)
list(replace = paste0("obs(", paste(.obs, collapse=", "), ")"))
} else {
list(replace=deparse1(fun))
}
}
}
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.