library(ggplot2)
library(mrgsolve)
library(nloptr)
library(dplyr)
library(magrittr)
options(mrgsolve.soloc="build")
This is a shortened version of map_bayes.html, showing only the estimation step.
We code up a one-compartment model, with fixed TVCL and TVV. We have
ETA1
and ETA2
as parameters in the model so
that we can update them as the optimizer proceeds. Our goal is to find
the values of ETA
that are most consistent with the
data.
<- '
code $SET request=""
$PARAM ETA1 = 0, ETA2 = 0
$CMT CENT
$PKMODEL ncmt=1
$MAIN
double TVCL = 1.5;
double TVVC = 23.4;
double CL = TVCL*exp(ETA1);
double V = TVVC*exp(ETA2);
$TABLE
capture DV = (CENT/V);
'
<- mcode_cache("map", code) mod
We also have the OMEGA
and SIGMA
matrices
from the population model estimation step.
<- cmat(0.23,-0.78, 0.62)
omega <- solve(omega)
omega.inv <- matrix(0.0032) sigma
Read in the data set. Notice that DV
has value
NA
for dosing records. When calculating the joint
likelihood of all the data, we will remove the missing values (dosing
records don’t have observations that contribute to the likelihood
value).
<- readRDS("map_bayes_data.RDS")
data
head(data)
. # A tibble: 4 × 6
. ID time evid amt cmt DV
. <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
. 1 1 0 1 750 1 NA
. 2 1 0.5 0 0 0 42.7
. 3 1 12 0 0 0 6.93
. 4 1 24 0 0 0 1.37
This function takes in a set of proposed \(\eta\)s along with the observed data vector, the data set and a model object and returns the value of the EBE objective function
When we do the estimation, the fixed effects and random effect variances are fixed.
The estimates are the \(\eta\) for clearance and volume
Arguments:
eta
the current values from the optimizerycol
the observed data column named
the data setm
the model objectdvcol
the predicted data column namepred
if TRUE
, just return predicted
valueseta
is a listeta
is properly named (i.e. ETA1
and ETA2
)eta
into a matrix that is one rowm
) with the current values of
ETA1
and ETA2
d
and save output to
out
objectif(pred)
) return
the simulated data<- function(eta,d,ycol,m,dvcol=ycol,pred=FALSE) {
mapbayes
<- as.numeric(sigma)
sig2 <- as.list(eta)
eta names(eta) <- names(init)
<- eta %>% unlist %>% matrix(nrow=1)
eta_m <- param(m,eta)
m <- mrgsim(m,data=d,output="df")
out if(pred) return(out)
# http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3339294/
<- out[[dvcol]]^2*sig2
sig2j <- log(sig2j) + (1/sig2j)*(d[[ycol]] - out[[dvcol]])^2
sqwres <- diag(eta_m %*% omega.inv %*% t(eta_m))
nOn return(sum(sqwres,na.rm=TRUE) + nOn)
}
<- c(ETA1=-0.3, ETA2=0.2) init
Fit the data
newuoa
is from the nloptr
packageoptim
) could probably also be
usedArguments to newuoa
mapbayes
<- nloptr::newuoa(init,mapbayes,ycol="DV",m=mod,d=data) fit
Here are the final estimates
$par fit
. [1] 0.4995400 -0.3274858
A data set and model to get predictions; this will give us a smooth prediction line
<- data %>% filter(evid==1)
pdata <- mod %>% update(end=24, delta=0.1) pmod
Predicted line based on final estimates
<- mapbayes(fit$par,ycol="DV",pdata,pmod,pred=TRUE) %>% filter(time > 0)
pred head(pred)
. ID time DV
. 1 1 0.1 43.82331
. 2 1 0.2 43.18567
. 3 1 0.3 42.55731
. 4 1 0.4 41.93809
. 5 1 0.5 41.32789
. 6 1 0.6 40.72656
Predicted line based on initial estimates
<- mapbayes(init,ycol="DV",pdata,pmod,,pred=TRUE) %>% filter(time > 0)
initial head(initial)
. ID time DV
. 1 1 0.1 26.13954
. 2 1 0.2 26.03811
. 3 1 0.3 25.93707
. 4 1 0.4 25.83642
. 5 1 0.5 25.73616
. 6 1 0.6 25.63629
Plot
ggplot() +
geom_line(data=pred, aes(time,DV),col="firebrick", lwd=1) +
geom_line(data=initial,aes(time,DV), lty=2, col="darkgreen", lwd=1) +
geom_point(data=data %>% filter(evid==0), aes(time,DV), col="darkslateblue",size=3) +
theme_bw()
mrgsolve: mrgsolve.github.io | metrum research group: metrumrg.com