diff options
author | Johannes Ranke <jranke@uni-bremen.de> | 2020-04-14 17:22:00 +0200 |
---|---|---|
committer | Johannes Ranke <jranke@uni-bremen.de> | 2020-04-14 17:22:00 +0200 |
commit | 26085403289e29259e500282e8e88a5ab00c07a0 (patch) | |
tree | e86d5195c725ee0c08a45e4393ff9c1dfad64314 /R | |
parent | d4a49b4837de347d34b2c198de7342c34b0fab63 (diff) |
Add a nlme method for mmkin row objects
Diffstat (limited to 'R')
-rw-r--r-- | R/nlme.R | 17 | ||||
-rw-r--r-- | R/nlme.mmkin.R | 85 |
2 files changed, 92 insertions, 10 deletions
@@ -1,4 +1,4 @@ -#' Estimation of parameter distributions from mmkin row objects +#' Helper functions to create nlme models from mmkin row objects #' #' These functions facilitate setting up a nonlinear mixed effects model for #' an mmkin row object. An mmkin row object is essentially a list of mkinfit @@ -81,14 +81,19 @@ #' nlme_f_sfo_sfo <- nlme_function(f_2["SFO-SFO", ]) #' nlme_f_sfo_sfo_ff <- nlme_function(f_2["SFO-SFO-ff", ]) #' nlme_f_fomc_sfo <- nlme_function(f_2["FOMC-SFO", ]) +#' assign("nlme_f_sfo_sfo", nlme_f_sfo_sfo, globalenv()) +#' assign("nlme_f_sfo_sfo_ff", nlme_f_sfo_sfo_ff, globalenv()) +#' assign("nlme_f_fomc_sfo", nlme_f_fomc_sfo, globalenv()) #' -#' # Allowing for correlations between random effects leads to non-convergence +#' # Allowing for correlations between random effects (not shown) +#' # leads to non-convergence #' f_nlme_sfo_sfo <- nlme(value ~ nlme_f_sfo_sfo(name, time, #' parent_0, log_k_parent_sink, log_k_parent_A1, log_k_A1_sink), #' data = grouped_data_2, #' fixed = parent_0 + log_k_parent_sink + log_k_parent_A1 + log_k_A1_sink ~ 1, #' random = pdDiag(parent_0 + log_k_parent_sink + log_k_parent_A1 + log_k_A1_sink ~ 1), #' start = mean_dp_sfo_sfo) +#' # augPred does not see to work on this object, so no plot is shown #' #' # The same model fitted with transformed formation fractions does not converge #' f_nlme_sfo_sfo_ff <- nlme(value ~ nlme_f_sfo_sfo_ff(name, time, @@ -98,14 +103,6 @@ #' random = pdDiag(parent_0 + log_k_parent + log_k_A1 + f_parent_ilr_1 ~ 1), #' start = mean_dp_sfo_sfo_ff) #' -#' # It does converge with this version of reduced random effects -#' f_nlme_sfo_sfo_ff <- nlme(value ~ nlme_f_sfo_sfo_ff(name, time, -#' parent_0, log_k_parent, log_k_A1, f_parent_ilr_1), -#' data = grouped_data_2, -#' fixed = parent_0 + log_k_parent + log_k_A1 + f_parent_ilr_1 ~ 1, -#' random = pdDiag(parent_0 + log_k_parent ~ 1), -#' start = mean_dp_sfo_sfo_ff) -#' #' f_nlme_fomc_sfo <- nlme(value ~ nlme_f_fomc_sfo(name, time, #' parent_0, log_alpha, log_beta, log_k_A1, f_parent_ilr_1), #' data = grouped_data_2, diff --git a/R/nlme.mmkin.R b/R/nlme.mmkin.R new file mode 100644 index 00000000..784ba609 --- /dev/null +++ b/R/nlme.mmkin.R @@ -0,0 +1,85 @@ +#' Create an nlme model for an mmkin row object +#' +#' This functions sets up a nonlinear mixed effects model for an mmkin row +#' object. An mmkin row object is essentially a list of mkinfit objects that +#' have been obtained by fitting the same model to a list of datasets. +#' +#' @param model An \code{\link{mmkin}} row object. +#' @param data Ignored, data are taken from the mmkin model +#' @param fixed Ignored, all degradation parameters fitted in the +#' mmkin model are used as fixed parameters +#' @param random If not specified, all fixed effects are complemented +#' with uncorrelated random effects +#' @param groups See the documentation of nlme +#' @param start If not specified, mean values of the fitted degradation +#' parameters taken from the mmkin object are used +#' @param correlation See the documentation of nlme +#' @param weights passed to nlme +#' @param subset passed to nlme +#' @param method passed to nlme +#' @param na.action passed to nlme +#' @param naPattern passed to nlme +#' @param control passed to nlme +#' @param verbose passed to nlme +#' @importFrom stats na.fail +#' @return Upon success, a fitted nlme.mmkin object, which is +#' an nlme object with additional elements +#' @export +#' @seealso \code{\link{nlme_function}} +#' @examples +#' ds <- lapply(experimental_data_for_UBA_2019[6:10], +#' function(x) subset(x$data[c("name", "time", "value")], name == "parent")) +#' f <- mmkin("SFO", ds, quiet = TRUE, cores = 1) +#' library(nlme) +#' f_nlme <- nlme(f) +#' nlme(f, random = parent_0 ~ 1) +#' f_nlme <- nlme(f, start = c(parent_0 = 100, log_k_parent_sink = 0.1)) +#' update(f_nlme, random = parent_0 ~ 1) +# Code inspired by nlme.nlsList +nlme.mmkin <- function(model, data = sys.frame(sys.parent()), + fixed, random = fixed, + groups, start, correlation = NULL, weights = NULL, + subset, method = c("ML", "REML"), + na.action = na.fail, naPattern, + control = list(), verbose= FALSE) +{ + if (nrow(model) > 1) stop("Only row objects allowed") + + thisCall <- as.list(match.call())[-1] + + # warn in case of use of arguments that are overriden + if (any(!is.na(match(names(thisCall), + c("fixed", "data"))))) { + warning("'nlme.mmkin' will redefine 'fixed' and 'data'") + } + + deg_func <- nlme_function(model) + assign("deg_func", deg_func, parent.frame()) + + # specify the model formula + this_model_text <- paste0("value ~ deg_func(", + paste(names(formals(deg_func)), collapse = ", "), ")") + this_model <- eval(parse(text = this_model_text)) + thisCall[["model"]] <- this_model + + mean_dp <- mean_degparms(model) + dp_names <- names(mean_dp) + + thisCall[["data"]] <- nlme_data(model) + + if (missing(start)) { + thisCall[["start"]] <- mean_dp + } + + thisCall[["fixed"]] <- lapply(as.list(dp_names), function(el) + eval(parse(text = paste(el, 1, sep = "~")))) + + if (missing(random)) { + thisCall[["random"]] <- pdDiag(thisCall[["fixed"]]) + } + + val <- do.call("nlme.formula", thisCall) + return(val) + class(val) <- c("nlme.mmkin", "nlme", "lme") +} + |