diff --git a/DESCRIPTION b/DESCRIPTION index 765cd22c5..71376e7e7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -112,6 +112,7 @@ Suggests: miceadds, mlogit, mlr3verse, + mmrm (>= 0.3.12), modelbased, modelsummary, nlme, @@ -246,6 +247,7 @@ Collate: 'methods_mlm.R' 'methods_mlogit.R' 'methods_mlr3.R' + 'methods_mmrm.R' 'methods_nlme.R' 'methods_ordinal.R' 'methods_plm.R' diff --git a/NAMESPACE b/NAMESPACE index 9c2e7b48f..494703309 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -21,6 +21,7 @@ S3method(get_coef,lmerModLmerTest) S3method(get_coef,mblogit) S3method(get_coef,merMod) S3method(get_coef,mlm) +S3method(get_coef,mmrm) S3method(get_coef,multinom) S3method(get_coef,nls) S3method(get_coef,polr) @@ -76,6 +77,7 @@ S3method(get_predict,mblogit) S3method(get_predict,merMod) S3method(get_predict,mhurdle) S3method(get_predict,mlogit) +S3method(get_predict,mmrm) S3method(get_predict,model_fit) S3method(get_predict,multinom) S3method(get_predict,ols) @@ -104,6 +106,7 @@ S3method(get_vcov,glimML) S3method(get_vcov,glmmTMB) S3method(get_vcov,gsm) S3method(get_vcov,mhurdle) +S3method(get_vcov,mmrm) S3method(get_vcov,model_fit) S3method(get_vcov,orm) S3method(get_vcov,pstpm2) @@ -160,6 +163,7 @@ S3method(set_coef,lmerMod) S3method(set_coef,lmerModLmerTest) S3method(set_coef,merMod) S3method(set_coef,mlm) +S3method(set_coef,mmrm) S3method(set_coef,model_fit) S3method(set_coef,multinom) S3method(set_coef,nls) diff --git a/NEWS.md b/NEWS.md index 2840055b7..481bc60dc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,9 +9,10 @@ Breaking changes: New models supported: -* `stpm2`, `pstpm2`, `gsm`, and `aft` models from `rstpm2`. Thanks to @aghaynes and @mclements. +* `rstpm2` package: support for `stpm2`, `pstpm2`, `gsm`, and `aft` models. Thanks to @mclements for contribution #1188 and @aghayes for useful comments. * `glm_weightit`, `coxph_weightit`, `multinom_weightit`, and `ordinal_weightit` models from `Weightit`. Thanks to @ngreifer. * `glmmgee` from the `glmtoolbox` package. Thanks to @adrianolszewski for the request and @lhvanegasp for help with implementation. +* `mmrm` package for mixed effects modelling. Thanks to @kkmann for contribution #1000, as well as @clarkliming and @lang-benjamin for useful comments. New features: diff --git a/R/methods_mmrm.R b/R/methods_mmrm.R new file mode 100644 index 000000000..3c7e77967 --- /dev/null +++ b/R/methods_mmrm.R @@ -0,0 +1,48 @@ +#' @include set_coef.R +#' @rdname set_coef +#' @keywords internal +#' @export +set_coef.mmrm <- function(model, coefs, ...) { + model$beta_est <- coefs + return(model) +} + + +#' @include get_coef.R +#' @rdname get_coef +#' @keywords internal +#' @export +get_coef.mmrm <- function(model, ...) { + return(coef(model, ...)) +} + + +#' @include get_vcov.R +#' @rdname get_vcov +#' @keywords internal +#' @export +get_vcov.mmrm <- function(model, ...) { + return(vcov(model, ...)) +} + + +#' @rdname get_predict +#' @keywords internal +#' @export +get_predict.mmrm <- function(model, newdata = model$data, type = "response", ...) { + type <- match.arg(type) + res <- data.frame( + rowid = seq_len(nrow(newdata)), + estimate = predict(model, newdata = newdata, type = type, conditional = FALSE) + ) + return(res) +} + + +#' @include sanity_model.R +#' @rdname sanitize_model_specific +#' @keywords internal +sanitize_model_specific.mmrm <- function(model, ...) { + insight::check_if_installed("mmrm", minimum_version = "0.3.11.9000") + return(model) +} diff --git a/R/sanity_model.R b/R/sanity_model.R index 09655cda5..808f67592 100644 --- a/R/sanity_model.R +++ b/R/sanity_model.R @@ -88,6 +88,7 @@ sanity_model_supported_class <- function(model) { "mhurdle", "mira", "mlogit", + "mmrm", "model_fit", c("multinom", "nnet"), "multinom_weightit", diff --git a/inst/tinytest/test-pkg-mmrm.R b/inst/tinytest/test-pkg-mmrm.R new file mode 100644 index 000000000..c0ecacfaa --- /dev/null +++ b/inst/tinytest/test-pkg-mmrm.R @@ -0,0 +1,17 @@ +source("helpers.R") +using("marginaleffects") + +requiet("mmrm") + +fit <- mmrm( + formula = FEV1 ~ RACE + SEX + ARMCD * AVISIT + us(AVISIT | USUBJID), + data = fev_data +) + +pre <- avg_predictions(fit, newdata = fev_data) +expect_inherits(pre, "predictions") + +cmp <- avg_comparisons(fit, + variables = "SEX", + newdata = fev_data) +expect_inherits(cmp, "comparisons") diff --git a/man/get_coef.Rd b/man/get_coef.Rd index ab041b218..a43de16fa 100644 --- a/man/get_coef.Rd +++ b/man/get_coef.Rd @@ -26,6 +26,7 @@ \alias{get_coef.mblogit} \alias{get_coef.gam} \alias{get_coef.mlm} +\alias{get_coef.mmrm} \alias{get_coef.selection} \alias{get_coef.scam} \alias{get_coef.nls} @@ -71,6 +72,8 @@ get_coef(model, ...) \method{get_coef}{mlm}(model, ...) +\method{get_coef}{mmrm}(model, ...) + \method{get_coef}{selection}(model, ...) \method{get_coef}{scam}(model, ...) diff --git a/man/get_predict.Rd b/man/get_predict.Rd index 9275573d9..046f3b77d 100644 --- a/man/get_predict.Rd +++ b/man/get_predict.Rd @@ -38,6 +38,7 @@ \alias{get_predict.mhurdle} \alias{get_predict.mlogit} \alias{get_predict.Learner} +\alias{get_predict.mmrm} \alias{get_predict.clm} \alias{get_predict.rq} \alias{get_predict.rms} @@ -120,6 +121,8 @@ get_predict(model, newdata, type, ...) \method{get_predict}{Learner}(model, newdata, type = NULL, ...) +\method{get_predict}{mmrm}(model, newdata = model$data, type = "response", ...) + \method{get_predict}{clm}(model, newdata = insight::get_data(model), type = "prob", ...) \method{get_predict}{rq}(model, newdata = insight::get_data(model), type = NULL, ...) diff --git a/man/get_vcov.Rd b/man/get_vcov.Rd index e944e9360..d78823027 100644 --- a/man/get_vcov.Rd +++ b/man/get_vcov.Rd @@ -2,8 +2,8 @@ % Please edit documentation in R/get_vcov.R, R/methods_MCMCglmm.R, % R/methods_afex.R, R/methods_aod.R, R/methods_biglm.R, R/methods_brms.R, % R/methods_dbarts.R, R/methods_gamlss.R, R/methods_glmmTMB.R, -% R/methods_mhurdle.R, R/methods_mlr3.R, R/methods_rms.R, R/methods_rstpm2.R, -% R/methods_scam.R, R/methods_tidymodels.R +% R/methods_mhurdle.R, R/methods_mlr3.R, R/methods_mmrm.R, R/methods_rms.R, +% R/methods_rstpm2.R, R/methods_scam.R, R/methods_tidymodels.R \name{get_vcov} \alias{get_vcov} \alias{get_vcov.default} @@ -17,6 +17,7 @@ \alias{get_vcov.glmmTMB} \alias{get_vcov.mhurdle} \alias{get_vcov.Learner} +\alias{get_vcov.mmrm} \alias{get_vcov.orm} \alias{get_vcov.stpm2} \alias{get_vcov.pstpm2} @@ -51,6 +52,8 @@ get_vcov(model, ...) \method{get_vcov}{Learner}(model, ...) +\method{get_vcov}{mmrm}(model, ...) + \method{get_vcov}{orm}(model, vcov = NULL, ...) \method{get_vcov}{stpm2}(model, ...) diff --git a/man/sanitize_model_specific.Rd b/man/sanitize_model_specific.Rd index 744c4a1d2..09e28cc8e 100644 --- a/man/sanitize_model_specific.Rd +++ b/man/sanitize_model_specific.Rd @@ -1,7 +1,7 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods_aod.R, R/methods_betareg.R, % R/sanity_model.R, R/methods_brms.R, R/methods_dbarts.R, R/methods_glmmTMB.R, -% R/methods_lme4.R, R/methods_mclogit.R, R/methods_mlogit.R, +% R/methods_lme4.R, R/methods_mclogit.R, R/methods_mlogit.R, R/methods_mmrm.R, % R/methods_ordinal.R, R/methods_plm.R, R/methods_quantreg.R, % R/methods_survey.R \name{sanitize_model_specific.glimML} @@ -15,6 +15,7 @@ \alias{sanitize_model_specific.merMod} \alias{sanitize_model_specific.mblogit} \alias{sanitize_model_specific.mlogit} +\alias{sanitize_model_specific.mmrm} \alias{sanitize_model_specific.clm} \alias{sanitize_model_specific.plm} \alias{sanitize_model_specific.rqs} @@ -47,6 +48,8 @@ sanitize_model_specific(model, ...) \method{sanitize_model_specific}{mlogit}(model, newdata, ...) +\method{sanitize_model_specific}{mmrm}(model, ...) + \method{sanitize_model_specific}{clm}(model, ...) \method{sanitize_model_specific}{plm}(model, ...) diff --git a/man/set_coef.Rd b/man/set_coef.Rd index 32349355f..d24e1e41e 100644 --- a/man/set_coef.Rd +++ b/man/set_coef.Rd @@ -32,6 +32,7 @@ \alias{set_coef.lmerModLmerTest} \alias{set_coef.lmerMod} \alias{set_coef.mlm} +\alias{set_coef.mmrm} \alias{set_coef.lme} \alias{set_coef.hurdle} \alias{set_coef.zeroinfl} @@ -97,6 +98,8 @@ set_coef(model, coefs, ...) \method{set_coef}{mlm}(model, coefs, ...) +\method{set_coef}{mmrm}(model, coefs, ...) + \method{set_coef}{lme}(model, coefs, ...) \method{set_coef}{hurdle}(model, coefs, ...)