aboutsummaryrefslogtreecommitdiff
path: root/R
diff options
context:
space:
mode:
authorJohannes Ranke <jranke@uni-bremen.de>2020-04-14 17:22:00 +0200
committerJohannes Ranke <jranke@uni-bremen.de>2020-04-14 17:22:00 +0200
commit26085403289e29259e500282e8e88a5ab00c07a0 (patch)
treee86d5195c725ee0c08a45e4393ff9c1dfad64314 /R
parentd4a49b4837de347d34b2c198de7342c34b0fab63 (diff)
Add a nlme method for mmkin row objects
Diffstat (limited to 'R')
-rw-r--r--R/nlme.R17
-rw-r--r--R/nlme.mmkin.R85
2 files changed, 92 insertions, 10 deletions
diff --git a/R/nlme.R b/R/nlme.R
index 12a3104c..fafaa7b6 100644
--- a/R/nlme.R
+++ b/R/nlme.R
@@ -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")
+}
+

Contact - Imprint