The tci
package implements target-controlled infusion
(TCI) algorithms to calculate infusion schedules for compartmental
pharmacokinetic (PK) and pharmacokinetic-pharmacodynamic (PK-PD) models.
Using these infusion schedules, functions in tci
can be
used to simulate PK or PK-PD responses with or without model
misspecification. Generated responses can be used to simulate
closed-loop control by implementing Bayesian updates to the PK or PK-PD
model based on the “observed” (i.e., simulated) data.
Closed-form solutions are provided for one, two, or three compartment
mammillary models (i.e., all peripheral compartments are joined to a
central compartment), as well as a three-compartment model with an
adjoining effect-site. Alternative models, potentially based on ordinary
differential equations (ODE), can be specified using other R packages
and adapted for use with tci
functions (see the “Custom PK
models and algorithms” vignette).
tci
implements both plasma-and effect-site targeting TCI
algorithms based on work by Jacobs (1990) and Shafer and Gregg (1992),
respectively. Users can implement alternative user-defined TCI
algorithms, however. Again, see the “Custom PK models and algorithms”
vignette for further details.
Several population PK models commonly used for TCI are implemented in
tci
. These include the Marsh, Schnider, and Eleveld models
for propofol, and the Minto, Kim, and Eleveld models for remifentanil.
Use of these models is illustrated in the “Population PK models”
vignette.
The tci
package can be installed from CRAN using the
command.
install.packages("tci")
The most recent version can be downloaded from GitHub using the
devtools
package and loaded as follows.
::install_github("jarretrt/tci") devtools
library(tci)
library(ggplot2) # for plotting
Equations implementing 1-, 2-, 3-compartment and 3-compartment-effect
structural PK models are included in the tci
package. The
function pkmod
will automatically infer the correct
structure based on the parameter names.
# 3-compartment model with effect site
<- pkmod(pars_pk = c(cl = 10, q2 = 2, q3 =20, v = 15, v2 = 30, v3 = 50, ke0 = 1.2))) (mod3ecpt
## tci pkmod object
## See ?update.pkmod to modify or add elements
##
## PK model
## 4-compartment PK model
## PK parameters: cl = 10, q2 = 2, q3 = 20, v = 15, v2 = 30, v3 = 50, ke0 = 1.2
## Initial concentrations: (0,0,0,0)
## Plasma compartment: 1
## Effect compartment: 4
##
## Simulation
## Additive error SD: 0
## Multiplicative error SD: 0
## Logged response: FALSE
Acceptable parameter names can be viewed by calling
list_parnms()
. Less-commonly used parameters, such as
clearance from a peripheral compartment, are also permissible.
# acceptable parameter names
list_parnms()
## Acceptable names for 'pars_pk' vector (case-insensitive)
##
## First compartment options
## Central volume: 'v','v1'
## Elimination: 'cl','cl1','k10','ke'
##
## Second compartment options
## Peripheral volume: 'v2'
## Transfer: 'q','q2','k12','k21'
## Elimination: 'cl2','k20'
##
## Third compartment options
## Second peripheral volume: 'v3'
## Transfer: 'q3','k13','k31'
## Elimination: 'cl3','k30'
##
## Effect-site
## Elimination: 'ke0'
Elements of pkmod
objects can be modified through an
update.pkmod
method. Perhaps most usefully, this allows for
partial modifications to PK-PD parameters. For example, the effect-site
equilibrium constant can be easily updated.
update(mod3ecpt, pars_pk = c(ke0 = 0.9), init = c(1,0.2,0.3,1))
## tci pkmod object
## See ?update.pkmod to modify or add elements
##
## PK model
## 4-compartment PK model
## PK parameters: cl = 10, q2 = 2, q3 = 20, v = 15, v2 = 30, v3 = 50, ke0 = 0.9
## Initial concentrations: (1,0.2,0.3,1)
## Plasma compartment: 1
## Effect compartment: 4
##
## Simulation
## Additive error SD: 0
## Multiplicative error SD: 0
## Logged response: FALSE
Most functions in the tci
package pass additional
arguments to update.pkmod
allowing for easy modification of
pkmod
objects as needed.
TCI algorithms are implemented using the function
tci_inf
(manual infusions are implemented by
inf_manual
). The user supplies a set of targets, times at
which the target is set, and a pkmod
object. The TCI
algorithm (defaults to type = "plasma"
) is iteratively
applied to calculate infusion rates required to reach each target in
turn. By default, infusion rates are updated in increments of 1/6,
corresponding to every 10-second intervals if infusions rate units are
in amount per minute. Infusion rates themselves must have the same units
as the PK elimination parameters. If elimination rates are in different
units, such as hours, then the TCI update frequency should be modified
by the argument dtm
.
# effect-site targeting for three-compartment effect site model
<- inf_tci(target_vals = c(2,3,4,4), target_tms = c(0,2,3,10),
inf_3ecpt pkmod = mod3ecpt, type = "effect")
head(inf_3ecpt)
## begin end inf_rate Ct c1_start c2_start c3_start c4_start
## [1,] 0.00000 0.16667 643.6921 2 0.000000 0.00000000 0.0000000 0.0000000
## [2,] 0.16667 0.33333 0.0000 2 6.033672 0.03532348 0.2079682 0.5966263
## [3,] 0.33333 0.50000 0.0000 2 4.301795 0.09138590 0.5235366 1.4096671
## [4,] 0.50000 0.66667 0.0000 2 3.136188 0.13103476 0.7267367 1.8178340
## [5,] 0.66667 0.83333 19.3835 2 2.350071 0.15960595 0.8548449 1.9785480
## [6,] 0.83333 1.00000 0.0000 2 2.000000 0.18174014 0.9390928 2.0109479
## c1_end c2_end c3_end c4_end
## [1,] 6.033672 0.03532348 0.2079682 0.5966263
## [2,] 4.301795 0.09138590 0.5235366 1.4096671
## [3,] 3.136188 0.13103476 0.7267367 1.8178340
## [4,] 2.350071 0.15960595 0.8548449 1.9785480
## [5,] 2.000000 0.18174014 0.9390928 2.0109479
## [6,] 1.586605 0.19939667 0.9931813 1.9678507
Population PK models are implemented by the function
poppkmod
. The user must supply a data frame with the set of
covariates (e.g., weight, age) required by the model. Several published
population PK models are currently implemented in tci
. For
propofol, these include the Marsh, Schnider, and Eleveld models. For
remifentanil, they include the Minto, Kim, and Eleveld models. See
?poppkmod
or the population PK model vignette for details.
list_pkmods()
will list available population PK models and
covariates required by each.
# data frame of patient covariates
<- data.frame(ID = 1:5, AGE = seq(20,60,by=10),
data TBW = seq(60,80,by=5), HGT = seq(150,190,by=10),
MALE = c(TRUE,TRUE,FALSE,FALSE,FALSE))
# Eleveld population PK model for propofol
<- poppkmod(data = data, drug = "ppf", model = "eleveld") pkpd_elvd
As with the pkmod
class, poppkmod
objects
can be used by inf_tci
and have predict
and
simulate
methods to predict and simulate PK-PD responses,
respectively.
PK-PD parameter values can be drawn at random from the
inter-/intra-individual variability distribution, as described by the
pkmod
Omega matrix, by either 1) setting the argument
sample = TRUE
when calling poppkmod
, or 2) by
using the function sample_iiv
.
set.seed(1)
<- sample_iiv(pkpd_elvd) pkpd_elvd_iiv
Simulations are best implemented through the function
simulate_tci
, which allows for model misspecification as
well as Bayesian updates to model parameters based on previously
observed data (i.e., “closed-loop” control). simulate_tci
can be used for both pkmod
or poppkmod
classes. Required arguments to simulate_tci
are 1) a prior
PK model (pkmod_prior
) that is used to calculate infusion
rates and may be updated throughout the simulation if update times are
provided, 2) a true PK model (pkmod_true
) that is used to
simulate observations, 3) TCI target values, 4) TCI target times, and 5)
times to simulate observations.
# TCI target values (PD response)
<- c(75,60,50,50)
target_vals # values are in terms of minutes. 1/6 = 10 seconds
# TCI target times
<- c(0,3,6,10)
target_tms # observation times
<- seq(1/6,10,1/6)
obs_tms
# simulate without updates ("open-loop")
<- simulate_tci(pkmod_prior = pkpd_elvd, pkmod_true = pkpd_elvd_iiv,
sim_ol type = "effect", seed = 1) target_vals, target_tms, obs_tms,
simulate_tci
returns an object with class
sim_tci
that can be plotted using the ggplot2
library.
plot(sim_ol)
Modifications can be made to the plot to show a subset of responses, concentrations instead of PD response values, infusion rates, and simulated data.
plot(sim_ol, yvar = "c4", id = c(1,3,5), show_inf = TRUE, wrap_id = TRUE)
Closed-loop simulations can be implemented by specifying a set of update times. We illustrate this with updates each minute and a processing delay of 20 seconds.
<- simulate_tci(pkmod_prior = pkpd_elvd, pkmod_true = pkpd_elvd_iiv,
sim_cl update_tms = 1:10, delay = 1/3,
target_vals, target_tms, obs_tms, type = "effect", seed = 1)
## [1] "Simulating ID=1"
## [1] "Simulating ID=2"
## [1] "Simulating ID=3"
## [1] "Simulating ID=4"
## [1] "Simulating ID=5"
Since plot.sim_tci
returns a ggplot2
object, it is easy to modify aspects such as titles and axis labels
using ggplot2
functions.
plot(sim_cl) +
xlab("Minutes") +
ylab("Bispectral Index") +
ggtitle("Closed-loop simulation of Eleveld propofol model",
subtitle = "Minute updates, processing delay of 20 seconds")