aboutsummaryrefslogtreecommitdiff
path: root/R
diff options
context:
space:
mode:
Diffstat (limited to 'R')
-rw-r--r--R/endpoints.R1
-rw-r--r--R/mkinfit.R6
-rw-r--r--R/mkinpredict.R20
-rw-r--r--R/multistart.R4
-rw-r--r--R/parplot.R19
-rw-r--r--R/plot.mixed.mmkin.R4
-rw-r--r--R/saem.R42
7 files changed, 78 insertions, 18 deletions
diff --git a/R/endpoints.R b/R/endpoints.R
index c3e0a0d3..70a9eef3 100644
--- a/R/endpoints.R
+++ b/R/endpoints.R
@@ -45,6 +45,7 @@ endpoints <- function(fit, covariates = NULL, covariate_quantile = 0.5) {
if (!is.null(fit$covariate_models)) {
if (is.null(covariates)) {
+ # Use covariate quantiles if no explicit covariates are given
covariates = as.data.frame(
apply(fit$covariates, 2, quantile,
covariate_quantile, simplify = FALSE))
diff --git a/R/mkinfit.R b/R/mkinfit.R
index c851fddb..52053685 100644
--- a/R/mkinfit.R
+++ b/R/mkinfit.R
@@ -21,7 +21,8 @@ utils::globalVariables(c("name", "time", "value"))
#' "FOMC", "DFOP", "HS", "SFORB", "IORE"). If a shorthand name is given, a
#' parent only degradation model is generated for the variable with the
#' highest value in \code{observed}.
-#' @param observed A dataframe with the observed data. The first column called
+#' @param observed A dataframe or an object coercible to a dataframe
+#' (e.g. a \code{tibble}) with the observed data. The first column called
#' "name" must contain the name of the observed variable for each data point.
#' The second column must contain the times of observation, named "time".
#' The third column must be named "value" and contain the observed values.
@@ -292,6 +293,9 @@ mkinfit <- function(mkinmod, observed,
# Get the names of observed variables
obs_vars <- names(mkinmod$spec)
+ # Coerce observed data to a dataframe
+ observed <- as.data.frame(observed)
+
# Subset observed data with names of observed data in the model and remove NA values
observed <- subset(observed, name %in% obs_vars)
observed <- subset(observed, !is.na(value))
diff --git a/R/mkinpredict.R b/R/mkinpredict.R
index 4c6d7862..2c865cb7 100644
--- a/R/mkinpredict.R
+++ b/R/mkinpredict.R
@@ -172,6 +172,15 @@ mkinpredict.mkinmod <- function(x,
}
if (solution_type == "deSolve") {
+
+ # We need to make sure that 0 is included in outtimes,
+ # even if we do not have observed data for time zero,
+ # because otherwise the initial values are not applied
+ # to time zero but to the time of the first observation
+ # in the data
+ if (min(outtimes) > 0) outtimes_deSolve <- c(0, outtimes)
+ else outtimes_deSolve <- outtimes
+
if (!is.null(x$cf) & use_compiled[1] != FALSE) {
if (!is.null(x$symbols) & use_symbols) {
@@ -182,7 +191,7 @@ mkinpredict.mkinmod <- function(x,
out <- deSolve::lsoda(
y = odeini,
- times = outtimes,
+ times = outtimes_deSolve,
func = lsoda_func,
initfunc = "initpar",
dllname = x$dll_info[["name"]],
@@ -209,7 +218,7 @@ mkinpredict.mkinmod <- function(x,
}
out <- deSolve::ode(
y = odeini,
- times = outtimes,
+ times = outtimes_deSolve,
func = mkindiff,
parms = odeparms,
method = method.ode,
@@ -219,6 +228,13 @@ mkinpredict.mkinmod <- function(x,
...
)
}
+
+ # Now we need to remove time zero, in case we did not
+ # have observations for it
+ if (min(outtimes) > 0) {
+ out <- out[-1, ]
+ }
+
n_out_na <- sum(is.na(out))
if (n_out_na > 0 & na_stop) {
cat("odeini:\n")
diff --git a/R/multistart.R b/R/multistart.R
index aeea2d81..4ba82a43 100644
--- a/R/multistart.R
+++ b/R/multistart.R
@@ -40,7 +40,7 @@
#' f_mmkin <- mmkin("DFOP", dmta_ds, error_model = "tc", cores = 7, quiet = TRUE)
#' f_saem_full <- saem(f_mmkin)
#' f_saem_full_multi <- multistart(f_saem_full, n = 16, cores = 16)
-#' parplot(f_saem_full_multi, lpos = "topleft")
+#' parplot(f_saem_full_multi, lpos = "topleft", las = 2)
#' illparms(f_saem_full)
#'
#' f_saem_reduced <- update(f_saem_full, no_random_effect = "log_k2")
@@ -50,7 +50,7 @@
#' library(parallel)
#' cl <- makePSOCKcluster(12)
#' f_saem_reduced_multi <- multistart(f_saem_reduced, n = 16, cluster = cl)
-#' parplot(f_saem_reduced_multi, lpos = "topright", ylim = c(0.5, 2))
+#' parplot(f_saem_reduced_multi, lpos = "topright", ylim = c(0.5, 2), las = 2)
#' stopCluster(cl)
#' }
multistart <- function(object, n = 50,
diff --git a/R/parplot.R b/R/parplot.R
index 3da4b51a..a33112a5 100644
--- a/R/parplot.R
+++ b/R/parplot.R
@@ -35,9 +35,6 @@ parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, llquant = NA,
scale = c("best", "median"),
lpos = "bottomleft", main = "", ...)
{
- oldpar <- par(no.readonly = TRUE)
- on.exit(par(oldpar, no.readonly = TRUE))
-
orig <- attr(object, "orig")
orig_parms <- parms(orig)
start_degparms <- orig$mean_dp_start
@@ -59,11 +56,10 @@ parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, llquant = NA,
selected <- which(ll > llmin)
selected_parms <- all_parms[selected, ]
- par(las = 1)
if (orig$transformations == "mkin") {
degparm_names_transformed <- names(start_degparms)
degparm_index <- which(names(orig_parms) %in% degparm_names_transformed)
- orig_parms[degparm_names_transformed] <- backtransform_odeparms(
+ orig_degparms <- backtransform_odeparms(
orig_parms[degparm_names_transformed],
orig$mmkin[[1]]$mkinmod,
transform_rates = orig$mmkin[[1]]$transform_rates,
@@ -74,14 +70,17 @@ parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, llquant = NA,
transform_fractions = orig$mmkin[[1]]$transform_fractions)
degparm_names <- names(start_degparms)
- names(orig_parms) <- c(degparm_names, names(orig_parms[-degparm_index]))
+ orig_parms_back <- orig_parms
+ orig_parms_back[degparm_index] <- orig_degparms
+ names(orig_parms_back)[degparm_index] <- degparm_names
+ orig_parms <- orig_parms_back
selected_parms[, degparm_names_transformed] <-
t(apply(selected_parms[, degparm_names_transformed], 1, backtransform_odeparms,
orig$mmkin[[1]]$mkinmod,
transform_rates = orig$mmkin[[1]]$transform_rates,
transform_fractions = orig$mmkin[[1]]$transform_fractions))
- colnames(selected_parms)[1:length(degparm_names)] <- degparm_names
+ colnames(selected_parms)[degparm_index] <- degparm_names
}
start_errparms <- orig$so@model@error.init
@@ -99,6 +98,12 @@ parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, llquant = NA,
# Boxplots of all scaled parameters
selected_scaled_parms <- t(apply(selected_parms, 1, function(x) x / parm_scale))
+ i_negative <- selected_scaled_parms <= 0
+ parms_with_negative_scaled_values <- paste(names(which(apply(i_negative, 2, any))), collapse = ", ")
+ if (any(i_negative)) {
+ warning("There are negative values for ", parms_with_negative_scaled_values, " which are set to NA for plotting")
+ }
+ selected_scaled_parms[i_negative] <- NA
boxplot(selected_scaled_parms, log = "y", main = main, ,
ylab = "Normalised parameters", ...)
diff --git a/R/plot.mixed.mmkin.R b/R/plot.mixed.mmkin.R
index d6c3d0de..058e01a8 100644
--- a/R/plot.mixed.mmkin.R
+++ b/R/plot.mixed.mmkin.R
@@ -93,7 +93,7 @@ plot.mixed.mmkin <- function(x,
nrow.legend = ceiling((length(i) + 1) / ncol.legend),
rel.height.legend = 0.02 + 0.07 * nrow.legend,
rel.height.bottom = 1.1,
- pch_ds = 1:length(i),
+ pch_ds = c(1:25, 33, 35:38, 40:41, 47:57, 60:90)[1:length(i)],
col_ds = pch_ds + 1,
lty_ds = col_ds,
frame = TRUE, ...
@@ -157,7 +157,7 @@ plot.mixed.mmkin <- function(x,
ifelse(length(x$covariate_models) == 1,
"Covariate", "Covariates"),
rownames(covariates))
- }
+ }
degparms_pop <- parms(x, covariates = covariates)
pop_curves <- TRUE
}
diff --git a/R/saem.R b/R/saem.R
index a9f97d23..2a9c2fa5 100644
--- a/R/saem.R
+++ b/R/saem.R
@@ -50,6 +50,9 @@ utils::globalVariables(c("predicted", "std"))
#' initialisation of [saemix::saemixModel] is used for omega.init.
#' @param covariates A data frame with covariate data for use in
#' 'covariate_models', with dataset names as row names.
+#' @param center_covariates Either NA, for no centering, or your
+#' preferred function for calculating the center, currently either
+#' median or mean.
#' @param covariate_models A list containing linear model formulas with one explanatory
#' variable, i.e. of the type 'parameter ~ covariate'. Covariates must be available
#' in the 'covariates' data frame.
@@ -148,6 +151,7 @@ saem.mmkin <- function(object,
omega.init = "auto",
covariates = NULL,
covariate_models = NULL,
+ center_covariates = c(NA, "median", "mean"),
no_random_effect = NULL,
error.init = c(1, 1),
nbiter.saemix = c(300, 100),
@@ -158,6 +162,18 @@ saem.mmkin <- function(object,
{
call <- match.call()
transformations <- match.arg(transformations)
+ center_covariates <- match.arg(center_covariates)
+ if (is.na(center_covariates)) {
+ covariate_centers <- NA
+ centered_covariates <- NA
+ } else {
+ center_covariate_func <- get(center_covariates)
+ centered_covariates <- data.frame(lapply(covariates,
+ function(x) x - center_covariate_func(x)))
+ rownames(centered_covariates) <- rownames(covariates)
+ covariate_centers <- sapply(covariates, center_covariate_func)
+ }
+
m_saemix <- saemix_model(object, verbose = verbose,
error_model = error_model,
degparms_start = degparms_start,
@@ -166,12 +182,14 @@ saem.mmkin <- function(object,
transformations = transformations,
covariance.model = covariance.model,
omega.init = omega.init,
- covariates = covariates,
+ covariates = if (is.na(center_covariates)) covariates else centered_covariates,
covariate_models = covariate_models,
error.init = error.init,
no_random_effect = no_random_effect,
...)
- d_saemix <- saemix_data(object, covariates = covariates, verbose = verbose)
+ d_saemix <- saemix_data(object,
+ covariates = if (is.na(center_covariates)) covariates else centered_covariates,
+ verbose = verbose)
fit_failed <- FALSE
FIM_failed <- NULL
@@ -227,6 +245,8 @@ saem.mmkin <- function(object,
transform_rates = object[[1]]$transform_rates,
transform_fractions = object[[1]]$transform_fractions,
covariates = covariates,
+ centered_covariates = centered_covariates,
+ covariate_centers = covariate_centers,
covariate_models = covariate_models,
sm = m_saemix,
so = f_saemix,
@@ -817,7 +837,8 @@ update.saem.mmkin <- function(object, ..., evaluate = TRUE) {
#' each column corresponding to a row of the data frame holding the covariates
#' @param covariates A data frame holding covariate values for which to
#' return parameter values. Only has an effect if 'ci' is FALSE.
-parms.saem.mmkin <- function(object, ci = FALSE, covariates = NULL, ...) {
+parms.saem.mmkin <- function(object, ci = FALSE, covariates = NULL, ...)
+{
cov.mod <- object$sm@covariance.model
n_cov_mod_parms <- sum(cov.mod[upper.tri(cov.mod, diag = TRUE)])
n_parms <- length(object$sm@name.modpar) +
@@ -839,12 +860,25 @@ parms.saem.mmkin <- function(object, ci = FALSE, covariates = NULL, ...) {
names(estimate) <- rownames(conf.int)
+ # If confidence intervals are requested, we do not care about covariates
if (ci) {
return(conf.int)
} else {
if (is.null(covariates)) {
return(estimate)
} else {
+ # If there are covariates in the model, calculate parameter
+ # estimates for the corresponding covariate values passed
+ # in 'covariates'.
+ covariate_centers <- object$covariate_centers
+ parm_covariates <- covariates
+ if (!is.na(covariate_centers[1])) {
+ # If covariates were centered by the saem function, we need to center
+ # user specified covariates as well
+ for (i in names(covariates)) {
+ parm_covariates[i] <- covariates[i] - object$covariate_centers[i]
+ }
+ }
est_for_cov <- matrix(NA,
nrow = length(object$sm@name.modpar), ncol = nrow(covariates),
dimnames = (list(object$sm@name.modpar, rownames(covariates))))
@@ -856,7 +890,7 @@ parms.saem.mmkin <- function(object, ci = FALSE, covariates = NULL, ...) {
beta_degparm_name <- paste0("beta_", covariate,
"(", deg_parm_name, ")")
est_for_cov[deg_parm_name, ] <- estimate[deg_parm_name] +
- covariates[[covariate]] * estimate[beta_degparm_name]
+ parm_covariates[[covariate]] * estimate[beta_degparm_name]
} else {
est_for_cov[deg_parm_name, ] <- estimate[deg_parm_name]
}

Contact - Imprint