Convergence assessment
Using lixoftConnectors
The convergence assessment can be run from the command line using the corresponding connector. As in the GUI, the following options can be chosen via the settings: the number of runs, the estimation of the standard errors and likelihood, linearization method and bounds for the sampling of the initial values.
# load and initialize the API
library(lixoftConnectors)
initializeLixoftConnectors(software="monolix")
# load a project from the demos
project <- paste0(getDemoPath(), "/1.creating_and_using_models/1.1.libraries_of_models/theophylline_project.mlxtran")
loadProject(projectFile = project)
# get the default settings and set new values
set <- getAssessmentSettings()
set$nbRuns <- 10
set$extendedEstimation <- T
set$useLin <- T
set$initialParameters <- data.frame(parameters = c("ka_pop","V_pop","Cl_pop"), fixed = FALSE, min=c(0.1, 0.1, 0.01), max=c(10,10,1))
# run the convergence assessment
runAssessment(settings = set)
# retrieve the results
getAssessmentResults()
When using the runAssessment() connector, its is possible to sample the initial value only for the fixed effects (except betas of covariate effects) and the sampling is uniform over an interval. If other strategies are needed, it is possible to implement a custom convergence assessment, as shown below.
Custom convergence assessment
The example below shows the functions to build a project from scratch using one of the demo data sets and a model from the libraries, and run a convergence assessment to evaluate the robustness of the convergence. Compared to the built-in convergence assessment, the strategy below samples new initial values for all parameters instead of fixed effects only, and it does not change the random seed:
# load and initialize the API
library(lixoftConnectors)
initializeLixoftConnectors(software="monolix")
# get folder containing demo datasets
demoPath = paste0(getDemoPath(), '/1.creating_and_using_models/1.1.libraries_of_models/')
# get name of model from library
model <- getLibraryModelName(library="pk",
filters = list(administration="oral",
delay="lagTime",
absorption = "firstOrder",
distribution = "1compartment",
elimination = "linear",
parametrization = "clearance"))
# create a new project by setting a data set and a structural model
newProject(data = list(dataFile = paste0(demoPath,'data/warfarin_data.csv'),
headerTypes =c("id", "time", "amount", "observation", "obsid", "contcov", "catcov", "ignore")),
mapping = list(list(obsId="1", observationName="y1", modelOutput="Cc")),
modelFile = model)
# set tasks in scenario
scenario <- getScenario()
scenario$tasks = c(populationParameterEstimation = T,
conditionalModeEstimation = T,
conditionalDistributionSampling = T,
standardErrorEstimation=T,
logLikelihoodEstimation=T)
scenario$linearization = TRUE
setScenario(scenario)
# ----------------------------------------------------------------------------
# convergence assessment: run 5 estimations with different initial estimates,
# store the results in tabestimates
# ----------------------------------------------------------------------------
popparams <- getPopulationParameterInformation()
tabestimates <- NULL; tabiters <- NULL
for(i in 1:5){
# sample new initial estimates
popini <- sapply(1:nrow(popparams), function(j){runif(n=1, min=popparams$initialValue[j]/2, max=popparams$initialValue[j]*2)})
# set sampled values as new initial estimates
newpopparams <- popparams
newpopparams$initialValue <- popini
setPopulationParameterInformation(newpopparams)
# run the estimation
runScenario()
# store the estimates and s.e. in a table
estimates <- as.data.frame(getEstimatedPopulationParameters())
names(estimates) <- "estimate"
rses <- getEstimatedStandardErrors()$linearization$rse
names(rses) <- getEstimatedStandardErrors()$linearization$parameter
rses <- as.data.frame(rses)
estimates <- merge(estimates, rses, by = "row.names")
estimates$run <- i
names(estimates)[names(estimates) == "Row.names"] <- "param"
tabestimates <- rbind(tabestimates, estimates)
# store the iterations
iters <- getChartsData("plotSaem")
iters$run <- i
tabiters <- rbind(tabiters, iters)
}
# load plotting libraries
library(ggplot2)
library(gridExtra)
# plot SAEM iterations
plotList <- list()
i <- 1
for (param in popparams$name) {
if (popparams[popparams$name == param, ]$method == "FIXED") next
changePhase <- tabiters$iteration[which(diff(tabiters$phase) == 1) + 1]
plotList[[i]] <- ggplot(tabiters, aes_string(x = "iteration", y = param)) +
geom_line(aes(group = run, color = factor(run))) +
theme(legend.position = "none", plot.title = element_text(hjust = .5)) +
geom_vline(xintercept = changePhase, color = 1:length(changePhase)) +
labs(title = param, x = NULL, y = NULL)
i <- i + 1
}
grid.arrange(grobs = plotList, ncol = 3)
# plot population parameters
plotList <- list()
i <- 1
for (param in popparams$name) {
if (popparams[popparams$name == param, ]$method == "FIXED") next
estimates <- tabestimates[tabestimates$param == param, ]
plotList[[i]] <- ggplot(estimates, aes(x = run, y = estimate)) +
geom_point(aes(color = factor(run))) +
geom_errorbar(aes(ymax = estimate * (1+rses/100), ymin = estimate * (1-rses/100), color = factor(run))) +
theme(legend.position = "none", plot.title = element_text(hjust = .5)) +
labs(title = param, x = NULL, y = NULL)
i <- i + 1
}
grid.arrange(grobs = plotList, ncol = 3)