From 9ae24c7e6980b141b16a85d18eb11257a902e4ac Mon Sep 17 00:00:00 2001 From: Jack Leary Date: Tue, 4 Jun 2024 14:53:47 -0400 Subject: [PATCH 1/2] updated imports in DESCRIPTION --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index fc4089e..7279414 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -9,7 +9,7 @@ Description: scLANE uses truncated power basis spline models to build flexible, Downstream analysis functionalities include model comparison, dynamic gene clustering, smoothed counts generation, gene set enrichment testing, & visualization. License: MIT + file LICENSE Encoding: UTF-8 -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Depends: glm2, magrittr, @@ -17,6 +17,7 @@ Depends: Imports: geeM, MASS, + mpath, dplyr, stats, utils, From d322f6118be64b5a40952235686d4ba3daaaa5ca Mon Sep 17 00:00:00 2001 From: Jack Leary Date: Wed, 5 Jun 2024 10:53:31 -0400 Subject: [PATCH 2/2] tweaked GLMM LASSO functionality --- R/fitGLMM.R | 39 ++++++++++++++++++++++++++++++++++++--- man/fitGLMM.Rd | 6 ++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/R/fitGLMM.R b/R/fitGLMM.R index 8473967..2d09720 100644 --- a/R/fitGLMM.R +++ b/R/fitGLMM.R @@ -16,6 +16,7 @@ #' @param M.glm The number of possible basis functions to use in the calls to \code{\link{marge2}} when choosing basis functions adaptively. #' @param return.basis (Optional) Whether the basis model matrix (denoted \code{B_final}) should be returned as part of the \code{marge} model object. Defaults to FALSE. #' @param return.GCV (Optional) Whether the final GCV value should be returned as part of the \code{marge} model object. Defaults to FALSE. +#' param vebose (Optional) Should intermediate output be printed to the console? Defaults to FALSE. #' @return An object of class \code{marge} containing the fitted model & other optional quantities of interest (basis function matrix, GCV, etc.). #' @seealso \code{\link[glmmTMB]{glmmTMB}} #' @seealso \code{\link{testDynamic}} @@ -38,7 +39,8 @@ fitGLMM <- function(X_pred = NULL, approx.knot = TRUE, M.glm = 3, return.basis = FALSE, - return.GCV = FALSE) { + return.GCV = FALSE, + verbose = FALSE) { # check inputs if (is.null(X_pred) || is.null(Y) || is.null(id.vec)) { stop("You forgot some inputs to fitGLMM().") } if (is.unsorted(id.vec)) { stop("Your data must be ordered by subject, please do so before running fitGLMM().") } @@ -74,10 +76,41 @@ fitGLMM <- function(X_pred = NULL, }) marge_style_names <- glm_marge_knots$old_coef coef_names <- glm_marge_knots$coef + if (verbose) { + message(paste0("Generated a total of ", + length(coef_names), + " basis functions across ", + length(unique(id.vec)), + " subjects.")) + } + # run NB LASSO with all possible basis functions + lasso_formula <- stats::as.formula(paste0("Y ~ ", paste0(colnames(glmm_basis_df), collapse = " + "))) + if (is.null(Y.offset)) { + pruned_model <- mpath::glmregNB(lasso_formula, + data = glmm_basis_df, + parallel = FALSE, + nlambda = 50, + alpha = 1, + standardize = TRUE, + trace = FALSE, + link = log) + } else { + pruned_model <- mpath::glmregNB(lasso_formula, + data = glmm_basis_df, + offset = log(1 / Y.offset), + parallel = FALSE, + nlambda = 50, + alpha = 1, + standardize = TRUE, + trace = FALSE, + link = log) + } + # identify nonzero basis functions in minimum AIC model + nonzero_coefs <- which(as.numeric(pruned_model$beta[, which.min(pruned_model$aic)]) != 0) # build formula automatically mod_formula <- stats::as.formula(paste0("Y ~ ", - paste(colnames(glmm_basis_df), collapse = " + "), - " + (1 + ", paste(colnames(glmm_basis_df), collapse = " + "), + paste(colnames(glmm_basis_df)[nonzero_coefs], collapse = " + "), + " + (1 + ", paste(colnames(glmm_basis_df)[nonzero_coefs], collapse = " + "), " | subject)")) glmm_basis_df <- dplyr::mutate(glmm_basis_df, Y = Y, diff --git a/man/fitGLMM.Rd b/man/fitGLMM.Rd index f49653e..a74b714 100644 --- a/man/fitGLMM.Rd +++ b/man/fitGLMM.Rd @@ -13,7 +13,8 @@ fitGLMM( approx.knot = TRUE, M.glm = 3, return.basis = FALSE, - return.GCV = FALSE + return.GCV = FALSE, + verbose = FALSE ) } \arguments{ @@ -33,7 +34,8 @@ fitGLMM( \item{return.basis}{(Optional) Whether the basis model matrix (denoted \code{B_final}) should be returned as part of the \code{marge} model object. Defaults to FALSE.} -\item{return.GCV}{(Optional) Whether the final GCV value should be returned as part of the \code{marge} model object. Defaults to FALSE.} +\item{return.GCV}{(Optional) Whether the final GCV value should be returned as part of the \code{marge} model object. Defaults to FALSE. +param vebose (Optional) Should intermediate output be printed to the console? Defaults to FALSE.} } \value{ An object of class \code{marge} containing the fitted model & other optional quantities of interest (basis function matrix, GCV, etc.).