From abbae2e08e50280ced8852612b854665e7e570e4 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:02:44 -0500 Subject: [PATCH 001/105] develop branch setup --- DESCRIPTION | 4 ++-- NEWS.md | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9c101ac2c..9d3230915 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4 -Date: 2025-12-10 +Version: 3.2.4.0001 +Date: 2025-12-12 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), diff --git a/NEWS.md b/NEWS.md index e480c085a..4fff5eae9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,20 @@ +# scCustomize 3.X.X (202X-XX-XX) +## Added + + + + +## Changed + + +## Fixes + + + + + + + # scCustomize 3.2.4 (2025-12-10) ## Added - Add progress bar support to following functions with `parallel` parameter using mcprogress package: `Read10X_GEO`, `Read10X_h5_GEO`, `Read10X_Multi_Directory`, `Read10X_h5_Multi_Directory`, `Read_GEO_Delim`, `Read_CellBender_h5_Multi_Directory`, `Read_CellBender_h5_Multi_File`. From f0ccba2e834b93fd957dd5499824389b1d92d166 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:02:59 -0500 Subject: [PATCH 002/105] Rename R/ scripts --- R/{QC_Utilities_Seurat.R => Utilities_QC_Seurat.R} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename R/{QC_Utilities_Seurat.R => Utilities_QC_Seurat.R} (100%) diff --git a/R/QC_Utilities_Seurat.R b/R/Utilities_QC_Seurat.R similarity index 100% rename from R/QC_Utilities_Seurat.R rename to R/Utilities_QC_Seurat.R From fb2fd3df12853a19ca560b9b1e0294cac13c44f6 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:07:22 -0500 Subject: [PATCH 003/105] add parameters if grouping by sample --- R/Plotting_Statistics.R | 71 +++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/R/Plotting_Statistics.R b/R/Plotting_Statistics.R index 0abaf8cd6..c699506f5 100644 --- a/R/Plotting_Statistics.R +++ b/R/Plotting_Statistics.R @@ -666,17 +666,19 @@ Plot_Median_Other <- function( #' Plot_Cells_per_Sample <- function( - seurat_object, - sample_col = "orig.ident", - group.by = NULL, - colors_use = NULL, - dot_size = 1, - plot_title = "Cells/Nuclei per Sample", - y_axis_label = "Number of Cells", - x_axis_label = NULL, - legend_title = NULL, - x_lab_rotate = TRUE, - color_seed = 123 + seurat_object, + sample_col = "orig.ident", + group.by = NULL, + colors_use = NULL, + dot_size = 1, + plot_title = "Cells/Nuclei per Sample", + y_axis_label = "Number of Cells", + x_axis_label = NULL, + legend_title = NULL, + x_lab_rotate = TRUE, + reorder = FALSE, + plot_median = TRUE, + color_seed = 123 ) { # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -730,15 +732,40 @@ Plot_Cells_per_Sample <- function( } } - # Generate base plot - plot <- ggplot(data = merged, mapping = aes(x = .data[[group.by]], y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + - geom_boxplot(fill = "white") + - geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + - scale_fill_manual(values = colors_use) + - theme_ggprism_mod() + - ggtitle(plot_title) + - ylab(y_axis_label) + - xlab("") + if (length(x = unique(seurat_object[[group.by]])) == length(unique(seurat_object[[sample_col]]))) { + if (isFALSE(x = reorder)) { + plot <- ggplot(data = merged, mapping = aes(x = .data[[group.by]], y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + + geom_boxplot(fill = "white") + + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + + scale_fill_manual(values = colors_use) + + theme_ggprism_mod() + + ggtitle(plot_title) + + ylab(y_axis_label) + + xlab("") + } else { + plot <- ggplot(data = merged, mapping = aes(x = reorder(.data[[group.by]], .data[["Number_of_Cells"]]), y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + + geom_boxplot(fill = "white") + + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + + scale_fill_manual(values = colors_use) + + theme_ggprism_mod() + + ggtitle(plot_title) + + ylab(y_axis_label) + + xlab("") + } + if (isTRUE(x = plot_median)) { + plot <- plot + geom_hline(yintercept = median(merged[["Number_of_Cells"]])) + } + } else { + # Generate base plot + plot <- ggplot(data = merged, mapping = aes(x = .data[[group.by]], y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + + geom_boxplot(fill = "white") + + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + + scale_fill_manual(values = colors_use) + + theme_ggprism_mod() + + ggtitle(plot_title) + + ylab(y_axis_label) + + xlab("") + } # Modify base plot if (isTRUE(x = x_lab_rotate)) { @@ -753,6 +780,10 @@ Plot_Cells_per_Sample <- function( plot <- plot + labs(fill = legend_title) } + if (length(x = unique(seurat_object[[group.by]])) == length(unique(seurat_object[[sample_col]]))) { + plot <- plot & NoLegend() + } + # Return plot return(plot) } From 10e2ba35edd0162b457843edd92e020d8eafd84b Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:11:58 -0500 Subject: [PATCH 004/105] update manual --- R/Plotting_Statistics.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/R/Plotting_Statistics.R b/R/Plotting_Statistics.R index c699506f5..3cf0dfaf9 100644 --- a/R/Plotting_Statistics.R +++ b/R/Plotting_Statistics.R @@ -645,6 +645,9 @@ Plot_Median_Other <- function( #' @param x_axis_label Label for x axis. #' @param legend_title Label for plot legend. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. +#' @param reorder logical, if plotting by sample should x-axis be reordered according to number of cells, +#' default is FALSE. +#' @param plot_median logical, if plotting by sample should line be added showing median, default is TRUE. #' @param color_seed random seed for the "varibow" palette shuffle if `colors_use = NULL` and number of #' groups plotted is greater than 36. Default = 123. #' @@ -756,6 +759,9 @@ Plot_Cells_per_Sample <- function( plot <- plot + geom_hline(yintercept = median(merged[["Number_of_Cells"]])) } } else { + if (isTRUE(x = reorder) || isFALSE(x = plot_median)) { + cli_warn(message = "The {.code reorder} and {.code plot_median} parameters were ignored as they are only valid if samples are not grouped by additional variable.") + } # Generate base plot plot <- ggplot(data = merged, mapping = aes(x = .data[[group.by]], y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + From 927c1510ae7641aa5db8e31ee54badeaf1cc828e Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:12:46 -0500 Subject: [PATCH 005/105] Update changelog --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 4fff5eae9..c39d3a97e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # scCustomize 3.X.X (202X-XX-XX) ## Added - +- Added `reorder` and `plot_median` parameters to `Plot_Cells_per_Sample` when grouping by sample. From 40f2973f5041dc4b3b8a53fecd5ef7b83215de13 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:20:14 -0500 Subject: [PATCH 006/105] add reorder_decreasing param --- R/Plotting_Statistics.R | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/R/Plotting_Statistics.R b/R/Plotting_Statistics.R index 3cf0dfaf9..52377bfc0 100644 --- a/R/Plotting_Statistics.R +++ b/R/Plotting_Statistics.R @@ -647,6 +647,8 @@ Plot_Median_Other <- function( #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param reorder logical, if plotting by sample should x-axis be reordered according to number of cells, #' default is FALSE. +#' @param reorder_decreasing logical, if `reorder = TRUE` should points be ordered from fewest to +#' greatest number of cells (FALSE) or reverse (TRUE), default is FALSE. #' @param plot_median logical, if plotting by sample should line be added showing median, default is TRUE. #' @param color_seed random seed for the "varibow" palette shuffle if `colors_use = NULL` and number of #' groups plotted is greater than 36. Default = 123. @@ -664,7 +666,15 @@ Plot_Median_Other <- function( #' #' @examples #' \dontrun{ -#' Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "Treatment") +#' # Plot cells per sample grouped by "Diagnosis" +#' Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "Diagnosis") +#' +#' # Plot cells per sample individually +#' Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident") +#' +#' #' # Plot cells per sample individually and reorder x-axis by cell number +#' Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident", order = TRUE) +#' #' } #' @@ -680,6 +690,7 @@ Plot_Cells_per_Sample <- function( legend_title = NULL, x_lab_rotate = TRUE, reorder = FALSE, + reorder_decreasing = FALSE, plot_median = TRUE, color_seed = 123 ) { @@ -746,7 +757,7 @@ Plot_Cells_per_Sample <- function( ylab(y_axis_label) + xlab("") } else { - plot <- ggplot(data = merged, mapping = aes(x = reorder(.data[[group.by]], .data[["Number_of_Cells"]]), y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + + plot <- ggplot(data = merged, mapping = aes(x = reorder(.data[[group.by]], .data[["Number_of_Cells"]], decreasing = decreasing), y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + From b9d1beaf2ebaa537551ef64384cdbde7f54d7ad9 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:20:39 -0500 Subject: [PATCH 007/105] reorder decreasing --- R/Plotting_Statistics.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Plotting_Statistics.R b/R/Plotting_Statistics.R index 52377bfc0..33dc9d108 100644 --- a/R/Plotting_Statistics.R +++ b/R/Plotting_Statistics.R @@ -757,7 +757,7 @@ Plot_Cells_per_Sample <- function( ylab(y_axis_label) + xlab("") } else { - plot <- ggplot(data = merged, mapping = aes(x = reorder(.data[[group.by]], .data[["Number_of_Cells"]], decreasing = decreasing), y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + + plot <- ggplot(data = merged, mapping = aes(x = reorder(.data[[group.by]], .data[["Number_of_Cells"]], decreasing = reorder_decreasing), y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + From ec53ff43b54ae4ceb047a2b4c7209ff81d1c6d3c Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:21:08 -0500 Subject: [PATCH 008/105] Update changelog --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index c39d3a97e..d2c0deb88 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # scCustomize 3.X.X (202X-XX-XX) ## Added -- Added `reorder` and `plot_median` parameters to `Plot_Cells_per_Sample` when grouping by sample. +- Added `reorder`, `reorder_decreasing`, and `plot_median` parameters to `Plot_Cells_per_Sample` when grouping by sample. From 4e2e98aecddca18bdac9112392dd4e808eab80bd Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:22:19 -0500 Subject: [PATCH 009/105] Update docs --- man/Add_CellBender_Diff.Rd | 2 +- man/Add_Cell_Complexity.Rd | 2 +- man/Add_Cell_QC_Metrics.Rd | 2 +- man/Add_Hemo.Rd | 2 +- man/Add_MALAT1_Threshold.Rd | 2 +- man/Add_Mito_Ribo.Rd | 2 +- man/Add_Top_Gene_Pct.Rd | 2 +- man/Plot_Cells_per_Sample.Rd | 21 ++++++++++++++++++++- man/exAM_Scoring.Rd | 2 +- 9 files changed, 28 insertions(+), 9 deletions(-) diff --git a/man/Add_CellBender_Diff.Rd b/man/Add_CellBender_Diff.Rd index fe93c7843..19639266d 100644 --- a/man/Add_CellBender_Diff.Rd +++ b/man/Add_CellBender_Diff.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/QC_Utilities_Seurat.R +% Please edit documentation in R/Utilities_QC_Seurat.R \name{Add_CellBender_Diff} \alias{Add_CellBender_Diff} \title{Calculate and add differences post-cell bender analysis} diff --git a/man/Add_Cell_Complexity.Rd b/man/Add_Cell_Complexity.Rd index a905db38c..cdc3d181a 100644 --- a/man/Add_Cell_Complexity.Rd +++ b/man/Add_Cell_Complexity.Rd @@ -1,6 +1,6 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/Generics.R, R/LIGER_Utilities.R, -% R/QC_Utilities_Seurat.R +% R/Utilities_QC_Seurat.R \name{Add_Cell_Complexity} \alias{Add_Cell_Complexity} \alias{Add_Cell_Complexity.liger} diff --git a/man/Add_Cell_QC_Metrics.Rd b/man/Add_Cell_QC_Metrics.Rd index f72a93b05..d21756750 100644 --- a/man/Add_Cell_QC_Metrics.Rd +++ b/man/Add_Cell_QC_Metrics.Rd @@ -1,6 +1,6 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/Generics.R, R/LIGER_Utilities.R, -% R/QC_Utilities_Seurat.R +% R/Utilities_QC_Seurat.R \name{Add_Cell_QC_Metrics} \alias{Add_Cell_QC_Metrics} \alias{Add_Cell_QC_Metrics.liger} diff --git a/man/Add_Hemo.Rd b/man/Add_Hemo.Rd index ccb3897b0..f824c84d2 100644 --- a/man/Add_Hemo.Rd +++ b/man/Add_Hemo.Rd @@ -1,6 +1,6 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/Generics.R, R/LIGER_Utilities.R, -% R/QC_Utilities_Seurat.R +% R/Utilities_QC_Seurat.R \name{Add_Hemo} \alias{Add_Hemo} \alias{Add_Hemo.liger} diff --git a/man/Add_MALAT1_Threshold.Rd b/man/Add_MALAT1_Threshold.Rd index 98db74ab9..169d3468f 100644 --- a/man/Add_MALAT1_Threshold.Rd +++ b/man/Add_MALAT1_Threshold.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/Generics.R, R/QC_Utilities_Seurat.R +% Please edit documentation in R/Generics.R, R/Utilities_QC_Seurat.R \name{Add_MALAT1_Threshold} \alias{Add_MALAT1_Threshold} \alias{Add_MALAT1_Threshold.Seurat} diff --git a/man/Add_Mito_Ribo.Rd b/man/Add_Mito_Ribo.Rd index 184ebdbc8..8d8e6f092 100644 --- a/man/Add_Mito_Ribo.Rd +++ b/man/Add_Mito_Ribo.Rd @@ -1,6 +1,6 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/Generics.R, R/LIGER_Utilities.R, -% R/QC_Utilities_Seurat.R +% R/Utilities_QC_Seurat.R \name{Add_Mito_Ribo} \alias{Add_Mito_Ribo} \alias{Add_Mito_Ribo.liger} diff --git a/man/Add_Top_Gene_Pct.Rd b/man/Add_Top_Gene_Pct.Rd index a1a93a5e5..0334c2fe2 100644 --- a/man/Add_Top_Gene_Pct.Rd +++ b/man/Add_Top_Gene_Pct.Rd @@ -1,6 +1,6 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/Generics.R, R/LIGER_Utilities.R, -% R/QC_Utilities_Seurat.R +% R/Utilities_QC_Seurat.R \name{Add_Top_Gene_Pct} \alias{Add_Top_Gene_Pct} \alias{Add_Top_Gene_Pct.liger} diff --git a/man/Plot_Cells_per_Sample.Rd b/man/Plot_Cells_per_Sample.Rd index 498f0e4d6..e45c2a1c9 100644 --- a/man/Plot_Cells_per_Sample.Rd +++ b/man/Plot_Cells_per_Sample.Rd @@ -15,6 +15,9 @@ Plot_Cells_per_Sample( x_axis_label = NULL, legend_title = NULL, x_lab_rotate = TRUE, + reorder = FALSE, + reorder_decreasing = FALSE, + plot_median = TRUE, color_seed = 123 ) } @@ -39,6 +42,14 @@ Plot_Cells_per_Sample( \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} +\item{reorder}{logical, if plotting by sample should x-axis be reordered according to number of cells, +default is FALSE.} + +\item{reorder_decreasing}{logical, if \code{reorder = TRUE} should points be ordered from fewest to +greatest number of cells (FALSE) or reverse (TRUE), default is FALSE.} + +\item{plot_median}{logical, if plotting by sample should line be added showing median, default is TRUE.} + \item{color_seed}{random seed for the "varibow" palette shuffle if \code{colors_use = NULL} and number of groups plotted is greater than 36. Default = 123.} } @@ -50,7 +61,15 @@ Plot of total cell or nuclei number per sample grouped by another meta data vari } \examples{ \dontrun{ -Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "Treatment") +# Plot cells per sample grouped by "Diagnosis" +Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "Diagnosis") + +# Plot cells per sample individually +Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident") + +#' # Plot cells per sample individually and reorder x-axis by cell number +Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident", order = TRUE) + } } diff --git a/man/exAM_Scoring.Rd b/man/exAM_Scoring.Rd index ad339f55b..50c9dac14 100644 --- a/man/exAM_Scoring.Rd +++ b/man/exAM_Scoring.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/QC_Utilities_Seurat.R +% Please edit documentation in R/Utilities_QC_Seurat.R \name{exAM_Scoring} \alias{exAM_Scoring} \title{Add exAM Gene List Module Scores} From 378aacbdcf818116ebf56f629880f7fa0ef013d2 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:22:32 -0500 Subject: [PATCH 010/105] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9d3230915..efa9e1693 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.0001 +Version: 3.2.4.0002 Date: 2025-12-12 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), From e52b90a8634c31bc68ab0949e4cca467ec807b84 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:25:14 -0500 Subject: [PATCH 011/105] check fix --- R/Plotting_Statistics.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Plotting_Statistics.R b/R/Plotting_Statistics.R index 33dc9d108..e3764607d 100644 --- a/R/Plotting_Statistics.R +++ b/R/Plotting_Statistics.R @@ -770,7 +770,7 @@ Plot_Cells_per_Sample <- function( plot <- plot + geom_hline(yintercept = median(merged[["Number_of_Cells"]])) } } else { - if (isTRUE(x = reorder) || isFALSE(x = plot_median)) { + if (isTRUE(x = reorder)) { cli_warn(message = "The {.code reorder} and {.code plot_median} parameters were ignored as they are only valid if samples are not grouped by additional variable.") } # Generate base plot From 5aa1aea980ba8207763a50ca8995b776d07b17f2 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:49:01 -0500 Subject: [PATCH 012/105] fix warning checks and add binwidth when by sample --- R/Plotting_Statistics.R | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/R/Plotting_Statistics.R b/R/Plotting_Statistics.R index e3764607d..1a28e3704 100644 --- a/R/Plotting_Statistics.R +++ b/R/Plotting_Statistics.R @@ -746,11 +746,13 @@ Plot_Cells_per_Sample <- function( } } - if (length(x = unique(seurat_object[[group.by]])) == length(unique(seurat_object[[sample_col]]))) { + if (nrow(x = unique(x = seurat_object[[group.by]])) == nrow(x = unique(x = seurat_object[[sample_col]]))) { + # create sample binwidth to avoid printing irrelevent warning + sample_binwidth <- (max(merged[["Number_of_Cells"]]) - min(merged[["Number_of_Cells"]])) * 1/30 + if (isFALSE(x = reorder)) { plot <- ggplot(data = merged, mapping = aes(x = .data[[group.by]], y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + - geom_boxplot(fill = "white") + - geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size, binwidth = sample_binwidth) + scale_fill_manual(values = colors_use) + theme_ggprism_mod() + ggtitle(plot_title) + @@ -758,8 +760,7 @@ Plot_Cells_per_Sample <- function( xlab("") } else { plot <- ggplot(data = merged, mapping = aes(x = reorder(.data[[group.by]], .data[["Number_of_Cells"]], decreasing = reorder_decreasing), y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + - geom_boxplot(fill = "white") + - geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size, binwidth = sample_binwidth) + scale_fill_manual(values = colors_use) + theme_ggprism_mod() + ggtitle(plot_title) + @@ -770,8 +771,8 @@ Plot_Cells_per_Sample <- function( plot <- plot + geom_hline(yintercept = median(merged[["Number_of_Cells"]])) } } else { - if (isTRUE(x = reorder)) { - cli_warn(message = "The {.code reorder} and {.code plot_median} parameters were ignored as they are only valid if samples are not grouped by additional variable.") + if (isTRUE(x = reorder) || isFALSE(x = plot_median) || isTRUE(x = reorder_decreasing)) { + cli_warn(message = "The {.code reorder}, {.code plot_median}, and {.code reorder_decreasing} parameters were ignored as they are only valid if samples are not grouped by additional variable.") } # Generate base plot plot <- ggplot(data = merged, mapping = aes(x = .data[[group.by]], y = .data[["Number_of_Cells"]], fill = .data[[group.by]])) + From db9de0338a175fa9ecd06932e880e668e0354365 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:27:08 -0500 Subject: [PATCH 013/105] Add velocyto loom read functions --- R/Read_Write_Data.R | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 131ad7d86..1b1aae099 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1534,6 +1534,87 @@ Read_CellBender_h5_Multi_File <- function( } + +#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#################### READ loom DATA #################### +#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +#' Read Loom Files +#' +#' Internalfunction to read velocyto loom files using hdf5r package. +#' +#' @param loom_file loom file to read +#' +#' @return list of sparse matrices containing spliced, unspliced, and ambiguous counts +#' @noRd +#' @keywords internal +#' +#' @references Function is updated from velocyto.R `read.loom.matrices` \url{https://github.com/velocyto-team/velocyto.R}. +#' Function included in scCustomize to avoid installation issues related to other aspects of +#' velocyto.R package. +#' + +ReadLoomMatrices <- function( + loom_file +) { + # Check hdf5r installed + hdf5r_check <- is_installed(pkg = "hdf5r") + if (isFALSE(x = hdf5r_check)) { + cli_abort(message = c( + "Please install the {.val hdf5r} package to use {.code Read_CellBender_h5_Mat} and read HDF5 files.", + "i" = "This can be accomplished with the following commands: ", + "----------------------------------------", + "{.field `install.packages({symbol$dquote_left}hdf5r{symbol$dquote_right})`}", + "----------------------------------------" + )) + } + + f <- hdf5r::H5File$new(loom_file, mode='r') + cells <- f[["col_attrs/CellID"]][] + genes <- f[["row_attrs/Gene"]][] + dl <- c(spliced="layers/spliced", + unspliced="layers/unspliced", + ambiguous="layers/ambiguous") + if("layers/spanning" %in% hdf5r::list.datasets(f)) { + dl <- c(dl, c(spanning="layers/spanning")) + } + + dlist <- lapply(dl, function(path) { + m <- as.sparse(t(f[[path]][,])) + rownames(m) <- genes; colnames(m) <- cells; + return(m) + }) + f$close_all() + return(dlist) +} + + +#' Load RNA Velocity results +#' +#' Wrapper function to +#' +#' @param loom_file +#' +#' @return list of sparse matrices containing spliced, unspliced, and ambiguous counts +#' +#' @export +#' +#' @examples +#' \dontrun{ +#' velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom") +#' } + +Read_Velocity <- function( + loom_file +) { + invisible(x = capture.output(ldat <- ReadLoomMatrices( + loom_file = loom_file, + ))) + return(ldat) +} + + #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #################### READ OTHER DATA #################### #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% From 37f41ebb45ea9e563f3560ebe0e18c117fd65681 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:27:15 -0500 Subject: [PATCH 014/105] Update changelog --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index d2c0deb88..640f00397 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ # scCustomize 3.X.X (202X-XX-XX) ## Added - Added `reorder`, `reorder_decreasing`, and `plot_median` parameters to `Plot_Cells_per_Sample` when grouping by sample. +- Added `Read_Velocity` function to enable reading of velocyto loom output files without needing to install velocyto.R (which currently suffers from significant installation issues unrelated to reading loom files). From 68fcaaedd94862484ff31aef19eb53e2126f5343 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:27:27 -0500 Subject: [PATCH 015/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index efa9e1693..f264f30d0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.0002 -Date: 2025-12-12 +Version: 3.2.4.0003 +Date: 2026-01-07 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From 4f8fdd6aa77c0c7e381e1bf0861a2a39dd4c6ada Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:31:45 -0500 Subject: [PATCH 016/105] Update manual --- R/Read_Write_Data.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 1b1aae099..aafeaa0a3 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1600,6 +1600,12 @@ ReadLoomMatrices <- function( #' #' @export #' +#' @references Function is updated from `SeuratWrappers::ReadVelocity` +#' \url{https://github.com/satijalab/seurat-wrappers/blob/master/R/velocity.R} (License: GPL-3). +#' Function included in scCustomize to avoid installation issues related to other aspects of +#' velocyto.R package which `SeuratWrappers::ReadVelocity` requires. +#' +#' #' @examples #' \dontrun{ #' velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom") From 1ea6cd036efd9a5ed2d7dfa5978111185407bdb3 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:32:06 -0500 Subject: [PATCH 017/105] Update docs --- NAMESPACE | 1 + man/Read_Velocity.Rd | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 man/Read_Velocity.Rd diff --git a/NAMESPACE b/NAMESPACE index fc0717b1e..45b74d9bc 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -144,6 +144,7 @@ export(Read_CellBender_h5_Multi_File) export(Read_GEO_Delim) export(Read_Metrics_10X) export(Read_Metrics_CellBender) +export(Read_Velocity) export(Reduction_Loading_Present) export(Rename_Clusters) export(Replace_Suffix) diff --git a/man/Read_Velocity.Rd b/man/Read_Velocity.Rd new file mode 100644 index 000000000..31aec9636 --- /dev/null +++ b/man/Read_Velocity.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Read_Write_Data.R +\name{Read_Velocity} +\alias{Read_Velocity} +\title{Load RNA Velocity results} +\usage{ +Read_Velocity(loom_file) +} +\arguments{ +\item{loom_file}{} +} +\value{ +list of sparse matrices containing spliced, unspliced, and ambiguous counts +} +\description{ +Wrapper function to +} +\examples{ +\dontrun{ +velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom") +} +} +\references{ +Function is updated from \code{SeuratWrappers::ReadVelocity} +\url{https://github.com/satijalab/seurat-wrappers/blob/master/R/velocity.R} (License: GPL-3). +Function included in scCustomize to avoid installation issues related to other aspects of +velocyto.R package which \code{SeuratWrappers::ReadVelocity} requires. +} From 88d2cc08ee4fac30139b25a45b96805085cc7cb8 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 7 Jan 2026 11:39:20 -0500 Subject: [PATCH 018/105] typo fix --- R/Read_Write_Data.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index aafeaa0a3..7f0c62cc4 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1615,7 +1615,7 @@ Read_Velocity <- function( loom_file ) { invisible(x = capture.output(ldat <- ReadLoomMatrices( - loom_file = loom_file, + loom_file = loom_file ))) return(ldat) } From 0eac3660e00af8ad6a66cd8187d905fcf9377739 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 9 Jan 2026 12:31:32 -0500 Subject: [PATCH 019/105] Add unique naming to match Read10X functionality --- R/Read_Write_Data.R | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 7f0c62cc4..99d633a65 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1556,7 +1556,8 @@ Read_CellBender_h5_Multi_File <- function( #' ReadLoomMatrices <- function( - loom_file + loom_file, + gene_symbol = TRUE ) { # Check hdf5r installed hdf5r_check <- is_installed(pkg = "hdf5r") @@ -1572,7 +1573,12 @@ ReadLoomMatrices <- function( f <- hdf5r::H5File$new(loom_file, mode='r') cells <- f[["col_attrs/CellID"]][] - genes <- f[["row_attrs/Gene"]][] + if (isTRUE(x = gene_symbol)) { + genes <- f[["row_attrs/Gene"]][] + } else { + genes <- f[["row_attrs/Accession"]][] + } + dl <- c(spliced="layers/spliced", unspliced="layers/unspliced", ambiguous="layers/ambiguous") @@ -1582,10 +1588,20 @@ ReadLoomMatrices <- function( dlist <- lapply(dl, function(path) { m <- as.sparse(t(f[[path]][,])) - rownames(m) <- genes; colnames(m) <- cells; + rownames(x = m) <- genes; colnames(x = m) <- cells; return(m) }) f$close_all() + + # check unique and edit gene names/ids if needed + num_dup <- sum(duplicated(x = rownames(x = dlist[["spliced"]]))) + + if (num_dup > 0) { + rownames(dlist[["spliced"]]) <- make.unique(names = rownames(dlist[["spliced"]])) + rownames(dlist[["unspliced"]]) <- make.unique(names = rownames(dlist[["unspliced"]])) + rownames(dlist[["ambiguous"]]) <- make.unique(names = rownames(dlist[["ambiguous"]])) + } + return(dlist) } From 2446ba50d6df545b977b0a5973cd589809fa7c0e Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 9 Jan 2026 12:41:36 -0500 Subject: [PATCH 020/105] pass gene symbol --- R/Read_Write_Data.R | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 99d633a65..65fdb0c39 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1597,6 +1597,8 @@ ReadLoomMatrices <- function( num_dup <- sum(duplicated(x = rownames(x = dlist[["spliced"]]))) if (num_dup > 0) { + cli_inform(message = c("A total of {.field {num_dup}} duplicate row names were found.", + "i" = "Making unique with {.code make.unique()}.")) rownames(dlist[["spliced"]]) <- make.unique(names = rownames(dlist[["spliced"]])) rownames(dlist[["unspliced"]]) <- make.unique(names = rownames(dlist[["unspliced"]])) rownames(dlist[["ambiguous"]]) <- make.unique(names = rownames(dlist[["ambiguous"]])) @@ -1628,10 +1630,12 @@ ReadLoomMatrices <- function( #' } Read_Velocity <- function( - loom_file + loom_file, + gene_symbol = TRUE ) { invisible(x = capture.output(ldat <- ReadLoomMatrices( - loom_file = loom_file + loom_file = loom_file, + gene_symbol = gene_symbol ))) return(ldat) } From fe5f1fd13f8ff0c9256a9ebbdddecb6a2f60a212 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:45:41 -0500 Subject: [PATCH 021/105] Updating Velocity functions --- R/Read_Write_Data.R | 178 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 169 insertions(+), 9 deletions(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 65fdb0c39..179260085 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1557,7 +1557,8 @@ Read_CellBender_h5_Multi_File <- function( ReadLoomMatrices <- function( loom_file, - gene_symbol = TRUE + gene_symbol = TRUE, + verbose = TRUE ) { # Check hdf5r installed hdf5r_check <- is_installed(pkg = "hdf5r") @@ -1597,8 +1598,11 @@ ReadLoomMatrices <- function( num_dup <- sum(duplicated(x = rownames(x = dlist[["spliced"]]))) if (num_dup > 0) { - cli_inform(message = c("A total of {.field {num_dup}} duplicate row names were found.", - "i" = "Making unique with {.code make.unique()}.")) + if (isTRUE(x = verbose)) { + cli_inform(message = c("A total of {.field {num_dup}} duplicate row names were found.", + "i" = "Making unique with {.code make.unique()}.")) + } + rownames(dlist[["spliced"]]) <- make.unique(names = rownames(dlist[["spliced"]])) rownames(dlist[["unspliced"]]) <- make.unique(names = rownames(dlist[["unspliced"]])) rownames(dlist[["ambiguous"]]) <- make.unique(names = rownames(dlist[["ambiguous"]])) @@ -1608,11 +1612,141 @@ ReadLoomMatrices <- function( } + +#' Read multiple loom files from same directory +#' +#' Internal wrapper to be used be `Read_Velocity` if data directory is provided. +#' +#' @param data_dir Directory containing the loom files provided by velocyto. +#' @param gene_symbol logical, should rownames of returned matrices have gene symbols or accession ID #s, +#' default is TRUE (symbols). +#' @param sample_list A vector of file prefixes/names if specific samples are desired. Default is `NULL` and +#' will load all samples in given directory. +#' @param sample_names a set of sample names to use for each sample entry in returned list. If `NULL` +#' will set names to the file name of each sample. +#' @param shared_suffix a suffix and file extension shared by all samples. +#' @param parallel logical (default FALSE). Whether to use multiple cores when reading in data. +#' Only possible on Linux based systems. +#' @param num_cores if `parallel = TRUE` indicates the number of cores to use for multicore processing. +#' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each +#' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of +#' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample +#' +#' @returns +#' @noRd +#' @keywords internal +#' + +ReadVelocity_Multi_File_Internal <- function( + data_dir = NULL, + gene_symbol = TRUE, + sample_list = NULL, + sample_names = NULL, + shared_suffix = NULL, + parallel = FALSE, + num_cores = NULL, + sort_type = FALSE +) { + if (!dir.exists(paths = data_dir)) { + cli_abort(message = "Directory provided does not exist") + } + if (length(x = data_dir) > 1) { + cli_abort(message = "{.code Read_Velocity} only supports reading from single data directory at a time.") + } + + # Confirm num_cores specified + if (isTRUE(x = parallel) && is.null(x = num_cores)) { + cli_abort("If {.code parallel = TRUE} then {.code num_cores} must be specified.") + } + + file.list <- list.files(path = data_dir, pattern = ".loom", full.names = FALSE) + + # Remove file suffix if provided + if (!is.null(x = shared_suffix)) { + shared_suffix <- gsub(pattern = ".loom", replacement = "", x = shared_suffix) + } + + if (is.null(x = sample_list)) { + if (is.null(x = shared_suffix)) { + sample_list <- gsub(pattern = ".loom", x = file.list, replacement = "") + } else { + sample_list <- gsub(pattern = paste0(shared_suffix, ".loom"), x = file.list, replacement = "") + } + } + + # Check sample_names length is ok + if (!is.null(x = sample_names) && length(x = sample_names) != length(x = sample_list)) { + cli_abort(message = "Length of {.code sample_names} {.field {length(x = sample_names)}} must be equal to number of samples {.field {length(x = sample_list)}}.") + } + + cli_inform(message = "{.field Reading Loom files from directory}") + pboptions(char = "=") + if (isTRUE(x = parallel)) { + cli_inform(message = c("NOTE: Parallel processing may not report informative error messages.", + "i" = "If function fails set {.code parallel = FALSE} and re-run for informative error reporting.")) + raw_data_list <- pmclapply(mc.cores = num_cores, 1:length(x = sample_list), function(i) { + loom_loc <- file.path(data_dir, paste0(sample_list[i], shared_suffix, ".loom")) + data <- Read_Velocity(loom_file = loom_loc, gene_symbol = gene_symbol) + }) + } else { + raw_data_list <- pblapply(1:length(x = sample_list), function(i) { + loom_loc <- file.path(data_dir, paste0(sample_list[i], shared_suffix, ".loom")) + data <- Read_Velocity(loom_file = loom_loc, gene_symbol = gene_symbol) + }) + } + + # Name the matrices + if (is.null(x = sample_names)) { + names(x = raw_data_list) <- sample_list + } else { + names(x = raw_data_list) <- sample_names + } + + if (isTRUE(x = sort_type)) { + spliced_list <- lapply(1:length(x = raw_data_list), function(x){ + data <- testing[[x]][["spliced"]] + }) + names(x = spliced_list) <- names(x = raw_data_list) + + unspliced_list <- lapply(1:length(x = raw_data_list), function(x){ + data <- testing[[x]][["unspliced"]] + }) + names(x = unspliced_list) <- names(x = raw_data_list) + + ambiguous_list <- lapply(1:length(x = raw_data_list), function(x){ + data <- testing[[x]][["ambiguous"]] + }) + names(x = ambiguous_list) <- names(x = raw_data_list) + + raw_data_list <- list("spliced" = spliced_list, + "unspliced" = unspliced_list, + "ambiguous" = ambiguous_list) + + } + + # return object + return(raw_data_list) +} + #' Load RNA Velocity results #' #' Wrapper function to #' -#' @param loom_file +#' @param loom_file path and name of loom file to read +#' @param data_dir path to data directory containing all loom files to read +#' @param gene_symbol logical, should rownames of returned matrices have gene symbols or accession ID #s, +#' default is TRUE (symbols). +#' @param sample_list A vector of file prefixes/names if specific samples are desired. Default is `NULL` and +#' will load all samples in given directory. +#' @param sample_names a set of sample names to use for each sample entry in returned list. If `NULL` +#' will set names to the file name of each sample. +#' @param shared_suffix a suffix and file extension shared by all samples. +#' @param parallel logical (default FALSE). Whether to use multiple cores when reading in data. +#' Only possible on Linux based systems. +#' @param num_cores if `parallel = TRUE` indicates the number of cores to use for multicore processing. +#' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each +#' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of +#' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample #' #' @return list of sparse matrices containing spliced, unspliced, and ambiguous counts #' @@ -1630,14 +1764,40 @@ ReadLoomMatrices <- function( #' } Read_Velocity <- function( - loom_file, - gene_symbol = TRUE + loom_file = NULL, + data_dir = NULL, + multi_dir = TRUE, + gene_symbol = TRUE, + sample_list = NULL, + sample_names = NULL, + shared_suffix = NULL, + parallel = FALSE, + num_cores = NULL, + sort_type = FALSE ) { - invisible(x = capture.output(ldat <- ReadLoomMatrices( + if (!is.null(x = loom_file) && !is.null(x = data_dir)) { + cli_abort(message = "Cannot specify values for both {.code loom_file} and {.code data_dir}.") + } + + if (!is.null(x = loom_file)) { + invisible(x = capture.output(data <- ReadLoomMatrices( loom_file = loom_file, - gene_symbol = gene_symbol + gene_symbol = gene_symbol, + verbose = TRUE ))) - return(ldat) + return(data) + } + # single data directory + if (isFALSE(x = multi_dir)) { + data_list <- ReadVelocity_Multi_File_Internal(data_dir = data_dir, gene_symbol = gene_symbol, sample_list = sample_list, sample_names = sample_names, shared_suffix = shared_suffix, parallel = parallel, num_cores = num_cores, sort_type = sort_type) + return(data_list) + } + + # multi directory + if (isTRUE(x = multi_dir)) { + data_list <- ReadVelocity_Multi_Dir_Internal(data_dir = data_dir, gene_symbol = gene_symbol, sample_list = sample_list, sample_names = sample_names, shared_suffix = shared_suffix, parallel = parallel, num_cores = num_cores, sort_type = sort_type) + return(data_list) + } } From d3cb6c9b5f068274a90483e73e9d1a3a6598a21e Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:47:29 -0500 Subject: [PATCH 022/105] Update docs --- man/Read_Velocity.Rd | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/man/Read_Velocity.Rd b/man/Read_Velocity.Rd index 31aec9636..401bab99c 100644 --- a/man/Read_Velocity.Rd +++ b/man/Read_Velocity.Rd @@ -4,10 +4,43 @@ \alias{Read_Velocity} \title{Load RNA Velocity results} \usage{ -Read_Velocity(loom_file) +Read_Velocity( + loom_file = NULL, + data_dir = NULL, + multi_dir = TRUE, + gene_symbol = TRUE, + sample_list = NULL, + sample_names = NULL, + shared_suffix = NULL, + parallel = FALSE, + num_cores = NULL, + sort_type = FALSE +) } \arguments{ -\item{loom_file}{} +\item{loom_file}{path and name of loom file to read} + +\item{data_dir}{path to data directory containing all loom files to read} + +\item{gene_symbol}{logical, should rownames of returned matrices have gene symbols or accession ID #s, +default is TRUE (symbols).} + +\item{sample_list}{A vector of file prefixes/names if specific samples are desired. Default is \code{NULL} and +will load all samples in given directory.} + +\item{sample_names}{a set of sample names to use for each sample entry in returned list. If \code{NULL} +will set names to the file name of each sample.} + +\item{shared_suffix}{a suffix and file extension shared by all samples.} + +\item{parallel}{logical (default FALSE). Whether to use multiple cores when reading in data. +Only possible on Linux based systems.} + +\item{num_cores}{if \code{parallel = TRUE} indicates the number of cores to use for multicore processing.} + +\item{sort_type}{logical, default is FALSE and will return list with 1 sample per entry. Each +sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of +3 matrix types (spliced, unspliced, ambiguous) with one entry per sample} } \value{ list of sparse matrices containing spliced, unspliced, and ambiguous counts From 8fa7493e585dfac10cd72754930b13a5a7ce972f Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:47:36 -0500 Subject: [PATCH 023/105] Update manual --- R/Read_Write_Data.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 179260085..e9f938849 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1632,7 +1632,7 @@ ReadLoomMatrices <- function( #' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of #' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample #' -#' @returns +#' @returns list of list of matrices #' @noRd #' @keywords internal #' From 03e01184c1eb6249c47cc70da4efb174cee4122d Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:34:52 -0500 Subject: [PATCH 024/105] rearrange parameters --- R/Read_Write_Data.R | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index e9f938849..43f238474 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1702,6 +1702,7 @@ ReadVelocity_Multi_File_Internal <- function( names(x = raw_data_list) <- sample_names } + # sort matrices by read type if (isTRUE(x = sort_type)) { spliced_list <- lapply(1:length(x = raw_data_list), function(x){ data <- testing[[x]][["spliced"]] @@ -1721,7 +1722,6 @@ ReadVelocity_Multi_File_Internal <- function( raw_data_list <- list("spliced" = spliced_list, "unspliced" = unspliced_list, "ambiguous" = ambiguous_list) - } # return object @@ -1736,6 +1736,9 @@ ReadVelocity_Multi_File_Internal <- function( #' @param data_dir path to data directory containing all loom files to read #' @param gene_symbol logical, should rownames of returned matrices have gene symbols or accession ID #s, #' default is TRUE (symbols). +#' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each +#' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of +#' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample #' @param sample_list A vector of file prefixes/names if specific samples are desired. Default is `NULL` and #' will load all samples in given directory. #' @param sample_names a set of sample names to use for each sample entry in returned list. If `NULL` @@ -1744,9 +1747,6 @@ ReadVelocity_Multi_File_Internal <- function( #' @param parallel logical (default FALSE). Whether to use multiple cores when reading in data. #' Only possible on Linux based systems. #' @param num_cores if `parallel = TRUE` indicates the number of cores to use for multicore processing. -#' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each -#' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of -#' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample #' #' @return list of sparse matrices containing spliced, unspliced, and ambiguous counts #' @@ -1768,12 +1768,12 @@ Read_Velocity <- function( data_dir = NULL, multi_dir = TRUE, gene_symbol = TRUE, + sort_type = FALSE, sample_list = NULL, sample_names = NULL, shared_suffix = NULL, parallel = FALSE, - num_cores = NULL, - sort_type = FALSE + num_cores = NULL ) { if (!is.null(x = loom_file) && !is.null(x = data_dir)) { cli_abort(message = "Cannot specify values for both {.code loom_file} and {.code data_dir}.") From 9aed30a5f9b586de8215ab7df03affeab9cd2383 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:45:10 -0500 Subject: [PATCH 025/105] Update to use internal and add single duplicate warning when mutli-file --- R/Read_Write_Data.R | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 43f238474..bf687c0da 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1686,15 +1686,19 @@ ReadVelocity_Multi_File_Internal <- function( "i" = "If function fails set {.code parallel = FALSE} and re-run for informative error reporting.")) raw_data_list <- pmclapply(mc.cores = num_cores, 1:length(x = sample_list), function(i) { loom_loc <- file.path(data_dir, paste0(sample_list[i], shared_suffix, ".loom")) - data <- Read_Velocity(loom_file = loom_loc, gene_symbol = gene_symbol) + data <- ReadLoomMatrices(loom_file = loom_loc, gene_symbol = gene_symbol, verbose = FALSE) }) } else { raw_data_list <- pblapply(1:length(x = sample_list), function(i) { loom_loc <- file.path(data_dir, paste0(sample_list[i], shared_suffix, ".loom")) - data <- Read_Velocity(loom_file = loom_loc, gene_symbol = gene_symbol) + data <- ReadLoomMatrices(loom_file = loom_loc, gene_symbol = gene_symbol, verbose = FALSE) }) } + # add call to report duplicates single time + reporter_file_path <- file.path(data_dir, paste0(sample_list[i], shared_suffix, ".loom")) + reporter_data <- scCustomize:::ReadLoomMatrices(loom_file = reporter_file_path, gene_symbol = gene_symbol, verbose = TRUE) + # Name the matrices if (is.null(x = sample_names)) { names(x = raw_data_list) <- sample_list From 6f12dc0be2976344c36a539e494e3ff4329096e5 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:00:03 -0500 Subject: [PATCH 026/105] add multi dir internal --- R/Read_Write_Data.R | 159 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 147 insertions(+), 12 deletions(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index bf687c0da..ea893d22d 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -502,8 +502,6 @@ Read10X_GEO <- function( #' @import mcprogress #' @import parallel #' @import pbapply -#' @importFrom Matrix readMM -#' @importFrom utils read.delim txtProgressBar setTxtProgressBar #' #' @export #' @@ -767,7 +765,6 @@ Read10X_Multi_Directory <- function( #' @import pbapply #' @importFrom Seurat Read10X_h5 #' @importFrom stringr str_extract -#' @importFrom utils txtProgressBar setTxtProgressBar #' #' @export #' @@ -1612,7 +1609,6 @@ ReadLoomMatrices <- function( } - #' Read multiple loom files from same directory #' #' Internal wrapper to be used be `Read_Velocity` if data directory is provided. @@ -1620,6 +1616,9 @@ ReadLoomMatrices <- function( #' @param data_dir Directory containing the loom files provided by velocyto. #' @param gene_symbol logical, should rownames of returned matrices have gene symbols or accession ID #s, #' default is TRUE (symbols). +#' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each +#' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of +#' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample #' @param sample_list A vector of file prefixes/names if specific samples are desired. Default is `NULL` and #' will load all samples in given directory. #' @param sample_names a set of sample names to use for each sample entry in returned list. If `NULL` @@ -1628,24 +1627,25 @@ ReadLoomMatrices <- function( #' @param parallel logical (default FALSE). Whether to use multiple cores when reading in data. #' Only possible on Linux based systems. #' @param num_cores if `parallel = TRUE` indicates the number of cores to use for multicore processing. -#' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each -#' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of -#' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample #' #' @returns list of list of matrices #' @noRd #' @keywords internal #' +#' @import mcprogress +#' @import parallel +#' @import pbapply +#' ReadVelocity_Multi_File_Internal <- function( data_dir = NULL, gene_symbol = TRUE, + sort_type = FALSE, sample_list = NULL, sample_names = NULL, shared_suffix = NULL, parallel = FALSE, - num_cores = NULL, - sort_type = FALSE + num_cores = NULL ) { if (!dir.exists(paths = data_dir)) { cli_abort(message = "Directory provided does not exist") @@ -1697,7 +1697,7 @@ ReadVelocity_Multi_File_Internal <- function( # add call to report duplicates single time reporter_file_path <- file.path(data_dir, paste0(sample_list[i], shared_suffix, ".loom")) - reporter_data <- scCustomize:::ReadLoomMatrices(loom_file = reporter_file_path, gene_symbol = gene_symbol, verbose = TRUE) + reporter_data <- ReadLoomMatrices(loom_file = reporter_file_path, gene_symbol = gene_symbol, verbose = TRUE) # Name the matrices if (is.null(x = sample_names)) { @@ -1732,13 +1732,132 @@ ReadVelocity_Multi_File_Internal <- function( return(raw_data_list) } + +#' Read loom files from multiple directories +#' +#' Wrapper to read loom files from multiple directory and return a list +#' +#' @param base_path path to the parent directory which contains all of the subdirectories of interest. +#' @param secondary_path path from the parent directory to loom files for each sample. +#' @param gene_symbol logical, should rownames of returned matrices have gene symbols or accession ID #s, +#' default is TRUE (symbols). +#' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each +#' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of +#' 3 matrix types (spliced, unspliced, ambiguous) with one entry per sample +#' @param sample_list A vector of file prefixes/names if specific samples are desired. Default is `NULL` and +#' will load all samples in given directory. +#' @param sample_names a set of sample names to use for each sample entry in returned list. If `NULL` +#' will set names to the file name of each sample. +#' @param shared_suffix a suffix and file extension shared by all samples. +#' @param parallel logical (default FALSE). Whether to use multiple cores when reading in data. +#' Only possible on Linux based systems. +#' @param num_cores if `parallel = TRUE` indicates the number of cores to use for multicore processing. +#' +#' @returns list of list of matrices +#' @noRd +#' @keywords internal +#' +#' @import mcprogress +#' @import parallel +#' @import pbapply +#' + +ReadVelocity_Multi_Directory <- function( + base_path, + secondary_path = NULL, + gene_symbol = TRUE, + sort_type = FALSE, + sample_list = NULL, + sample_names = NULL, + parallel = FALSE, + num_cores = NULL +) { + # Confirm num_cores specified + if (isTRUE(x = parallel) && is.null(x = num_cores)) { + cli_abort("If {.code parallel = TRUE} then {.code num_cores} must be specified.") + } + # Confirm directory exists + if (dir.exists(paths = base_path) == FALSE) { + cli_abort(message = "Directory: {.val {base_path}} specified by {.code base_path} does not exist.") + } + # Detect libraries if sample_list is NULL + if (is.null(x = sample_list)) { + sample_list <- Pull_Directory_List(base_path = base_path) + } + + # set "" if no secondary path + if (is.null(x = secondary_path)) { + secondary_path <- "" + } + # Check if full directory path exists + for (i in 1:length(x = sample_list)) { + full_directory_path <- file.path(base_path, sample_list[i], secondary_path) + if (dir.exists(paths = full_directory_path) == FALSE) { + cli_abort(message = "Full Directory does not exist {.val {full_directory_path}} was not found.") + } + } + + # read data + cli_inform(message = "{.field Reading Loom files.}") + if (isTRUE(x = parallel)) { + cli_inform(message = c("NOTE: Parallel processing may not report informative error messages.", + "i" = "If function fails set {.code parallel = FALSE} and re-run for informative error reporting.")) + # if parallel + raw_data_list <- pmclapply(mc.cores = num_cores, 1:length(x = sample_list), function(x) { + file_path <- file.path(base_path, sample_list[x], secondary_path, paste0(sample_list[x], ".loom")) + raw_data <- ReadLoomMatrices(loom_file = file_path, gene_symbol = gene_symbol, verbose = FALSE) + return(raw_data) + }) + } else { + raw_data_list <- pblapply(1:length(x = sample_list), function(x) { + file_path <- file.path(base_path, sample_list[x], secondary_path, paste0(sample_list[x], ".loom")) + raw_data <- ReadLoomMatrices(loom_file = file_path, gene_symbol = gene_symbol, verbose = FALSE) + }) + } + + # add call to report duplicates single time + reporter_file_path <- file.path(base_path, sample_list[1], secondary_path, paste0(sample_list[1], ".loom")) + reporter_data <- ReadLoomMatrices(loom_file = reporter_file_path, gene_symbol = gene_symbol, verbose = TRUE) + + # Name the list items + if (is.null(x = sample_names)) { + names(x = raw_data_list) <- sample_list + } else { + names(x = raw_data_list) <- sample_names + } + + # sort matrices by read type + if (isTRUE(x = sort_type)) { + spliced_list <- lapply(1:length(x = raw_data_list), function(x){ + data <- testing[[x]][["spliced"]] + }) + names(x = spliced_list) <- names(x = raw_data_list) + + unspliced_list <- lapply(1:length(x = raw_data_list), function(x){ + data <- testing[[x]][["unspliced"]] + }) + names(x = unspliced_list) <- names(x = raw_data_list) + + ambiguous_list <- lapply(1:length(x = raw_data_list), function(x){ + data <- testing[[x]][["ambiguous"]] + }) + names(x = ambiguous_list) <- names(x = raw_data_list) + + raw_data_list <- list("spliced" = spliced_list, + "unspliced" = unspliced_list, + "ambiguous" = ambiguous_list) + } + return(raw_data_list) +} + + #' Load RNA Velocity results #' #' Wrapper function to #' #' @param loom_file path and name of loom file to read #' @param data_dir path to data directory containing all loom files to read -#' @param gene_symbol logical, should rownames of returned matrices have gene symbols or accession ID #s, +#' @param gene_symbol logical, should row names of returned matrices have gene symbols or accession ID #s, #' default is TRUE (symbols). #' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each #' sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of @@ -1750,7 +1869,7 @@ ReadVelocity_Multi_File_Internal <- function( #' @param shared_suffix a suffix and file extension shared by all samples. #' @param parallel logical (default FALSE). Whether to use multiple cores when reading in data. #' Only possible on Linux based systems. -#' @param num_cores if `parallel = TRUE` indicates the number of cores to use for multicore processing. +#' @param num_cores if `parallel = TRUE` indicates the number of cores to use for multi-core processing. #' #' @return list of sparse matrices containing spliced, unspliced, and ambiguous counts #' @@ -1764,7 +1883,23 @@ ReadVelocity_Multi_File_Internal <- function( #' #' @examples #' \dontrun{ +#' # Read single velocity loom file #' velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom") +#' +#' # Read single velocity loom file with ensembl IDs +#' velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom", gene_symbol = FALSE) +#' +#' # Read multiple files from a parent directory with many subdirectories & return 1 list entry per sample +#' # Each entry will contain 3 matrices (spliced, unspliced, ambiguous) +#' velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/") +#' +#' # Sort returned list by read type instead of by sample +#' # list will contain 3 entries (spliced, unspliced, ambiguous) +#' # each entry will contain 1 matrix per sample +#' velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/", sort_type = TRUE) +#' +#' # Read multiple files from a single directory +#' velo_res_list <- Read_Velocity(loom_file = "PATH/", multi_dir = FALSE) #' } Read_Velocity <- function( From 30777b97a420ad736d5ecd1421cbfae360f50cf2 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:00:32 -0500 Subject: [PATCH 027/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f264f30d0..dbd3f91ef 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.0003 -Date: 2026-01-07 +Version: 3.2.4.0004 +Date: 2026-01-13 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From ce9cfad5317f492e014e99fa0f80cf9b05ec3906 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:01:08 -0500 Subject: [PATCH 028/105] Update docs --- man/Read_Velocity.Rd | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/man/Read_Velocity.Rd b/man/Read_Velocity.Rd index 401bab99c..4dda22689 100644 --- a/man/Read_Velocity.Rd +++ b/man/Read_Velocity.Rd @@ -9,12 +9,12 @@ Read_Velocity( data_dir = NULL, multi_dir = TRUE, gene_symbol = TRUE, + sort_type = FALSE, sample_list = NULL, sample_names = NULL, shared_suffix = NULL, parallel = FALSE, - num_cores = NULL, - sort_type = FALSE + num_cores = NULL ) } \arguments{ @@ -22,9 +22,13 @@ Read_Velocity( \item{data_dir}{path to data directory containing all loom files to read} -\item{gene_symbol}{logical, should rownames of returned matrices have gene symbols or accession ID #s, +\item{gene_symbol}{logical, should row names of returned matrices have gene symbols or accession ID #s, default is TRUE (symbols).} +\item{sort_type}{logical, default is FALSE and will return list with 1 sample per entry. Each +sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of +3 matrix types (spliced, unspliced, ambiguous) with one entry per sample} + \item{sample_list}{A vector of file prefixes/names if specific samples are desired. Default is \code{NULL} and will load all samples in given directory.} @@ -36,11 +40,7 @@ will set names to the file name of each sample.} \item{parallel}{logical (default FALSE). Whether to use multiple cores when reading in data. Only possible on Linux based systems.} -\item{num_cores}{if \code{parallel = TRUE} indicates the number of cores to use for multicore processing.} - -\item{sort_type}{logical, default is FALSE and will return list with 1 sample per entry. Each -sample entry will contain 3 matrices (spliced, unspliced, ambiguous). If TRUE will return list of -3 matrix types (spliced, unspliced, ambiguous) with one entry per sample} +\item{num_cores}{if \code{parallel = TRUE} indicates the number of cores to use for multi-core processing.} } \value{ list of sparse matrices containing spliced, unspliced, and ambiguous counts @@ -50,7 +50,23 @@ Wrapper function to } \examples{ \dontrun{ +# Read single velocity loom file velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom") + +# Read single velocity loom file with ensembl IDs +velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom", gene_symbol = FALSE) + +# Read multiple files from a parent directory with many subdirectories & return 1 list entry per sample +# Each entry will contain 3 matrices (spliced, unspliced, ambiguous) +velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/") + +# Sort returned list by read type instead of by sample +# list will contain 3 entries (spliced, unspliced, ambiguous) +# each entry will contain 1 matrix per sample +velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/", sort_type = TRUE) + +# Read multiple files from a single directory +velo_res_list <- Read_Velocity(loom_file = "PATH/", multi_dir = FALSE) } } \references{ From 524c97467621d54e8b3fe075ebb32a74fb17aa75 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:04:42 -0500 Subject: [PATCH 029/105] Update manual --- R/Read_Write_Data.R | 2 ++ man/Read_Velocity.Rd | 2 ++ 2 files changed, 4 insertions(+) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index ea893d22d..3eb1086ed 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1879,6 +1879,8 @@ ReadVelocity_Multi_Directory <- function( #' \url{https://github.com/satijalab/seurat-wrappers/blob/master/R/velocity.R} (License: GPL-3). #' Function included in scCustomize to avoid installation issues related to other aspects of #' velocyto.R package which `SeuratWrappers::ReadVelocity` requires. +#' scCustomize version also adds multi-file and multi-directory support, ability to return Ensembl IDs, +#' and multi-core parallel file reading. #' #' #' @examples diff --git a/man/Read_Velocity.Rd b/man/Read_Velocity.Rd index 4dda22689..b05b73491 100644 --- a/man/Read_Velocity.Rd +++ b/man/Read_Velocity.Rd @@ -74,4 +74,6 @@ Function is updated from \code{SeuratWrappers::ReadVelocity} \url{https://github.com/satijalab/seurat-wrappers/blob/master/R/velocity.R} (License: GPL-3). Function included in scCustomize to avoid installation issues related to other aspects of velocyto.R package which \code{SeuratWrappers::ReadVelocity} requires. +scCustomize version also adds multi-file and multi-directory support, ability to return Ensembl IDs, +and multi-core parallel file reading. } From 8b4f6e939259342c58c6bf823ef74c5f98555ed1 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 14 Jan 2026 08:40:49 -0500 Subject: [PATCH 030/105] remove old notes --- R/Read_Write_Data.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 3eb1086ed..4e8429e33 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -689,7 +689,7 @@ Read10X_Multi_Directory <- function( if (isTRUE(x = parallel)) { cli_inform(message = c("NOTE: Parallel processing may not report informative error messages.", "i" = "If function fails set {.code parallel = FALSE} and re-run for informative error reporting.")) - # *** Here is where the swap of mclapply or pbmclapply is occuring *** + raw_data_list <- pmclapply(mc.cores = num_cores, 1:length(x = sample_list), function(x) { if (isTRUE(x = cellranger_multi)) { file_path <- file.path(base_path, sample_list[x], secondary_path, sample_list[x], multi_extra_path) @@ -839,7 +839,7 @@ Read10X_h5_Multi_Directory <- function( if (isTRUE(x = parallel)) { cli_inform(message = c("NOTE: Parallel processing may not report informative error messages.", "i" = "If function fails set {.code parallel = FALSE} and re-run for informative error reporting.")) - # *** Here is where the swap of mclapply or pbmclapply is occuring *** + raw_data_list <- pmclapply(mc.cores = num_cores, 1:length(x = sample_list), function(x) { if (isTRUE(x = cellranger_multi)) { file_path <- file.path(base_path, sample_list[x], secondary_path, sample_list[x], multi_extra_path, h5_filename) From 91c79cf33e656fd12ef04e55e62ab869b43fb962 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:24:25 -0500 Subject: [PATCH 031/105] styling --- R/Internal_Utilities.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/Internal_Utilities.R b/R/Internal_Utilities.R index 7c3a2250e..f06b2e476 100644 --- a/R/Internal_Utilities.R +++ b/R/Internal_Utilities.R @@ -590,7 +590,7 @@ Percent_Expressing_Meta <- function( row_dim_names <- features_list col_dim_names <- names(x = percent_expressing) mat_dims <- list(row_dim_names, col_dim_names) - final_df <- data.frame(matrix(unlist(percent_expressing), nrow = length(features_list), byrow = FALSE, dimnames = mat_dims), stringsAsFactors = FALSE) + final_df <- data.frame(matrix(unlist(x = percent_expressing), nrow = length(features_list), byrow = FALSE, dimnames = mat_dims), stringsAsFactors = FALSE) return(final_df) } @@ -645,7 +645,7 @@ Middle_Number <- function( max ) { min_max <- c(min, max) - middle <- min_max[-length(min_max)] + diff(min_max) / 2 + middle <- min_max[-length(x = min_max)] + diff(x = min_max) / 2 return(middle) } From 580a5e9b07ec81be9f2fd2d8dcc4b1d118eefaf0 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:11:34 -0500 Subject: [PATCH 032/105] add check dots --- R/Generics.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/Generics.R b/R/Generics.R index 29479e106..7a08cf2da 100644 --- a/R/Generics.R +++ b/R/Generics.R @@ -153,6 +153,7 @@ Add_MALAT1_Threshold <- function(object, ...) { #' Add_Cell_QC_Metrics <- function(object, ...) { + rlang::check_dots_used() UseMethod(generic = "Add_Cell_QC_Metrics", object = object) } From 9932c8127a7b336ad16dbeb79d206c8b6a45a1b9 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:13:55 -0500 Subject: [PATCH 033/105] change to warning --- R/Generics.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Generics.R b/R/Generics.R index 7a08cf2da..a44347e10 100644 --- a/R/Generics.R +++ b/R/Generics.R @@ -153,7 +153,7 @@ Add_MALAT1_Threshold <- function(object, ...) { #' Add_Cell_QC_Metrics <- function(object, ...) { - rlang::check_dots_used() + rlang::check_dots_used(error = function(e) warn(e)) UseMethod(generic = "Add_Cell_QC_Metrics", object = object) } From 7b93089bd6dbd4c13c8bd7156e40a38d4c095d0c Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:19:25 -0500 Subject: [PATCH 034/105] Seurat version --- R/Generics.R | 1 - R/Utilities_QC_Seurat.R | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/R/Generics.R b/R/Generics.R index a44347e10..29479e106 100644 --- a/R/Generics.R +++ b/R/Generics.R @@ -153,7 +153,6 @@ Add_MALAT1_Threshold <- function(object, ...) { #' Add_Cell_QC_Metrics <- function(object, ...) { - rlang::check_dots_used(error = function(e) warn(e)) UseMethod(generic = "Add_Cell_QC_Metrics", object = object) } diff --git a/R/Utilities_QC_Seurat.R b/R/Utilities_QC_Seurat.R index 7749bdf12..c595f81df 100644 --- a/R/Utilities_QC_Seurat.R +++ b/R/Utilities_QC_Seurat.R @@ -119,6 +119,8 @@ Add_Cell_QC_Metrics.Seurat <- function( overwrite = FALSE, ... ) { + Seurat:::CheckDots(...) + # Set assay assay <- assay %||% DefaultAssay(object = object) From 5f023aa3c38bbc9883e77bcb1226c0a1fb805516 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:24:14 -0500 Subject: [PATCH 035/105] base --- R/Utilities_QC_Seurat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Utilities_QC_Seurat.R b/R/Utilities_QC_Seurat.R index c595f81df..7ef58fea8 100644 --- a/R/Utilities_QC_Seurat.R +++ b/R/Utilities_QC_Seurat.R @@ -119,7 +119,7 @@ Add_Cell_QC_Metrics.Seurat <- function( overwrite = FALSE, ... ) { - Seurat:::CheckDots(...) + chkDots(...) # Set assay assay <- assay %||% DefaultAssay(object = object) From 1d6bfbe7d3210983e4fb47f53f0343cf80d6faf7 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:31:37 -0500 Subject: [PATCH 036/105] remove unused parameter --- R/LIGER_Utilities.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/LIGER_Utilities.R b/R/LIGER_Utilities.R index 37587733a..408ee8479 100644 --- a/R/LIGER_Utilities.R +++ b/R/LIGER_Utilities.R @@ -1096,7 +1096,6 @@ Add_Cell_QC_Metrics.liger <- function( add_IEG = TRUE, add_hemo = TRUE, add_lncRNA = TRUE, - add_cell_cycle = TRUE, species, mito_name = "percent_mito", ribo_name = "percent_ribo", From 39869e08bb759a880a41f749d59e5033f056460a Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:31:54 -0500 Subject: [PATCH 037/105] Add native feature check before scoring --- R/Utilities_QC_Seurat.R | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/R/Utilities_QC_Seurat.R b/R/Utilities_QC_Seurat.R index 7ef58fea8..e7fe42cae 100644 --- a/R/Utilities_QC_Seurat.R +++ b/R/Utilities_QC_Seurat.R @@ -241,7 +241,10 @@ Add_Cell_QC_Metrics.Seurat <- function( # Add Cell Cycle Scoring cli_inform(message = "Calculating {.field Cell Cycle Scores}.") - object <- CellCycleScoring(object = object, s.features = Seurat::cc.genes.updated.2019$s.genes, g2m.features = Seurat::cc.genes.updated.2019$g2m.genes) + s.genes_found <- Feature_PreCheck(object = object, features = Seurat::cc.genes.updated.2019$s.genes) + g2m.genes_found <- Feature_PreCheck(object = object, features = Seurat::cc.genes.updated.2019$g2m.genes) + + object <- CellCycleScoring(object = object, s.features = s.genes_found, g2m.features = g2m.genes_found) } } From 67047cc69995f894b3b097a492d52985d885b74c Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:49:34 -0500 Subject: [PATCH 038/105] add chkdots --- R/Utilities_QC_Seurat.R | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/R/Utilities_QC_Seurat.R b/R/Utilities_QC_Seurat.R index e7fe42cae..5f2d9eee9 100644 --- a/R/Utilities_QC_Seurat.R +++ b/R/Utilities_QC_Seurat.R @@ -119,6 +119,7 @@ Add_Cell_QC_Metrics.Seurat <- function( overwrite = FALSE, ... ) { + # check dots chkDots(...) # Set assay @@ -323,6 +324,9 @@ Add_Mito_Ribo.Seurat <- function( species_prefix = NULL, ... ) { + # check dots + chkDots(...) + # Accepted species names accepted_names <- data.frame( Mouse_Options = c("Mouse", "mouse", "Ms", "ms", "Mm", "mm"), @@ -561,6 +565,9 @@ Add_Hemo.Seurat <- function( list_species_names = FALSE, ... ) { + # check dots + chkDots(...) + # Accepted species names accepted_names <- data.frame( Mouse_Options = c("Mouse", "mouse", "Ms", "ms", "Mm", "mm"), @@ -716,8 +723,8 @@ Add_Cell_Complexity.Seurat <- function( overwrite = FALSE, ... ) { - # Check Seurat - Is_Seurat(seurat_object = object) + # check dots + chkDots(...) # Add assay warning message if (assay != "RNA") { @@ -800,6 +807,9 @@ Add_Top_Gene_Pct.Seurat <- function( verbose = TRUE, ... ){ + # check dots + chkDots(...) + # Check for scuttle first scuttle_check <- is_installed(pkg = "scuttle") if (isFALSE(x = scuttle_check)) { @@ -999,8 +1009,8 @@ Add_MALAT1_Threshold.Seurat <- function( rough_max = 2, ... ) { - # Check Seurat - Is_Seurat(seurat_object = object) + # check dots + chkDots(...) # Check for sample column if (is.null(x = sample_col) && isFALSE(x = whole_object)) { From d0bc01d206ccc37cc6a4f0a2577b76d3f2c46a5d Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:50:06 -0500 Subject: [PATCH 039/105] remove from liger --- man/Add_Cell_QC_Metrics.Rd | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/man/Add_Cell_QC_Metrics.Rd b/man/Add_Cell_QC_Metrics.Rd index d21756750..a05a37e52 100644 --- a/man/Add_Cell_QC_Metrics.Rd +++ b/man/Add_Cell_QC_Metrics.Rd @@ -18,7 +18,6 @@ Add_Cell_QC_Metrics(object, ...) add_IEG = TRUE, add_hemo = TRUE, add_lncRNA = TRUE, - add_cell_cycle = TRUE, species, mito_name = "percent_mito", ribo_name = "percent_ribo", @@ -105,9 +104,6 @@ object (Default is TRUE).} \item{add_lncRNA}{logical, whether to add percentage of counts belonging to lncRNA genes to object (Default is TRUE).} -\item{add_cell_cycle}{logical, whether to addcell cycle scores and phase based on -\code{\link[Seurat]{CellCycleScoring}}. Only applicable if \code{species = "human"}. (Default is TRUE).} - \item{species}{Species of origin for given Seurat Object. If mouse, human, marmoset, zebrafish, rat, drosophila, rhesus macaque, or chicken (name or abbreviation) are provided the function will automatically generate patterns and features.} @@ -180,6 +176,9 @@ function will abort if column with name provided to \code{meta_col_name} is pres \item{add_IEG_module_score}{logical, whether to add module score belonging to IEG genes to object (Default is TRUE).} +\item{add_cell_cycle}{logical, whether to addcell cycle scores and phase based on +\code{\link[Seurat]{CellCycleScoring}}. Only applicable if \code{species = "human"}. (Default is TRUE).} + \item{ieg_module_name}{name to use for new meta data column for module score of IEGs. Default is "ieg_score".} } \value{ From e590d59db98d949482cfeed7fff99036b2f3d718 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:51:41 -0500 Subject: [PATCH 040/105] Update changelog --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 640f00397..4d6c1f8ce 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,7 +6,7 @@ ## Changed - +- Add checks for appropriate `...` usage. ## Fixes From 3408f332fdb6702048f719984886f1650fb692a5 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:51:57 -0500 Subject: [PATCH 041/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index dbd3f91ef..8917ce518 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.0004 -Date: 2026-01-13 +Version: 3.2.4.0005 +Date: 2026-01-23 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From 904ab2b9e691ef186cecc883f9275c55e9c9393c Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:11:56 -0500 Subject: [PATCH 042/105] fix single directory --- R/Read_Write_Data.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 4e8429e33..4612d0e4f 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1696,7 +1696,7 @@ ReadVelocity_Multi_File_Internal <- function( } # add call to report duplicates single time - reporter_file_path <- file.path(data_dir, paste0(sample_list[i], shared_suffix, ".loom")) + reporter_file_path <- file.path(data_dir, paste0(sample_list[1], shared_suffix, ".loom")) reporter_data <- ReadLoomMatrices(loom_file = reporter_file_path, gene_symbol = gene_symbol, verbose = TRUE) # Name the matrices From 17096fc6bb86a7e11e742adfe3d9d37caabc65a1 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 18 Feb 2026 12:33:53 -0500 Subject: [PATCH 043/105] add assay_suffix parameter --- R/Utilities_QC_Seurat.R | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/R/Utilities_QC_Seurat.R b/R/Utilities_QC_Seurat.R index 5f2d9eee9..650433d7b 100644 --- a/R/Utilities_QC_Seurat.R +++ b/R/Utilities_QC_Seurat.R @@ -19,6 +19,8 @@ #' @param add_lncRNA logical, whether to add percentage of counts belonging to lncRNA genes to object (Default is TRUE). #' @param add_cell_cycle logical, whether to addcell cycle scores and phase based on #' \code{\link[Seurat]{CellCycleScoring}}. Only applicable if `species = "human"`. (Default is TRUE). +#' @param assay_suffix logical, whether to add assay suffix to the QC column name added to meta.data. +#' Default is FALSE. #' @param mito_name name to use for the new meta.data column containing percent mitochondrial counts. #' Default is "percent_mito". #' @param ribo_name name to use for the new meta.data column containing percent ribosomal counts. @@ -94,6 +96,7 @@ Add_Cell_QC_Metrics.Seurat <- function( add_hemo = TRUE, add_lncRNA = TRUE, add_cell_cycle = TRUE, + assay_suffix = FALSE, mito_name = "percent_mito", ribo_name = "percent_ribo", mito_ribo_name = "percent_mito_ribo", @@ -153,6 +156,11 @@ Add_Cell_QC_Metrics.Seurat <- function( macaque_options <- accepted_names$Macaque_Options chicken_options <- accepted_names$Chicken_Options + # pull column names before adding QC + if (isTRUE(x = assay_suffix)) { + old_col_names <- colnames(x = Fetch_Meta(object = object)) + } + # Add mito/ribo if (isTRUE(x = add_mito_ribo)) { cli_inform(message = c("*" = "Adding {.field Mito/Ribo Percentages} to meta.data.")) @@ -249,6 +257,20 @@ Add_Cell_QC_Metrics.Seurat <- function( } } + # pull new column names after adding QC + if (isTRUE(x = assay_suffix)) { + new_col_names <- colnames(x = Fetch_Meta(object = object)) + + added_cols <- setdiff(x = new_col_names, y = old_col_names) + + assay <- DefaultAssay(object = object) + + added_cols_new <- paste0(added_cols, "_", assay) + + # Add assay suffix to new columns + colnames(x = object@meta.data) <- c(old_col_names, added_cols_new) + } + # Log Command object <- LogSeuratCommand(object = object) From 5e63d6786bb09789006970938133201fa220ac61 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 18 Feb 2026 12:51:44 -0500 Subject: [PATCH 044/105] assay suffix to exam and MALAT1 functions --- R/Utilities_QC_Seurat.R | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/R/Utilities_QC_Seurat.R b/R/Utilities_QC_Seurat.R index 650433d7b..c8f80abdc 100644 --- a/R/Utilities_QC_Seurat.R +++ b/R/Utilities_QC_Seurat.R @@ -929,6 +929,8 @@ Add_Top_Gene_Pct.Seurat <- function( #' @param sample_col column name in meta.data that contains sample ID information. #' @param malat1_threshold_name name to use for the new meta.data column containing percent IEG gene counts. #' Default is set dependent on species gene symbol. +#' @param assay_suffix logical, whether to add assay suffix to the QC column name added to meta.data. +#' Default is FALSE. #' @param ensembl_ids logical, whether feature names in the object are gene names or #' ensembl IDs (default is FALSE; set TRUE if feature names are ensembl IDs). #' @param assay Assay to use (default is the current object default assay). @@ -1011,6 +1013,7 @@ Add_MALAT1_Threshold.Seurat <- function( species, sample_col = NULL, malat1_threshold_name = NULL, + assay_suffix = FALSE, ensembl_ids = FALSE, assay = NULL, overwrite = FALSE, @@ -1086,6 +1089,11 @@ Add_MALAT1_Threshold.Seurat <- function( } } + # pull column names before adding QC + if (isTRUE(x = assay_suffix)) { + old_col_names <- colnames(x = Fetch_Meta(object = object)) + } + # Overwrite check if (malat1_threshold_name %in% colnames(x = object@meta.data)) { if (isFALSE(x = overwrite)) { @@ -1247,6 +1255,20 @@ Add_MALAT1_Threshold.Seurat <- function( object[[malat1_threshold_name]] <- factor(object[[malat1_threshold_name]][,1], levels = c("TRUE","FALSE")) } + # pull new column names after adding QC + if (isTRUE(x = assay_suffix)) { + new_col_names <- colnames(x = Fetch_Meta(object = object)) + + added_cols <- setdiff(x = new_col_names, y = old_col_names) + + assay <- DefaultAssay(object = object) + + added_cols_new <- paste0(added_cols, "_", assay) + + # Add assay suffix to new columns + colnames(x = object@meta.data) <- c(old_col_names, added_cols_new) + } + object <- LogSeuratCommand(object = object) return(object) @@ -1260,6 +1282,8 @@ Add_MALAT1_Threshold.Seurat <- function( #' @param seurat_object object name. #' @param species Species of origin for given Seurat Object. Only accepted species are: mouse, human (name or abbreviation). #' @param exam_module_name name to use for the new meta.data column containing module scores. +#' @param assay_suffix logical, whether to add assay suffix to the QC column name added to meta.data. +#' Default is FALSE. #' @param method method to use for module scoring, currently only "Seurat" is supported but more to be added. . #' @param ensembl_ids logical, whether feature names in the object are gene names or #' ensembl IDs (default is FALSE; set TRUE if feature names are ensembl IDs). @@ -1289,6 +1313,7 @@ exAM_Scoring <- function( seurat_object, species, exam_module_name = NULL, + assay_suffix = FALSE, method = "Seurat", ensembl_ids = FALSE, assay = NULL, @@ -1330,6 +1355,11 @@ exAM_Scoring <- function( # Check Seurat Is_Seurat(seurat_object = seurat_object) + # pull column names before adding QC + if (isTRUE(x = assay_suffix)) { + old_col_names <- colnames(x = Fetch_Meta(object = seurat_object)) + } + if (method == "UCell") { # Check Nebulosa installed UCell_check <- is_installed(pkg = "UCell") @@ -1412,6 +1442,20 @@ exAM_Scoring <- function( } } + # pull new column names after adding QC + if (isTRUE(x = assay_suffix)) { + new_col_names <- colnames(x = Fetch_Meta(object = seurat_object)) + + added_cols <- setdiff(x = new_col_names, y = old_col_names) + + assay <- DefaultAssay(object = seurat_object) + + added_cols_new <- paste0(added_cols, "_", assay) + + # Add assay suffix to new columns + colnames(x = seurat_object@meta.data) <- c(old_col_names, added_cols_new) + } + # Log Command seurat_object <- LogSeuratCommand(object = seurat_object) From a535b8af4b56a4f1162229839a7a01063bead9dc Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:30:50 -0500 Subject: [PATCH 045/105] deprecate plot_by and replace with group.by for Seq_QC_Plot_* family --- R/Plotting_QC_Seq_10X.R | 627 +++++++++++++++++++++++++--------------- 1 file changed, 389 insertions(+), 238 deletions(-) diff --git a/R/Plotting_QC_Seq_10X.R b/R/Plotting_QC_Seq_10X.R index 6ebf4c9bf..e9208f27f 100644 --- a/R/Plotting_QC_Seq_10X.R +++ b/R/Plotting_QC_Seq_10X.R @@ -8,7 +8,8 @@ #' Plot the mean number of reads per cell #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -35,45 +36,55 @@ Seq_QC_Plot_Reads_per_Cell <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Reads_per_Cell(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") + } + + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use } } - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Mean_Reads_per_Cell"]])) + @@ -89,7 +100,7 @@ Seq_QC_Plot_Reads_per_Cell <- function( xlab("") + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Mean_Reads_per_Cell"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Mean_Reads_per_Cell"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + theme(legend.position = "none", @@ -100,7 +111,7 @@ Seq_QC_Plot_Reads_per_Cell <- function( scale_fill_manual(values = colors_use) + ggtitle("Mean Reads per Cell per Sample") + ylab('Mean Reads per Cell') + - xlab(plot_by) + + xlab(group.by) + theme_ggprism_mod() } @@ -120,10 +131,10 @@ Seq_QC_Plot_Reads_per_Cell <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by ,colors_use = NULL,]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -142,7 +153,7 @@ Seq_QC_Plot_Reads_per_Cell <- function( #' Plot the number of cells per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -169,45 +180,55 @@ Seq_QC_Plot_Reads_per_Cell <- function( Seq_QC_Plot_Number_Cells <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Number_Cells(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use } } - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Estimated_Number_of_Cells"]])) + @@ -223,7 +244,7 @@ Seq_QC_Plot_Number_Cells <- function( xlab("") + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Estimated_Number_of_Cells"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Estimated_Number_of_Cells"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + theme(legend.position = "none", @@ -234,7 +255,7 @@ Seq_QC_Plot_Number_Cells <- function( scale_fill_manual(values = colors_use) + ggtitle("Cells per Sample") + ylab('Cells') + - xlab(plot_by) + + xlab(group.by) + theme_ggprism_mod() } @@ -254,10 +275,10 @@ Seq_QC_Plot_Number_Cells <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -276,7 +297,7 @@ Seq_QC_Plot_Number_Cells <- function( #' Plot the median genes per cell per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -303,45 +324,55 @@ Seq_QC_Plot_Number_Cells <- function( Seq_QC_Plot_Genes <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Genes(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { cli_abort(message = " is not a column in the provided `metrics_dataframe`.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use } } - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Median_Genes_per_Cell"]])) + @@ -352,13 +383,13 @@ Seq_QC_Plot_Genes <- function( xlab("") + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Median_Genes_per_Cell"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Median_Genes_per_Cell"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Median Genes per Cell") + ylab('Median Genes') + - xlab(plot_by) + + xlab(group.by) + theme_ggprism_mod() } @@ -378,10 +409,10 @@ Seq_QC_Plot_Genes <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -400,7 +431,7 @@ Seq_QC_Plot_Genes <- function( #' Plot the median UMIs per cell per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -427,45 +458,55 @@ Seq_QC_Plot_Genes <- function( Seq_QC_Plot_UMIs <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_UMIs(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use } } - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Median_UMI_Counts_per_Cell"]])) + @@ -476,13 +517,13 @@ Seq_QC_Plot_UMIs <- function( xlab("") + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Median_UMI_Counts_per_Cell"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Median_UMI_Counts_per_Cell"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Median UMIs per Cell") + ylab('Median UMIs') + - xlab(plot_by) + + xlab(group.by) + theme_ggprism_mod() } @@ -502,10 +543,10 @@ Seq_QC_Plot_UMIs <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -524,7 +565,7 @@ Seq_QC_Plot_UMIs <- function( #' Plot the total genes detected per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -551,45 +592,55 @@ Seq_QC_Plot_UMIs <- function( Seq_QC_Plot_Total_Genes <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Total_Genes(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") + } + + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use } } - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Total_Genes_Detected"]])) + @@ -600,13 +651,13 @@ Seq_QC_Plot_Total_Genes <- function( xlab("") + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Total_Genes_Detected"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Total_Genes_Detected"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Total Genes Detected per Sample") + ylab('Total Genes') + - xlab(plot_by) + + xlab(group.by) + theme_ggprism_mod() } @@ -626,10 +677,10 @@ Seq_QC_Plot_Total_Genes <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -648,7 +699,7 @@ Seq_QC_Plot_Total_Genes <- function( #' Plot the sequencing saturation percentage per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -676,38 +727,48 @@ Seq_QC_Plot_Total_Genes <- function( Seq_QC_Plot_Saturation <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Saturation(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -718,7 +779,7 @@ Seq_QC_Plot_Saturation <- function( metrics_dataframe[,"Sequencing_Saturation"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Sequencing_Saturation"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Sequencing_Saturation"]]), color = .data[["samples_plotting"]]) + @@ -730,13 +791,13 @@ Seq_QC_Plot_Saturation <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Sequencing_Saturation"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Sequencing_Saturation"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Sequencing Saturation") + ylab('Sequencing Saturation Percent') + - xlab(plot_by)+ + xlab(group.by)+ scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -757,10 +818,10 @@ Seq_QC_Plot_Saturation <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -779,7 +840,7 @@ Seq_QC_Plot_Saturation <- function( #' Plot the fraction of reads in cells per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -807,38 +868,48 @@ Seq_QC_Plot_Saturation <- function( Seq_QC_Plot_Reads_in_Cells <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Reads_in_Cells(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") + } + + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -849,7 +920,7 @@ Seq_QC_Plot_Reads_in_Cells <- function( metrics_dataframe[,"Fraction_Reads_in_Cells"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Fraction_Reads_in_Cells"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Fraction_Reads_in_Cells"]]), color = .data[["samples_plotting"]]) + @@ -861,13 +932,13 @@ Seq_QC_Plot_Reads_in_Cells <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Fraction_Reads_in_Cells"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Fraction_Reads_in_Cells"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Fraction of Reads in Cells per Sample") + ylab('Fraction of Reads in Cells') + - xlab(plot_by)+ + xlab(group.by)+ scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -888,10 +959,10 @@ Seq_QC_Plot_Reads_in_Cells <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -910,7 +981,7 @@ Seq_QC_Plot_Reads_in_Cells <- function( #' Plot the fraction of reads confidently mapped to transcriptome #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -938,38 +1009,48 @@ Seq_QC_Plot_Reads_in_Cells <- function( Seq_QC_Plot_Transcriptome <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Transcriptome(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -980,7 +1061,7 @@ Seq_QC_Plot_Transcriptome <- function( metrics_dataframe[,"Reads_Mapped_Confidently_to_Transcriptome"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Reads_Mapped_Confidently_to_Transcriptome"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Reads_Mapped_Confidently_to_Transcriptome"]]), color = .data[["samples_plotting"]]) + @@ -992,13 +1073,13 @@ Seq_QC_Plot_Transcriptome <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Reads_Mapped_Confidently_to_Transcriptome"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Reads_Mapped_Confidently_to_Transcriptome"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Percent of Reads Confidently Mapped to Transcriptome") + ylab('Percent of Reads') + - xlab(plot_by) + + xlab(group.by) + scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -1018,10 +1099,10 @@ Seq_QC_Plot_Transcriptome <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -1040,7 +1121,7 @@ Seq_QC_Plot_Transcriptome <- function( #' Plot the fraction of reads confidently mapped to genome #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -1068,38 +1149,48 @@ Seq_QC_Plot_Transcriptome <- function( Seq_QC_Plot_Genome <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Genome(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -1110,7 +1201,7 @@ Seq_QC_Plot_Genome <- function( metrics_dataframe[,"Reads_Mapped_Confidently_to_Genome"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Reads_Mapped_Confidently_to_Genome"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Reads_Mapped_Confidently_to_Genome"]]), color = .data[["samples_plotting"]]) + @@ -1122,13 +1213,13 @@ Seq_QC_Plot_Genome <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Reads_Mapped_Confidently_to_Genome"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Reads_Mapped_Confidently_to_Genome"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Percent of Reads Confidently Mapped to Genome") + ylab('Percent of Reads') + - xlab(plot_by) + + xlab(group.by) + scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -1148,10 +1239,10 @@ Seq_QC_Plot_Genome <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -1170,7 +1261,7 @@ Seq_QC_Plot_Genome <- function( #' Plot the fraction of reads confidently mapped to intergenic regions #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -1198,38 +1289,48 @@ Seq_QC_Plot_Genome <- function( Seq_QC_Plot_Intergenic <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Intergenic(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -1240,7 +1341,7 @@ Seq_QC_Plot_Intergenic <- function( metrics_dataframe[,"Reads_Mapped_Confidently_to_Intergenic_Regions"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Reads_Mapped_Confidently_to_Intergenic_Regions"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Reads_Mapped_Confidently_to_Intergenic_Regions"]]), color = .data[["samples_plotting"]]) + @@ -1252,13 +1353,13 @@ Seq_QC_Plot_Intergenic <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Reads_Mapped_Confidently_to_Intergenic_Regions"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Reads_Mapped_Confidently_to_Intergenic_Regions"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Percent of Reads Confidently Mapped to Intergenic Regions") + ylab('Percent of Reads') + - xlab(plot_by) + + xlab(group.by) + scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -1278,10 +1379,10 @@ Seq_QC_Plot_Intergenic <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -1300,7 +1401,7 @@ Seq_QC_Plot_Intergenic <- function( #' Plot the fraction of reads confidently mapped to intronic regions #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -1328,38 +1429,48 @@ Seq_QC_Plot_Intergenic <- function( Seq_QC_Plot_Intronic <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Intronic(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -1370,7 +1481,7 @@ Seq_QC_Plot_Intronic <- function( metrics_dataframe[,"Reads_Mapped_Confidently_to_Intronic_Regions"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Reads_Mapped_Confidently_to_Intronic_Regions"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Reads_Mapped_Confidently_to_Intronic_Regions"]]), color = .data[["samples_plotting"]]) + @@ -1382,13 +1493,13 @@ Seq_QC_Plot_Intronic <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Reads_Mapped_Confidently_to_Intronic_Regions"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Reads_Mapped_Confidently_to_Intronic_Regions"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Percent of Reads Confidently Mapped to Intronic Regions") + ylab('Percent of Reads') + - xlab(plot_by) + + xlab(group.by) + scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -1408,10 +1519,10 @@ Seq_QC_Plot_Intronic <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -1430,7 +1541,7 @@ Seq_QC_Plot_Intronic <- function( #' Plot the fraction of reads confidently mapped to Exonic regions #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -1458,38 +1569,48 @@ Seq_QC_Plot_Intronic <- function( Seq_QC_Plot_Exonic <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Exonic(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") + } + + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -1500,7 +1621,7 @@ Seq_QC_Plot_Exonic <- function( metrics_dataframe[,"Reads_Mapped_Confidently_to_Exonic_Regions"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Reads_Mapped_Confidently_to_Exonic_Regions"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Reads_Mapped_Confidently_to_Exonic_Regions"]]), color = .data[["samples_plotting"]]) + @@ -1512,13 +1633,13 @@ Seq_QC_Plot_Exonic <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Reads_Mapped_Confidently_to_Exonic_Regions"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Reads_Mapped_Confidently_to_Exonic_Regions"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Percent of Reads Confidently Mapped to Exonic Regions") + ylab('Percent of Reads') + - xlab(plot_by) + + xlab(group.by) + scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -1538,10 +1659,10 @@ Seq_QC_Plot_Exonic <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -1560,7 +1681,7 @@ Seq_QC_Plot_Exonic <- function( #' Plot the fraction of reads mapped Antisense to Gene #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -1588,38 +1709,48 @@ Seq_QC_Plot_Exonic <- function( Seq_QC_Plot_Antisense <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, significance = FALSE, ... ) { - if (!plot_by %in% colnames(x = metrics_dataframe)) { - cli_abort(message = "{.val {plot_by}} is not a column in the provided {.code metrics_dataframe}.") + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Antisense(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + + if (!group.by %in% colnames(x = metrics_dataframe)) { + cli_abort(message = "{.val {group.by}} is not a column in the provided {.code metrics_dataframe}.") } - # Change plot_by to character vector to make significance functions show all comparisons - if (inherits(x = metrics_dataframe[[plot_by]], what = "factor")) { + # Change group.by to character vector to make significance functions show all comparisons + if (inherits(x = metrics_dataframe[[group.by]], what = "factor")) { stats_dataframe <- metrics_dataframe - stats_dataframe[[plot_by]] <- as.character(stats_dataframe[[plot_by]]) + stats_dataframe[[group.by]] <- as.character(stats_dataframe[[group.by]]) } else { stats_dataframe <- metrics_dataframe } # Create color palette if null and check valid if provided - length_plotby <- length(x = unique(x = metrics_dataframe[[plot_by]])) + length_plotby <- length(x = unique(x = metrics_dataframe[[group.by]])) - if (is.null(x = colors_use) && !plot_by == "sample_id") { + if (is.null(x = colors_use) && !group.by == "sample_id") { if (length_plotby <= 8) { colors_use <- Dark2_Pal() } else { colors_use <- DiscretePalette_scCustomize(num_colors = length_plotby, palette = "polychrome") } } else { - if (length(x = colors_use) < length_plotby && !plot_by == "sample_id") { + if (length(x = colors_use) < length_plotby && !group.by == "sample_id") { cli_abort(message = c("Not enough colors provided.", - "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {plot_by}} column: {.field {length_plotby}}.") + "i" = "The number of colors supplied: {.field {length(x = colors_use)}}, is less than the number of groups in {.val {group.by}} column: {.field {length_plotby}}.") ) } else { colors_use <- colors_use @@ -1630,7 +1761,7 @@ Seq_QC_Plot_Antisense <- function( metrics_dataframe[,"Reads_Mapped_Antisense_to_Gene"] <- as.numeric(gsub("%", "", metrics_dataframe[,"Reads_Mapped_Antisense_to_Gene"])) - if (plot_by == "sample_id") { + if (group.by == "sample_id") { metrics_dataframe$samples_plotting <- "Samples" plot <- ggplot(metrics_dataframe, aes(x = .data[["samples_plotting"]], y = .data[["Reads_Mapped_Antisense_to_Gene"]]), color = .data[["samples_plotting"]]) + @@ -1642,13 +1773,13 @@ Seq_QC_Plot_Antisense <- function( scale_y_continuous(labels = label_percent(accuracy = 0.01, scale = 1)) + theme_ggprism_mod() } else { - plot <- ggplot(metrics_dataframe, aes(x=.data[[plot_by]], y = .data[["Reads_Mapped_Antisense_to_Gene"]], fill = .data[[plot_by]])) + + plot <- ggplot(metrics_dataframe, aes(x=.data[[group.by]], y = .data[["Reads_Mapped_Antisense_to_Gene"]], fill = .data[[group.by]])) + geom_boxplot(fill = "white") + geom_dotplot(binaxis ='y', stackdir = 'center', dotsize = dot_size) + scale_fill_manual(values = colors_use) + ggtitle("Percent of Reads Confidently Mapped to Antisense to Gene") + ylab('Percent of Reads') + - xlab(plot_by) + + xlab(group.by) + scale_y_continuous(labels = label_percent(accuracy = 1, scale = 1)) + theme_ggprism_mod() } @@ -1668,10 +1799,10 @@ Seq_QC_Plot_Antisense <- function( )) } - if (length(x = unique(x = stats_dataframe[[plot_by]])) < 2) { - cli_abort(message = "Cannot calculate statistics when {.val {plot_by}} column contains less than 2 groups.") + if (length(x = unique(x = stats_dataframe[[group.by]])) < 2) { + cli_abort(message = "Cannot calculate statistics when {.val {group.by}} column contains less than 2 groups.") } - groups <- unique(x = stats_dataframe[[plot_by]]) + groups <- unique(x = stats_dataframe[[group.by]]) comparisons <- combn(groups, 2) comparisons <- data.frame(comparisons, stringsAsFactors = FALSE) @@ -1695,7 +1826,7 @@ Seq_QC_Plot_Antisense <- function( #' Plot a combined plot of the basic QC metrics from sequencing output. #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -1723,7 +1854,8 @@ Seq_QC_Plot_Antisense <- function( Seq_QC_Plot_Basic_Combined <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -1731,6 +1863,15 @@ Seq_QC_Plot_Basic_Combined <- function( significance = FALSE, ... ) { + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Basic_Combined(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + # Create rotated axis value if (isTRUE(x = x_lab_rotate)) { axis_angle <- 45 @@ -1739,36 +1880,36 @@ Seq_QC_Plot_Basic_Combined <- function( } # Create Plots & modify for plotting together - p1 <- Seq_QC_Plot_Number_Cells(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p1 <- Seq_QC_Plot_Number_Cells(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p1 <- p1 + labs(title = str_wrap(p1$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p2 <- Seq_QC_Plot_Reads_per_Cell(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p2 <- Seq_QC_Plot_Reads_per_Cell(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p2 <- p2 + labs(title = str_wrap(p2$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p3 <- Seq_QC_Plot_Genes(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p3 <- Seq_QC_Plot_Genes(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p3 <- p3 + labs(title = str_wrap(p3$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p4 <- Seq_QC_Plot_UMIs(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p4 <- Seq_QC_Plot_UMIs(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p4 <- p4 + labs(title = str_wrap(p4$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p5 <- Seq_QC_Plot_Total_Genes(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p5 <- Seq_QC_Plot_Total_Genes(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p5 <- p5 + labs(title = str_wrap(p5$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p6 <- Seq_QC_Plot_Saturation(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p6 <- Seq_QC_Plot_Saturation(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p6 <- p6 + labs(title = str_wrap(p6$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p7 <- Seq_QC_Plot_Reads_in_Cells(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p7 <- Seq_QC_Plot_Reads_in_Cells(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p7 <- p7 + labs(title = str_wrap(p7$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p8 <- Seq_QC_Plot_Transcriptome(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p8 <- Seq_QC_Plot_Transcriptome(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p8 <- p8 + labs(title = str_wrap(p8$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) @@ -1787,7 +1928,7 @@ Seq_QC_Plot_Basic_Combined <- function( #' Plot a combined plot of the Alignment QC metrics from sequencing output. #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). -#' @param plot_by Grouping factor for the plot. Default is to plot as single group with single point per sample. +#' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. #' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. @@ -1815,7 +1956,8 @@ Seq_QC_Plot_Basic_Combined <- function( Seq_QC_Plot_Alignment_Combined <- function( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -1823,6 +1965,15 @@ Seq_QC_Plot_Alignment_Combined <- function( significance = FALSE, ... ) { + # check deprecation + if (is_present(plot_by)) { + deprecate_warn(when = "3.5.0", + what = "Seq_QC_Plot_Alignment_Combined(plot_by)", + details = c("i" = "The {.code plot_by} parameter is soft-deprecated. Please update code to use `group.by` instead.") + ) + group.by <- plot_by + } + # Create rotated axis value if (isTRUE(x = x_lab_rotate)) { axis_angle <- 45 @@ -1831,28 +1982,28 @@ Seq_QC_Plot_Alignment_Combined <- function( } # Create Plots & modify for plotting together - p1 <- Seq_QC_Plot_Genome(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size, ...) + p1 <- Seq_QC_Plot_Genome(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size, ...) p1 <- p1 + labs(title = str_wrap(p1$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p2 <- Seq_QC_Plot_Intergenic(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p2 <- Seq_QC_Plot_Intergenic(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p2 <- p2 + labs(title = str_wrap(p2$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p3 <- Seq_QC_Plot_Transcriptome(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p3 <- Seq_QC_Plot_Transcriptome(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p3 <- p3 + labs(title = str_wrap(p3$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p4 <- Seq_QC_Plot_Exonic(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p4 <- Seq_QC_Plot_Exonic(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p4 <- p4 + labs(title = str_wrap(p4$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p5 <- Seq_QC_Plot_Intronic(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p5 <- Seq_QC_Plot_Intronic(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p5 <- p5 + labs(title = str_wrap(p5$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) - p6 <- Seq_QC_Plot_Antisense(metrics_dataframe = metrics_dataframe, plot_by = plot_by, colors_use = colors_use, significance = significance, dot_size = dot_size,) + p6 <- Seq_QC_Plot_Antisense(metrics_dataframe = metrics_dataframe, group.by = group.by, colors_use = colors_use, significance = significance, dot_size = dot_size,) p6 <- p6 + labs(title = str_wrap(p6$labels$title, 18)) + theme_ggprism_mod(base_size = 10, axis_text_angle = axis_angle) From 3a62f81a6815aaf91f1b2990687c268f95feff22 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:31:51 -0500 Subject: [PATCH 046/105] Update changelog --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 4d6c1f8ce..681b2c311 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,7 @@ ## Changed +- **BREAKING CHANGE** The `plot_by` parameter has been soft-deprecated in `Seq_QC_Plot_*` family of functions. Please use `group.by` instead. Using `plot_by` will warn user but still work until scCustomize v3.5.0. - Add checks for appropriate `...` usage. ## Fixes From 221f796a07d5f3797d6de91e550f440b044f5871 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:32:19 -0500 Subject: [PATCH 047/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8917ce518..97d1b473c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.0005 -Date: 2026-01-23 +Version: 3.2.4.0006 +Date: 2026-02-26 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From f2050f0cc0f3dc47820d02d0049ababbc4ab2b1a Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:32:46 -0500 Subject: [PATCH 048/105] Update docs --- man/Add_Cell_QC_Metrics.Rd | 4 ++++ man/Add_MALAT1_Threshold.Rd | 4 ++++ man/Seq_QC_Plot_Alignment_Combined.Rd | 5 +++-- man/Seq_QC_Plot_Antisense.Rd | 5 +++-- man/Seq_QC_Plot_Basic_Combined.Rd | 5 +++-- man/Seq_QC_Plot_Exonic.Rd | 5 +++-- man/Seq_QC_Plot_Genes.Rd | 5 +++-- man/Seq_QC_Plot_Genome.Rd | 5 +++-- man/Seq_QC_Plot_Intergenic.Rd | 5 +++-- man/Seq_QC_Plot_Intronic.Rd | 5 +++-- man/Seq_QC_Plot_Number_Cells.Rd | 5 +++-- man/Seq_QC_Plot_Reads_in_Cells.Rd | 5 +++-- man/Seq_QC_Plot_Reads_per_Cell.Rd | 7 +++++-- man/Seq_QC_Plot_Saturation.Rd | 5 +++-- man/Seq_QC_Plot_Total_Genes.Rd | 5 +++-- man/Seq_QC_Plot_Transcriptome.Rd | 5 +++-- man/Seq_QC_Plot_UMIs.Rd | 5 +++-- man/exAM_Scoring.Rd | 4 ++++ 18 files changed, 59 insertions(+), 30 deletions(-) diff --git a/man/Add_Cell_QC_Metrics.Rd b/man/Add_Cell_QC_Metrics.Rd index a05a37e52..28f905a93 100644 --- a/man/Add_Cell_QC_Metrics.Rd +++ b/man/Add_Cell_QC_Metrics.Rd @@ -56,6 +56,7 @@ Add_Cell_QC_Metrics(object, ...) add_hemo = TRUE, add_lncRNA = TRUE, add_cell_cycle = TRUE, + assay_suffix = FALSE, mito_name = "percent_mito", ribo_name = "percent_ribo", mito_ribo_name = "percent_mito_ribo", @@ -179,6 +180,9 @@ function will abort if column with name provided to \code{meta_col_name} is pres \item{add_cell_cycle}{logical, whether to addcell cycle scores and phase based on \code{\link[Seurat]{CellCycleScoring}}. Only applicable if \code{species = "human"}. (Default is TRUE).} +\item{assay_suffix}{logical, whether to add assay suffix to the QC column name added to meta.data. +Default is FALSE.} + \item{ieg_module_name}{name to use for new meta data column for module score of IEGs. Default is "ieg_score".} } \value{ diff --git a/man/Add_MALAT1_Threshold.Rd b/man/Add_MALAT1_Threshold.Rd index 169d3468f..7f7293e11 100644 --- a/man/Add_MALAT1_Threshold.Rd +++ b/man/Add_MALAT1_Threshold.Rd @@ -12,6 +12,7 @@ Add_MALAT1_Threshold(object, ...) species, sample_col = NULL, malat1_threshold_name = NULL, + assay_suffix = FALSE, ensembl_ids = FALSE, assay = NULL, overwrite = FALSE, @@ -45,6 +46,9 @@ Add_MALAT1_Threshold(object, ...) \item{malat1_threshold_name}{name to use for the new meta.data column containing percent IEG gene counts. Default is set dependent on species gene symbol.} +\item{assay_suffix}{logical, whether to add assay suffix to the QC column name added to meta.data. +Default is FALSE.} + \item{ensembl_ids}{logical, whether feature names in the object are gene names or ensembl IDs (default is FALSE; set TRUE if feature names are ensembl IDs).} diff --git a/man/Seq_QC_Plot_Alignment_Combined.Rd b/man/Seq_QC_Plot_Alignment_Combined.Rd index f4989dc18..6b804b297 100644 --- a/man/Seq_QC_Plot_Alignment_Combined.Rd +++ b/man/Seq_QC_Plot_Alignment_Combined.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Alignment_Combined( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -18,7 +19,7 @@ Seq_QC_Plot_Alignment_Combined( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Antisense.Rd b/man/Seq_QC_Plot_Antisense.Rd index 493df5b16..ab02d3fe8 100644 --- a/man/Seq_QC_Plot_Antisense.Rd +++ b/man/Seq_QC_Plot_Antisense.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Antisense( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Antisense( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Basic_Combined.Rd b/man/Seq_QC_Plot_Basic_Combined.Rd index 6e3968aed..51e54dfac 100644 --- a/man/Seq_QC_Plot_Basic_Combined.Rd +++ b/man/Seq_QC_Plot_Basic_Combined.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Basic_Combined( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -18,7 +19,7 @@ Seq_QC_Plot_Basic_Combined( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Exonic.Rd b/man/Seq_QC_Plot_Exonic.Rd index c03a0ce04..4b22d111f 100644 --- a/man/Seq_QC_Plot_Exonic.Rd +++ b/man/Seq_QC_Plot_Exonic.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Exonic( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Exonic( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Genes.Rd b/man/Seq_QC_Plot_Genes.Rd index b90312610..904edcf66 100644 --- a/man/Seq_QC_Plot_Genes.Rd +++ b/man/Seq_QC_Plot_Genes.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Genes( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Genes( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Genome.Rd b/man/Seq_QC_Plot_Genome.Rd index 355f97b81..87a55f93c 100644 --- a/man/Seq_QC_Plot_Genome.Rd +++ b/man/Seq_QC_Plot_Genome.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Genome( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Genome( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Intergenic.Rd b/man/Seq_QC_Plot_Intergenic.Rd index 147c76daa..ff7847a65 100644 --- a/man/Seq_QC_Plot_Intergenic.Rd +++ b/man/Seq_QC_Plot_Intergenic.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Intergenic( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Intergenic( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Intronic.Rd b/man/Seq_QC_Plot_Intronic.Rd index 193a8003f..161962252 100644 --- a/man/Seq_QC_Plot_Intronic.Rd +++ b/man/Seq_QC_Plot_Intronic.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Intronic( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Intronic( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Number_Cells.Rd b/man/Seq_QC_Plot_Number_Cells.Rd index 35ea5bf88..f927a2991 100644 --- a/man/Seq_QC_Plot_Number_Cells.Rd +++ b/man/Seq_QC_Plot_Number_Cells.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Number_Cells( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Number_Cells( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Reads_in_Cells.Rd b/man/Seq_QC_Plot_Reads_in_Cells.Rd index 7be4f5002..fb28f4057 100644 --- a/man/Seq_QC_Plot_Reads_in_Cells.Rd +++ b/man/Seq_QC_Plot_Reads_in_Cells.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Reads_in_Cells( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Reads_in_Cells( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Reads_per_Cell.Rd b/man/Seq_QC_Plot_Reads_per_Cell.Rd index 61f47787c..5c3bce88d 100644 --- a/man/Seq_QC_Plot_Reads_per_Cell.Rd +++ b/man/Seq_QC_Plot_Reads_per_Cell.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Reads_per_Cell( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,9 @@ Seq_QC_Plot_Reads_per_Cell( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} + +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Saturation.Rd b/man/Seq_QC_Plot_Saturation.Rd index 43427e9af..18fcc4aa4 100644 --- a/man/Seq_QC_Plot_Saturation.Rd +++ b/man/Seq_QC_Plot_Saturation.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Saturation( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Saturation( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Total_Genes.Rd b/man/Seq_QC_Plot_Total_Genes.Rd index 90038a8c3..b8397c160 100644 --- a/man/Seq_QC_Plot_Total_Genes.Rd +++ b/man/Seq_QC_Plot_Total_Genes.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Total_Genes( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Total_Genes( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Transcriptome.Rd b/man/Seq_QC_Plot_Transcriptome.Rd index 0fe36c1a6..7b955fdfd 100644 --- a/man/Seq_QC_Plot_Transcriptome.Rd +++ b/man/Seq_QC_Plot_Transcriptome.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_Transcriptome( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_Transcriptome( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_UMIs.Rd b/man/Seq_QC_Plot_UMIs.Rd index 5ee01a979..a8714e7b3 100644 --- a/man/Seq_QC_Plot_UMIs.Rd +++ b/man/Seq_QC_Plot_UMIs.Rd @@ -6,7 +6,8 @@ \usage{ Seq_QC_Plot_UMIs( metrics_dataframe, - plot_by = "sample_id", + group.by = "sample_id", + plot_by = deprecated(), colors_use = NULL, dot_size = 1, x_lab_rotate = FALSE, @@ -17,7 +18,7 @@ Seq_QC_Plot_UMIs( \arguments{ \item{metrics_dataframe}{data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}).} -\item{plot_by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/exAM_Scoring.Rd b/man/exAM_Scoring.Rd index 50c9dac14..689928d35 100644 --- a/man/exAM_Scoring.Rd +++ b/man/exAM_Scoring.Rd @@ -8,6 +8,7 @@ exAM_Scoring( seurat_object, species, exam_module_name = NULL, + assay_suffix = FALSE, method = "Seurat", ensembl_ids = FALSE, assay = NULL, @@ -23,6 +24,9 @@ exAM_Scoring( \item{exam_module_name}{name to use for the new meta.data column containing module scores.} +\item{assay_suffix}{logical, whether to add assay suffix to the QC column name added to meta.data. +Default is FALSE.} + \item{method}{method to use for module scoring, currently only "Seurat" is supported but more to be added. .} \item{ensembl_ids}{logical, whether feature names in the object are gene names or From 4eb7b75a6e2eaefd928d854eaf5c4cbbf6c5b676 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:56:08 -0500 Subject: [PATCH 049/105] make linewidth addition conditional to avoid empty aesthetic warnings in ggplot 4.0.0+ --- R/Plotting_QC_Seurat.R | 61 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/R/Plotting_QC_Seurat.R b/R/Plotting_QC_Seurat.R index 01c75ee5f..e589f19ef 100644 --- a/R/Plotting_QC_Seurat.R +++ b/R/Plotting_QC_Seurat.R @@ -77,12 +77,20 @@ QC_Plots_Genes <- function( nFeature <- paste0("nFeature_", assay) plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = nFeature, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") + # cutoff linewidth adjustment + if (!is.null(x = cutoff_line_width)) { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + } else { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + } + # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -172,12 +180,20 @@ QC_Plots_UMIs <- function( nCount <- paste0("nCount_", assay) plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = nCount, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") + # cutoff linewidth adjustment + if (!is.null(x = cutoff_line_width)) { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + } else { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + } + # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -263,12 +279,20 @@ QC_Plots_Mito <- function( Is_Seurat(seurat_object = seurat_object) plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = mito_name, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") + # cutoff linewidth adjustment + if (!is.null(x = cutoff_line_width)) { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + } else { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + } + # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -358,12 +382,20 @@ QC_Plots_Feature <- function( plot_title <- paste0(feature, " per Cell/Nucleus") } plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = feature, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") + # cutoff linewidth adjustment + if (!is.null(x = cutoff_line_width)) { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + } else { + plot <- plot + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + } + # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -660,8 +692,16 @@ QC_Histogram <- function( plot <- ggplot(data = data_to_plot, aes(x = .data[[all_found_features[x]]])) + geom_histogram(color = "black", fill = colors_use, bins = bins) + theme_cowplot() + - geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + ggtitle(plot_titles[x]) + + # cutoff linewidth adjustment + if (!is.null(x = cutoff_line_width)) { + plot <- plot + + geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + } else { + plot <- plot + + geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + } }) # wrap and return plots @@ -699,8 +739,17 @@ QC_Histogram <- function( plot <- ggplot(data = sub_data, aes(x = .data[[all_found_features]])) + geom_histogram(color = "black", fill = colors_use[x], bins = bins) + theme_cowplot() + - geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + ggtitle(meta_sample_list[x]) + + # cutoff linewidth adjustment + if (!is.null(x = cutoff_line_width)) { + plot <- plot + + geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + } else { + plot <- plot + + geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + } + }) # wrap and return plots From 0acbd6fd9d8d28975d4bf4028e25fe55dd4ff831 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:58:00 -0500 Subject: [PATCH 050/105] Update changelog --- NEWS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 681b2c311..b32a88703 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,7 +10,8 @@ - Add checks for appropriate `...` usage. ## Fixes - +- Fixed setting of `linewidth` parameter to be conditional in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. + From e5c76bd8b270fab2fe1acffc39d81a5edc098bd3 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:58:07 -0500 Subject: [PATCH 051/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 97d1b473c..00aefe6ae 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.0006 -Date: 2026-02-26 +Version: 3.2.4.9007 +Date: 2026-03-03 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From 3f1b4024c2849d02368e4b8f7ce09113f680612f Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:08:39 -0500 Subject: [PATCH 052/105] revert conditional and set a default close to ggplot2 default value to avoid issues in complexity --- R/Plotting_QC_Seurat.R | 196 ++++++++++++++++++++++++++++------------- 1 file changed, 133 insertions(+), 63 deletions(-) diff --git a/R/Plotting_QC_Seurat.R b/R/Plotting_QC_Seurat.R index e589f19ef..443a9bbd8 100644 --- a/R/Plotting_QC_Seurat.R +++ b/R/Plotting_QC_Seurat.R @@ -76,21 +76,19 @@ QC_Plots_Genes <- function( nFeature <- paste0("nFeature_", assay) + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = nFeature, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") - # cutoff linewidth adjustment - if (!is.null(x = cutoff_line_width)) { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) - } else { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") - } - # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -179,21 +177,19 @@ QC_Plots_UMIs <- function( nCount <- paste0("nCount_", assay) + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = nCount, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") - # cutoff linewidth adjustment - if (!is.null(x = cutoff_line_width)) { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) - } else { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") - } - # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -278,21 +274,19 @@ QC_Plots_Mito <- function( # Check Seurat Is_Seurat(seurat_object = seurat_object) + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = mito_name, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") - # cutoff linewidth adjustment - if (!is.null(x = cutoff_line_width)) { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) - } else { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") - } - # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -381,21 +375,20 @@ QC_Plots_Feature <- function( if (is.null(x = plot_title)) { plot_title <- paste0(feature, " per Cell/Nucleus") } + + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = feature, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + theme(plot.subtitle = element_text(hjust = 0.5), legend.position = "none") - # cutoff linewidth adjustment - if (!is.null(x = cutoff_line_width)) { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) - } else { - plot <- plot + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") - } - # Rotate x axis label if (isFALSE(x = x_lab_rotate)) { plot <- plot + UnRotate_X() @@ -477,7 +470,27 @@ QC_Plots_Complexity <- function( color_seed = 123, ... ) { - plot <- QC_Plots_Feature(seurat_object = seurat_object, feature = feature, group.by = group.by, x_axis_label = x_axis_label, y_axis_label = y_axis_label, plot_title = plot_title, low_cutoff = low_cutoff, high_cutoff = high_cutoff, pt.size = pt.size, colors_use = colors_use, x_lab_rotate = x_lab_rotate, y_axis_log = y_axis_log, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, cutoff_line_width = cutoff_line_width, ...) + # plot + plot <- QC_Plots_Feature(seurat_object = seurat_object, + feature = feature, + group.by = group.by, + x_axis_label = x_axis_label, + y_axis_label = y_axis_label, + plot_title = plot_title, + low_cutoff = low_cutoff, + high_cutoff = high_cutoff, + pt.size = pt.size, + colors_use = colors_use, + x_lab_rotate = x_lab_rotate, + y_axis_log = y_axis_log, + raster = raster, + ggplot_default_colors = ggplot_default_colors, + color_seed = color_seed, + plot_median = plot_median, + median_size = median_size, + plot_boxplot = plot_boxplot, + cutoff_line_width = cutoff_line_width, + ...) return(plot) } @@ -568,11 +581,57 @@ QC_Plots_Combined_Vln <- function( } # Create Individual Plots - feature_plot <- QC_Plots_Genes(seurat_object = seurat_object, group.by = group.by, low_cutoff = feature_cutoffs[1], high_cutoff = feature_cutoffs[2], pt.size = pt.size, colors_use = colors_use, x_lab_rotate = x_lab_rotate, y_axis_log = y_axis_log, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, cutoff_line_width = cutoff_line_width, ...) - - UMI_plot <- QC_Plots_UMIs(seurat_object = seurat_object, group.by = group.by, low_cutoff = UMI_cutoffs[1], high_cutoff = UMI_cutoffs[2], pt.size = pt.size, colors_use = colors_use, x_lab_rotate = x_lab_rotate, y_axis_log = y_axis_log, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, cutoff_line_width = cutoff_line_width, ...) - - mito_plot <- QC_Plots_Mito(seurat_object = seurat_object, group.by = group.by, mito_name = mito_name, low_cutoff = mito_cutoffs[1], high_cutoff = mito_cutoffs[2], pt.size = pt.size, colors_use = colors_use, x_lab_rotate = x_lab_rotate, y_axis_log = y_axis_log, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, cutoff_line_width = cutoff_line_width, ...) + feature_plot <- QC_Plots_Genes(seurat_object = seurat_object, + group.by = group.by, + low_cutoff = feature_cutoffs[1], + high_cutoff = feature_cutoffs[2], + pt.size = pt.size, + colors_use = colors_use, + x_lab_rotate = x_lab_rotate, + y_axis_log = y_axis_log, + raster = raster, + ggplot_default_colors = ggplot_default_colors, + color_seed = color_seed, + plot_median = plot_median, + median_size = median_size, + plot_boxplot = plot_boxplot, + cutoff_line_width = cutoff_line_width, + ...) + + UMI_plot <- QC_Plots_UMIs(seurat_object = seurat_object, + group.by = group.by, + low_cutoff = UMI_cutoffs[1], + high_cutoff = UMI_cutoffs[2], + pt.size = pt.size, + colors_use = colors_use, + x_lab_rotate = x_lab_rotate, + y_axis_log = y_axis_log, + raster = raster, + ggplot_default_colors = ggplot_default_colors, + color_seed = color_seed, + plot_median = plot_median, + median_size = median_size, + plot_boxplot = plot_boxplot, + cutoff_line_width = cutoff_line_width, + ...) + + mito_plot <- QC_Plots_Mito(seurat_object = seurat_object, + group.by = group.by, + mito_name = mito_name, + low_cutoff = mito_cutoffs[1], + high_cutoff = mito_cutoffs[2], + pt.size = pt.size, + colors_use = colors_use, + x_lab_rotate = x_lab_rotate, + y_axis_log = y_axis_log, + raster = raster, + ggplot_default_colors = ggplot_default_colors, + color_seed = color_seed, + plot_median = plot_median, + median_size = median_size, + plot_boxplot = plot_boxplot, + cutoff_line_width = cutoff_line_width, + ...) # wrap plots plots <- wrap_plots(feature_plot, UMI_plot, mito_plot, ncol = 3) @@ -685,6 +744,12 @@ QC_Histogram <- function( plot_titles <- all_found_features } + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + # Plot if (is.null(x = split.by)) { plot_list <- lapply(1:length(x = all_found_features), function(x) { @@ -692,16 +757,8 @@ QC_Histogram <- function( plot <- ggplot(data = data_to_plot, aes(x = .data[[all_found_features[x]]])) + geom_histogram(color = "black", fill = colors_use, bins = bins) + theme_cowplot() + + geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + ggtitle(plot_titles[x]) - - # cutoff linewidth adjustment - if (!is.null(x = cutoff_line_width)) { - plot <- plot + - geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) - } else { - plot <- plot + - geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") - } }) # wrap and return plots @@ -739,17 +796,8 @@ QC_Histogram <- function( plot <- ggplot(data = sub_data, aes(x = .data[[all_found_features]])) + geom_histogram(color = "black", fill = colors_use[x], bins = bins) + theme_cowplot() + + geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") + ggtitle(meta_sample_list[x]) - - # cutoff linewidth adjustment - if (!is.null(x = cutoff_line_width)) { - plot <- plot + - geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) - } else { - plot <- plot + - geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red") - } - }) # wrap and return plots @@ -893,6 +941,12 @@ QC_Plot_UMIvsGene <- function( } } + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + if (isFALSE(x = ident_legend) && isFALSE(x = combination)) { cli_warn(message = "{.code ident_legend} parameter ignored as {.code combination = FALSE}") } @@ -1130,12 +1184,20 @@ QC_Plot_GenevsFeature <- function( } } + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + # Plot - FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = nFeature, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + + plot <- FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = nFeature, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + geom_hline(yintercept = c(low_cutoff_gene, high_cutoff_gene), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + geom_vline(xintercept = c(low_cutoff_feature, high_cutoff_feature), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + + return(plot) } @@ -1242,10 +1304,18 @@ QC_Plot_UMIvsFeature <- function( } } + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.635 is as close to default as I can approximate + if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_line_width <- 0.635 + } + # Plot - FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = nCount, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + + plot <- FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = nCount, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + geom_hline(yintercept = c(low_cutoff_UMI, high_cutoff_UMI), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + geom_vline(xintercept = c(low_cutoff_feature, high_cutoff_feature), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + xlab(x_axis_label) + ylab(y_axis_label) + + return(plot) } From b27e7263840de38c247023c3409a9c30e45f40c2 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:09:25 -0500 Subject: [PATCH 053/105] Update changelog --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index b32a88703..d1e0795cb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,7 +10,7 @@ - Add checks for appropriate `...` usage. ## Fixes -- Fixed setting of `linewidth` parameter to be conditional in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. +- Fixed setting default setting of `linewidth` parameter in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. From 1c45a55fd4592a8082e3b2dde26c3db43e25b199 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:09:38 -0500 Subject: [PATCH 054/105] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 00aefe6ae..3b7f3d5b8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9007 +Version: 3.2.4.9008 Date: 2026-03-03 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), From c2306cbe499cd50b62a9b35d2b2ed18f88b6ee59 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:49:32 -0500 Subject: [PATCH 055/105] fix sample_col parameter to avoid deprecation warning --- R/LIGER_Utilities.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/LIGER_Utilities.R b/R/LIGER_Utilities.R index 408ee8479..a922df152 100644 --- a/R/LIGER_Utilities.R +++ b/R/LIGER_Utilities.R @@ -581,7 +581,7 @@ Dataset_Size_LIGER <- function( found_meta <- Meta_Present(object = liger_object, meta_col_names = meta_data_column, print_msg = FALSE)[[1]] - sample_meta <- Extract_Sample_Meta(object = liger_object, sample_name = "dataset", variables_include = found_meta) + sample_meta <- Extract_Sample_Meta(object = liger_object, sample_col = "dataset", variables_include = found_meta) # join data dataset_cells_df <- right_join(x = dataset_cells_df, y = sample_meta, by = join_by("dataset")) From 963d8ebd9ab19d383bf210e078ba925955155d20 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:53:17 -0500 Subject: [PATCH 056/105] Fix manual entries for Extract_Sample_Meta --- R/Utilities_Objects.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/Utilities_Objects.R b/R/Utilities_Objects.R index c8cac1c03..986f0a930 100644 --- a/R/Utilities_Objects.R +++ b/R/Utilities_Objects.R @@ -497,7 +497,7 @@ Add_Sample_Meta <- function( #' @param include_all logical, whether or not to include all object meta data columns in output data.frame. #' Default is FALSE. #' -#' @return Returns a data.frame with one row per `sample_name`. +#' @return Returns a data.frame with one row per `sample_col`. #' #' @importFrom dplyr any_of grouped_df select slice #' @importFrom magrittr "%>%" @@ -510,14 +510,14 @@ Add_Sample_Meta <- function( #' library(Seurat) #' pbmc_small[["batch"]] <- sample(c("batch1", "batch2"), size = ncol(pbmc_small), replace = TRUE) #' -#' sample_meta <- Extract_Sample_Meta(object = pbmc_small, sample_name = "orig.ident") +#' sample_meta <- Extract_Sample_Meta(object = pbmc_small, sample_col = "orig.ident") #' #' # Only return specific columns from meta data (orig.ident and batch) -#' sample_meta2 <- Extract_Sample_Meta(object = pbmc_small, sample_name = "orig.ident", +#' sample_meta2 <- Extract_Sample_Meta(object = pbmc_small, sample_col = "orig.ident", #' variables_include = "batch") #' #' # Return all columns from meta data -#' sample_meta3 <- Extract_Sample_Meta(object = pbmc_small, sample_name = "orig.ident", +#' sample_meta3 <- Extract_Sample_Meta(object = pbmc_small, sample_col = "orig.ident", #' include_all = TRUE) #' From 2208ba50122b71887120cc4238603de56466c54a Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:53:24 -0500 Subject: [PATCH 057/105] Update changelog --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index d1e0795cb..f4fc398ac 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,7 @@ ## Fixes - Fixed setting default setting of `linewidth` parameter in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. +- Fixed warning in `Dataset_Size_LIGER` due to deprecation in `Extract_Sample_Meta`. From 341153b19ac99b9ade73619f8af69117f11d6cf7 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:54:56 -0500 Subject: [PATCH 058/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3b7f3d5b8..5b784855d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9008 -Date: 2026-03-03 +Version: 3.2.4.9009 +Date: 2026-03-04 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From 7cf0b2a1c9a6af1c769ef38bf57792478162bbca Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:55:15 -0500 Subject: [PATCH 059/105] Update docs --- man/Extract_Sample_Meta.Rd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/man/Extract_Sample_Meta.Rd b/man/Extract_Sample_Meta.Rd index d49dc3b3f..e45324f4e 100644 --- a/man/Extract_Sample_Meta.Rd +++ b/man/Extract_Sample_Meta.Rd @@ -38,7 +38,7 @@ function can be joined with output of \code{\link[scCustomize]{Median_Stats}}. Default is FALSE.} } \value{ -Returns a data.frame with one row per \code{sample_name}. +Returns a data.frame with one row per \code{sample_col}. } \description{ Returns a by identity meta.data data.frame with one row per sample. Useful for downstream @@ -48,14 +48,14 @@ quick view of sample breakdown, meta data table creation, and/or use in pseudobu library(Seurat) pbmc_small[["batch"]] <- sample(c("batch1", "batch2"), size = ncol(pbmc_small), replace = TRUE) -sample_meta <- Extract_Sample_Meta(object = pbmc_small, sample_name = "orig.ident") +sample_meta <- Extract_Sample_Meta(object = pbmc_small, sample_col = "orig.ident") # Only return specific columns from meta data (orig.ident and batch) -sample_meta2 <- Extract_Sample_Meta(object = pbmc_small, sample_name = "orig.ident", +sample_meta2 <- Extract_Sample_Meta(object = pbmc_small, sample_col = "orig.ident", variables_include = "batch") # Return all columns from meta data -sample_meta3 <- Extract_Sample_Meta(object = pbmc_small, sample_name = "orig.ident", +sample_meta3 <- Extract_Sample_Meta(object = pbmc_small, sample_col = "orig.ident", include_all = TRUE) } From 8c1eaedd5e0495aadaa4c365a60ef4ede34d83c5 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:27:36 -0500 Subject: [PATCH 060/105] deprecate old line_width to linewidth --- R/Plotting_QC_Seurat.R | 278 +++++++++++++++++++++++++++++------------ R/Plotting_Seurat.R | 23 +++- 2 files changed, 219 insertions(+), 82 deletions(-) diff --git a/R/Plotting_QC_Seurat.R b/R/Plotting_QC_Seurat.R index 443a9bbd8..7d7f4fc86 100644 --- a/R/Plotting_QC_Seurat.R +++ b/R/Plotting_QC_Seurat.R @@ -14,7 +14,9 @@ #' @param x_axis_label Label for x axis. #' @param low_cutoff Plot line a potential low threshold for filtering. #' @param high_cutoff Plot line a potential high threshold for filtering. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param pt.size Point size for plotting. #' @param plot_median logical, whether to plot median for each ident on the plot (Default is FALSE). #' @param median_size Shape size for the median is plotted. @@ -54,7 +56,8 @@ QC_Plots_Genes <- function( y_axis_label = "Features", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, plot_boxplot = FALSE, @@ -68,6 +71,15 @@ QC_Plots_Genes <- function( color_seed = 123, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plots_Genes(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -77,13 +89,13 @@ QC_Plots_Genes <- function( nFeature <- paste0("nFeature_", assay) # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = nFeature, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + @@ -115,7 +127,9 @@ QC_Plots_Genes <- function( #' @param x_axis_label Label for x axis. #' @param low_cutoff Plot line a potential low threshold for filtering. #' @param high_cutoff Plot line a potential high threshold for filtering. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param pt.size Point size for plotting. #' @param plot_median logical, whether to plot median for each ident on the plot (Default is FALSE). #' @param median_size Shape size for the median is plotted. @@ -155,7 +169,8 @@ QC_Plots_UMIs <- function( y_axis_label = "UMIs", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -169,6 +184,15 @@ QC_Plots_UMIs <- function( color_seed = 123, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plots_UMIs(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -178,13 +202,13 @@ QC_Plots_UMIs <- function( nCount <- paste0("nCount_", assay) # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = nCount, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + @@ -218,7 +242,9 @@ QC_Plots_UMIs <- function( #' @param x_axis_label Label for x axis. #' @param low_cutoff Plot line a potential low threshold for filtering. #' @param high_cutoff Plot line a potential high threshold for filtering. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param pt.size Point size for plotting. #' @param plot_median logical, whether to plot median for each ident on the plot (Default is FALSE). #' @param median_size Shape size for the median is plotted. @@ -258,7 +284,8 @@ QC_Plots_Mito <- function( y_axis_label = "% Mitochondrial Gene Counts", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -271,17 +298,26 @@ QC_Plots_Mito <- function( color_seed = 123, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plots_Mito(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = mito_name, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + @@ -314,7 +350,9 @@ QC_Plots_Mito <- function( #' @param plot_title Plot Title. #' @param low_cutoff Plot line a potential low threshold for filtering. #' @param high_cutoff Plot line a potential high threshold for filtering. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param pt.size Point size for plotting. #' @param plot_median logical, whether to plot median for each ident on the plot (Default is FALSE). #' @param median_size Shape size for the median is plotted. @@ -356,7 +394,8 @@ QC_Plots_Feature <- function( plot_title = NULL, low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -369,6 +408,15 @@ QC_Plots_Feature <- function( color_seed = 123, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plots_Feature(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -377,13 +425,13 @@ QC_Plots_Feature <- function( } # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } plot <- VlnPlot_scCustom(seurat_object = seurat_object, features = feature, group.by = group.by, colors_use = colors_use, pt.size = pt.size, raster = raster, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, plot_median = plot_median, plot_boxplot = plot_boxplot, median_size = median_size, ...) + - geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle(plot_title) + @@ -416,7 +464,9 @@ QC_Plots_Feature <- function( #' @param plot_title Plot Title. #' @param low_cutoff Plot line a potential low threshold for filtering. #' @param high_cutoff Plot line a potential high threshold for filtering. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param pt.size Point size for plotting #' @param plot_median logical, whether to plot median for each ident on the plot (Default is FALSE). #' @param median_size Shape size for the median is plotted. @@ -457,7 +507,8 @@ QC_Plots_Complexity <- function( plot_title = "Cell Complexity", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, plot_boxplot = FALSE, @@ -470,6 +521,15 @@ QC_Plots_Complexity <- function( color_seed = 123, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plots_Complexity(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # plot plot <- QC_Plots_Feature(seurat_object = seurat_object, feature = feature, @@ -489,7 +549,7 @@ QC_Plots_Complexity <- function( plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, - cutoff_line_width = cutoff_line_width, + cutoff_linewidth = cutoff_linewidth, ...) return(plot) @@ -508,7 +568,9 @@ QC_Plots_Complexity <- function( #' @param mito_cutoffs Numeric vector of length 1 or 2 to plot lines for potential low/high threshold for filtering. #' @param mito_name The column name containing percent mitochondrial counts information. Default value is #' "percent_mito" which is default value created when using `Add_Mito_Ribo()`. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param pt.size Point size for plotting #' @param plot_median logical, whether to plot median for each ident on the plot (Default is FALSE). #' @param median_size Shape size for the median is plotted. @@ -547,7 +609,8 @@ QC_Plots_Combined_Vln <- function( UMI_cutoffs = NULL, mito_cutoffs = NULL, mito_name = "percent_mito", - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -560,6 +623,15 @@ QC_Plots_Combined_Vln <- function( color_seed = 123, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plots_Combined_Vln(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -595,7 +667,7 @@ QC_Plots_Combined_Vln <- function( plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, - cutoff_line_width = cutoff_line_width, + cutoff_linewidth = cutoff_linewidth, ...) UMI_plot <- QC_Plots_UMIs(seurat_object = seurat_object, @@ -612,7 +684,7 @@ QC_Plots_Combined_Vln <- function( plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, - cutoff_line_width = cutoff_line_width, + cutoff_linewidth = cutoff_linewidth, ...) mito_plot <- QC_Plots_Mito(seurat_object = seurat_object, @@ -630,7 +702,7 @@ QC_Plots_Combined_Vln <- function( plot_median = plot_median, median_size = median_size, plot_boxplot = plot_boxplot, - cutoff_line_width = cutoff_line_width, + cutoff_linewidth = cutoff_linewidth, ...) # wrap plots @@ -653,7 +725,9 @@ QC_Plots_Combined_Vln <- function( #' @param features Feature from meta.data, assay features, or feature name shortcut to plot. #' @param low_cutoff Plot line a potential low threshold for filtering. #' @param high_cutoff Plot line a potential high threshold for filtering. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param split.by Feature to split plots by (i.e. "orig.ident"). #' @param bins number of bins to plot default is 250. #' @param colors_use color to fill histogram bars, default is "dodgerblue". @@ -684,18 +758,28 @@ QC_Plots_Combined_Vln <- function( QC_Histogram <- function( seurat_object, - features, - low_cutoff = NULL, - high_cutoff = NULL, - cutoff_line_width = NULL, - split.by = NULL, - bins = 250, - colors_use = "dodgerblue", - num_columns = NULL, - plot_title = NULL, - assay = NULL, - print_defaults = FALSE + features, + low_cutoff = NULL, + high_cutoff = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, + split.by = NULL, + bins = 250, + colors_use = "dodgerblue", + num_columns = NULL, + plot_title = NULL, + assay = NULL, + print_defaults = FALSE ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Histogram(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -745,9 +829,9 @@ QC_Histogram <- function( } # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } # Plot @@ -757,7 +841,7 @@ QC_Histogram <- function( plot <- ggplot(data = data_to_plot, aes(x = .data[[all_found_features[x]]])) + geom_histogram(color = "black", fill = colors_use, bins = bins) + theme_cowplot() + - geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + + geom_vline(xintercept = c(low_cutoff, high_cutoff), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + ggtitle(plot_titles[x]) }) @@ -823,7 +907,9 @@ QC_Histogram <- function( #' @param high_cutoff_gene Plot line a potential high threshold for filtering genes per cell. #' @param low_cutoff_UMI Plot line a potential low threshold for filtering UMIs per cell. #' @param high_cutoff_UMI Plot line a potential high threshold for filtering UMIs per cell. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param colors_use vector of colors to use for plotting by identity. #' @param meta_gradient_name Name of continuous meta data variable to color points in plot by. #' (MUST be continuous variable i.e. "percent_mito"). @@ -881,7 +967,8 @@ QC_Plot_UMIvsGene <- function( high_cutoff_gene = Inf, low_cutoff_UMI = -Inf, high_cutoff_UMI = Inf, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, colors_use = NULL, meta_gradient_name = NULL, meta_gradient_color = viridis_plasma_dark_high, @@ -900,6 +987,15 @@ QC_Plot_UMIvsGene <- function( shuffle_seed = 1, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plot_UMIvsGene(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -942,9 +1038,9 @@ QC_Plot_UMIvsGene <- function( } # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } if (isFALSE(x = ident_legend) && isFALSE(x = combination)) { @@ -1009,8 +1105,8 @@ QC_Plot_UMIvsGene <- function( scale_color_gradientn(colors = meta_gradient_color, limits = c(meta_gradient_low_cutoff, NA), na.value = meta_gradient_na_color) + theme_cowplot() + theme(plot.title = element_text(hjust = 0.5)) + - geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle("Genes vs. UMIs per Cell/Nucleus", subtitle = c(paste0("Correlation of full dataset is: ", plot_cor_full, ".", "\nCorrelation of filtered dataset would be: ", plot_cor_filtered, ". ", "\nThe low cutoff for plotting ", meta_gradient_name, " is: ", meta_cutoff_reported))) @@ -1021,8 +1117,8 @@ QC_Plot_UMIvsGene <- function( scale_color_gradientn(colors = meta_gradient_color, limits = c(meta_gradient_low_cutoff, NA), na.value = meta_gradient_na_color) + theme_cowplot() + theme(plot.title = element_text(hjust = 0.5)) + - geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle("Genes vs. UMIs per Cell/Nucleus", subtitle = c(paste0("Correlation of full dataset is: ", plot_cor_full, ".", "\nCorrelation of filtered dataset would be: ", plot_cor_filtered, ". ", "\nThe low cutoff for plotting ", meta_gradient_name, " is: ", meta_cutoff_reported))) @@ -1031,8 +1127,8 @@ QC_Plot_UMIvsGene <- function( # Plot by identity if (is.null(x = meta_gradient_name) && isFALSE(x = combination)) { p1 <- FeatureScatter(object = seurat_object, feature1 = nCount, feature2 = nFeature, cells = cells, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + - geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle("Genes vs. UMIs per Cell/Nucleus", subtitle = c(paste0("Correlation of full dataset is: ", plot_cor_full, ".", "\nCorrelation of filtered dataset would be: ", plot_cor_filtered, "."))) @@ -1042,8 +1138,8 @@ QC_Plot_UMIvsGene <- function( if (isTRUE(x = combination)) { # Plot by identity p1 <- FeatureScatter(object = seurat_object, feature1 = nCount, feature2 = nFeature, cells = cells, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + - geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) + ggtitle("") @@ -1058,8 +1154,8 @@ QC_Plot_UMIvsGene <- function( scale_color_gradientn(colors = meta_gradient_color, limits = c(meta_gradient_low_cutoff, NA), na.value = meta_gradient_na_color) + theme_cowplot() + theme(plot.title = element_text(hjust = 0.5)) + - geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) } else { @@ -1068,8 +1164,8 @@ QC_Plot_UMIvsGene <- function( scale_color_gradientn(colors = meta_gradient_color, limits = c(meta_gradient_low_cutoff, NA), na.value = meta_gradient_na_color) + theme_cowplot() + theme(plot.title = element_text(hjust = 0.5)) + - geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(if(is.finite(x = low_cutoff_gene)) {low_cutoff_gene}, if(is.finite(x = high_cutoff_gene)) {high_cutoff_gene}), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(if(is.finite(x = low_cutoff_UMI)) {low_cutoff_UMI}, if(is.finite(x = high_cutoff_UMI)) {high_cutoff_UMI}), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) } @@ -1093,7 +1189,9 @@ QC_Plot_UMIvsGene <- function( #' @param high_cutoff_gene Plot line a potential high threshold for filtering genes per cell. #' @param low_cutoff_feature Plot line a potential low threshold for filtering feature1 per cell. #' @param high_cutoff_feature Plot line a potential high threshold for filtering feature1 per cell. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param colors_use vector of colors to use for plotting by identity. #' @param pt.size Adjust point size for plotting. #' @param group.by Name of one or more metadata columns to group (color) cells by (for example, orig.ident). @@ -1134,7 +1232,8 @@ QC_Plot_GenevsFeature <- function( high_cutoff_gene = NULL, low_cutoff_feature = NULL, high_cutoff_feature = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, colors_use = NULL, pt.size = 1, group.by = NULL, @@ -1146,6 +1245,15 @@ QC_Plot_GenevsFeature <- function( shuffle_seed = 1, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plot_GenevsFeature(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -1185,15 +1293,15 @@ QC_Plot_GenevsFeature <- function( } # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } # Plot plot <- FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = nFeature, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + - geom_hline(yintercept = c(low_cutoff_gene, high_cutoff_gene), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(low_cutoff_feature, high_cutoff_feature), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(low_cutoff_gene, high_cutoff_gene), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(low_cutoff_feature, high_cutoff_feature), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) @@ -1213,7 +1321,9 @@ QC_Plot_GenevsFeature <- function( #' @param high_cutoff_UMI Plot line a potential high threshold for filtering UMI per cell. #' @param low_cutoff_feature Plot line a potential low threshold for filtering feature1 per cell. #' @param high_cutoff_feature Plot line a potential high threshold for filtering feature1 per cell. -#' @param cutoff_line_width numerical value for thickness of cutoff lines, default is NULL. +#' @param cutoff_line_width `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. +#' @param cutoff_linewidth numerical value for thickness of cutoff lines, +#' default is NULL, uses ggplot2 defaults. #' @param colors_use vector of colors to use for plotting by identity. #' @param pt.size Adjust point size for plotting. #' @param group.by Name of one or more metadata columns to group (color) cells by (for example, orig.ident). @@ -1254,7 +1364,8 @@ QC_Plot_UMIvsFeature <- function( high_cutoff_UMI = NULL, low_cutoff_feature = NULL, high_cutoff_feature = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, colors_use = NULL, pt.size = 1, group.by = NULL, @@ -1266,6 +1377,15 @@ QC_Plot_UMIvsFeature <- function( shuffle_seed = 1, ... ) { + # check deprecation + if (is_present(cutoff_line_width)) { + deprecate_warn(when = "3.5.0", + what = "QC_Plot_UMIvsFeature(cutoff_line_width)", + details = c("i" = "The {.code cutoff_line_width} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- cutoff_line_width + } + # Check Seurat Is_Seurat(seurat_object = seurat_object) @@ -1305,15 +1425,15 @@ QC_Plot_UMIvsFeature <- function( } # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings - # 0.635 is as close to default as I can approximate - if (is.null(x = cutoff_line_width) && packageVersion(pkg = "ggplot2") >= "4.0.0") { - cutoff_line_width <- 0.635 + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 } # Plot plot <- FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = nCount, pt.size = pt.size, shuffle = TRUE, raster = raster, raster.dpi = raster.dpi, cols = colors_use, group.by = group.by, seed = shuffle_seed, ...) + - geom_hline(yintercept = c(low_cutoff_UMI, high_cutoff_UMI), linetype = "dashed", color = "red", linewidth = cutoff_line_width) + - geom_vline(xintercept = c(low_cutoff_feature, high_cutoff_feature), linetype = "dashed", color = "blue", linewidth = cutoff_line_width) + + geom_hline(yintercept = c(low_cutoff_UMI, high_cutoff_UMI), linetype = "dashed", color = "red", linewidth = cutoff_linewidth) + + geom_vline(xintercept = c(low_cutoff_feature, high_cutoff_feature), linetype = "dashed", color = "blue", linewidth = cutoff_linewidth) + xlab(x_axis_label) + ylab(y_axis_label) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 597a6fcdc..6d1a5c421 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -2666,9 +2666,10 @@ FeatureScatter_scCustom <- function( #' @param ndims The number of dims to plot. Default is NULL and will plot all dims #' @param reduction The reduction to use, default is "pca" #' @param calc_cutoffs logical, whether or not to calculate the cutoffs, default is TRUE. -#' @param plot_cutoffs lgoical, whether to plot the cutoffs as vertical lines on plot, default is TRUE. +#' @param plot_cutoffs logical, whether to plot the cutoffs as vertical lines on plot, default is TRUE. #' @param line_colors colors for the cutoff lines, default is c("dodgerblue", "firebrick"). -#' @param linewidth widith of the cutoff lines, default is 0.5. +#' @param cutoff_linewidth width of the cutoff lines, default is NULL, uses ggplot2 default. +#' @param linewidth `r lifecycle::badge("soft-deprecated")`. See `cutoff_linewidth`. #' #' @references Modified from following: \url{https://hbctraining.github.io/scRNA-seq/lessons/elbow_plot_metric.html}. #' @@ -2691,8 +2692,18 @@ ElbowPlot_scCustom <- function( calc_cutoffs = TRUE, plot_cutoffs = TRUE, line_colors = c("dodgerblue", "firebrick"), - linewidth = 0.5 + cutoff_linewidth = NULL, + linewidth = deprecated() ) { + # check deprecation + if (is_present(linewidth)) { + deprecate_warn(when = "3.5.0", + what = "ElbowPlot_scCustom(linewidth)", + details = c("i" = "The {.code linewidth} parameter is soft-deprecated. Please update code to use `cutoff_linewidth` instead.") + ) + cutoff_linewidth <- linewidth + } + # check seurat Is_Seurat(seurat_object = seurat_object) @@ -2734,6 +2745,12 @@ ElbowPlot_scCustom <- function( cli_abort(message = "The number of values provided to {.code line_colors} must be either 1 or 2.") } + # set default `linewidth` when ggplot2 >= 4.0.0 to avoid empty aesthetic warnings + # 0.6365 is as close to default as I can approximate + if (is.null(x = cutoff_linewidth) && packageVersion(pkg = "ggplot2") >= "4.0.0") { + cutoff_linewidth <- 0.6365 + } + # Create plot plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction) From 2c7c24efb533401420a4182ab4e2f909aee7ab46 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:29:24 -0500 Subject: [PATCH 061/105] Update changelog --- NEWS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index f4fc398ac..46c270b0e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,7 +7,9 @@ ## Changed - **BREAKING CHANGE** The `plot_by` parameter has been soft-deprecated in `Seq_QC_Plot_*` family of functions. Please use `group.by` instead. Using `plot_by` will warn user but still work until scCustomize v3.5.0. -- Add checks for appropriate `...` usage. +- **BREAKING CHANGE** The parameter `cutoff_line_width` has been soft-deprecated in `QC_Plot_*` family of functions. Please use `cutoff_linewidth` instead. Using `cutoff_line_width` will warn user but still work until scCustomize v3.5.0. +- **BREAKING CHANGE** The parameter `linewidth` has been soft-deprecated in `ElbowPlot_scCustom` function. Please use `cutoff_linewidth` instead. Using `linewidth` will warn user but still work until scCustomize v3.5.0. +- Add checks for appropriate `...` usage. ## Fixes - Fixed setting default setting of `linewidth` parameter in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. From 92d5a6d0af37220c2911218071f5a20a0469e1ef Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:29:40 -0500 Subject: [PATCH 062/105] Update docs --- man/ElbowPlot_scCustom.Rd | 9 ++++++--- man/QC_Histogram.Rd | 8 ++++++-- man/QC_Plot_GenevsFeature.Rd | 8 ++++++-- man/QC_Plot_UMIvsFeature.Rd | 8 ++++++-- man/QC_Plot_UMIvsGene.Rd | 8 ++++++-- man/QC_Plots_Combined_Vln.Rd | 8 ++++++-- man/QC_Plots_Complexity.Rd | 8 ++++++-- man/QC_Plots_Feature.Rd | 8 ++++++-- man/QC_Plots_Genes.Rd | 8 ++++++-- man/QC_Plots_Mito.Rd | 8 ++++++-- man/QC_Plots_UMIs.Rd | 8 ++++++-- 11 files changed, 66 insertions(+), 23 deletions(-) diff --git a/man/ElbowPlot_scCustom.Rd b/man/ElbowPlot_scCustom.Rd index 22791ddce..24cb194c1 100644 --- a/man/ElbowPlot_scCustom.Rd +++ b/man/ElbowPlot_scCustom.Rd @@ -11,7 +11,8 @@ ElbowPlot_scCustom( calc_cutoffs = TRUE, plot_cutoffs = TRUE, line_colors = c("dodgerblue", "firebrick"), - linewidth = 0.5 + cutoff_linewidth = NULL, + linewidth = deprecated() ) } \arguments{ @@ -23,11 +24,13 @@ ElbowPlot_scCustom( \item{calc_cutoffs}{logical, whether or not to calculate the cutoffs, default is TRUE.} -\item{plot_cutoffs}{lgoical, whether to plot the cutoffs as vertical lines on plot, default is TRUE.} +\item{plot_cutoffs}{logical, whether to plot the cutoffs as vertical lines on plot, default is TRUE.} \item{line_colors}{colors for the cutoff lines, default is c("dodgerblue", "firebrick").} -\item{linewidth}{widith of the cutoff lines, default is 0.5.} +\item{cutoff_linewidth}{width of the cutoff lines, default is NULL, uses ggplot2 default.} + +\item{linewidth}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} } \value{ ggplot2 object diff --git a/man/QC_Histogram.Rd b/man/QC_Histogram.Rd index a677b3654..088c57535 100644 --- a/man/QC_Histogram.Rd +++ b/man/QC_Histogram.Rd @@ -9,7 +9,8 @@ QC_Histogram( features, low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, split.by = NULL, bins = 250, colors_use = "dodgerblue", @@ -28,7 +29,10 @@ QC_Histogram( \item{high_cutoff}{Plot line a potential high threshold for filtering.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{split.by}{Feature to split plots by (i.e. "orig.ident").} diff --git a/man/QC_Plot_GenevsFeature.Rd b/man/QC_Plot_GenevsFeature.Rd index f968becb3..8cd6bb133 100644 --- a/man/QC_Plot_GenevsFeature.Rd +++ b/man/QC_Plot_GenevsFeature.Rd @@ -13,7 +13,8 @@ QC_Plot_GenevsFeature( high_cutoff_gene = NULL, low_cutoff_feature = NULL, high_cutoff_feature = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, colors_use = NULL, pt.size = 1, group.by = NULL, @@ -43,7 +44,10 @@ QC_Plot_GenevsFeature( \item{high_cutoff_feature}{Plot line a potential high threshold for filtering feature1 per cell.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{colors_use}{vector of colors to use for plotting by identity.} diff --git a/man/QC_Plot_UMIvsFeature.Rd b/man/QC_Plot_UMIvsFeature.Rd index 49b41dc6b..ba3f5fb19 100644 --- a/man/QC_Plot_UMIvsFeature.Rd +++ b/man/QC_Plot_UMIvsFeature.Rd @@ -13,7 +13,8 @@ QC_Plot_UMIvsFeature( high_cutoff_UMI = NULL, low_cutoff_feature = NULL, high_cutoff_feature = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, colors_use = NULL, pt.size = 1, group.by = NULL, @@ -43,7 +44,10 @@ QC_Plot_UMIvsFeature( \item{high_cutoff_feature}{Plot line a potential high threshold for filtering feature1 per cell.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{colors_use}{vector of colors to use for plotting by identity.} diff --git a/man/QC_Plot_UMIvsGene.Rd b/man/QC_Plot_UMIvsGene.Rd index 1394f5d4b..9ac9f7d4e 100644 --- a/man/QC_Plot_UMIvsGene.Rd +++ b/man/QC_Plot_UMIvsGene.Rd @@ -12,7 +12,8 @@ QC_Plot_UMIvsGene( high_cutoff_gene = Inf, low_cutoff_UMI = -Inf, high_cutoff_UMI = Inf, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, colors_use = NULL, meta_gradient_name = NULL, meta_gradient_color = viridis_plasma_dark_high, @@ -47,7 +48,10 @@ QC_Plot_UMIvsGene( \item{high_cutoff_UMI}{Plot line a potential high threshold for filtering UMIs per cell.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{colors_use}{vector of colors to use for plotting by identity.} diff --git a/man/QC_Plots_Combined_Vln.Rd b/man/QC_Plots_Combined_Vln.Rd index 1e3f09b40..baa41dde6 100644 --- a/man/QC_Plots_Combined_Vln.Rd +++ b/man/QC_Plots_Combined_Vln.Rd @@ -11,7 +11,8 @@ QC_Plots_Combined_Vln( UMI_cutoffs = NULL, mito_cutoffs = NULL, mito_name = "percent_mito", - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -40,7 +41,10 @@ default is the current active.ident of the object.} \item{mito_name}{The column name containing percent mitochondrial counts information. Default value is "percent_mito" which is default value created when using \code{Add_Mito_Ribo()}.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{pt.size}{Point size for plotting} diff --git a/man/QC_Plots_Complexity.Rd b/man/QC_Plots_Complexity.Rd index 769ac3e1d..a7c278dec 100644 --- a/man/QC_Plots_Complexity.Rd +++ b/man/QC_Plots_Complexity.Rd @@ -13,7 +13,8 @@ QC_Plots_Complexity( plot_title = "Cell Complexity", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, plot_boxplot = FALSE, @@ -45,7 +46,10 @@ default is the current active.ident of the object.} \item{high_cutoff}{Plot line a potential high threshold for filtering.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{pt.size}{Point size for plotting} diff --git a/man/QC_Plots_Feature.Rd b/man/QC_Plots_Feature.Rd index d48e76ccc..49e7192ef 100644 --- a/man/QC_Plots_Feature.Rd +++ b/man/QC_Plots_Feature.Rd @@ -13,7 +13,8 @@ QC_Plots_Feature( plot_title = NULL, low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -45,7 +46,10 @@ default is the current active.ident of the object.} \item{high_cutoff}{Plot line a potential high threshold for filtering.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{pt.size}{Point size for plotting.} diff --git a/man/QC_Plots_Genes.Rd b/man/QC_Plots_Genes.Rd index 7eca2a978..4f3afe155 100644 --- a/man/QC_Plots_Genes.Rd +++ b/man/QC_Plots_Genes.Rd @@ -12,7 +12,8 @@ QC_Plots_Genes( y_axis_label = "Features", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, plot_boxplot = FALSE, @@ -43,7 +44,10 @@ default is the current active.ident of the object.} \item{high_cutoff}{Plot line a potential high threshold for filtering.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{pt.size}{Point size for plotting.} diff --git a/man/QC_Plots_Mito.Rd b/man/QC_Plots_Mito.Rd index be3399d02..eed70b4a6 100644 --- a/man/QC_Plots_Mito.Rd +++ b/man/QC_Plots_Mito.Rd @@ -13,7 +13,8 @@ QC_Plots_Mito( y_axis_label = "\% Mitochondrial Gene Counts", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -46,7 +47,10 @@ default is the current active.ident of the object.} \item{high_cutoff}{Plot line a potential high threshold for filtering.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{pt.size}{Point size for plotting.} diff --git a/man/QC_Plots_UMIs.Rd b/man/QC_Plots_UMIs.Rd index 7b05a56a6..3f7a011cb 100644 --- a/man/QC_Plots_UMIs.Rd +++ b/man/QC_Plots_UMIs.Rd @@ -12,7 +12,8 @@ QC_Plots_UMIs( y_axis_label = "UMIs", low_cutoff = NULL, high_cutoff = NULL, - cutoff_line_width = NULL, + cutoff_line_width = deprecated(), + cutoff_linewidth = NULL, pt.size = NULL, plot_median = FALSE, median_size = 15, @@ -43,7 +44,10 @@ default is the current active.ident of the object.} \item{high_cutoff}{Plot line a potential high threshold for filtering.} -\item{cutoff_line_width}{numerical value for thickness of cutoff lines, default is NULL.} +\item{cutoff_line_width}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#soft-deprecated}{\figure{lifecycle-soft-deprecated.svg}{options: alt='[Soft-deprecated]'}}}{\strong{[Soft-deprecated]}}. See \code{cutoff_linewidth}.} + +\item{cutoff_linewidth}{numerical value for thickness of cutoff lines, +default is NULL, uses ggplot2 defaults.} \item{pt.size}{Point size for plotting.} From 3894c0fa05f1b03023a033ee8ff523e38bb49bb3 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:29:52 -0500 Subject: [PATCH 063/105] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5b784855d..efe511345 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9009 +Version: 3.2.4.9010 Date: 2026-03-04 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), From d4bbebdea5b2ae3b9608e226e59a117aba5a0c9f Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:16:33 -0500 Subject: [PATCH 064/105] typo fix --- NEWS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 46c270b0e..77d7b6835 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,8 +11,9 @@ - **BREAKING CHANGE** The parameter `linewidth` has been soft-deprecated in `ElbowPlot_scCustom` function. Please use `cutoff_linewidth` instead. Using `linewidth` will warn user but still work until scCustomize v3.5.0. - Add checks for appropriate `...` usage. + ## Fixes -- Fixed setting default setting of `linewidth` parameter in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. +- Fixed default setting of `linewidth` parameter in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. - Fixed warning in `Dataset_Size_LIGER` due to deprecation in `Extract_Sample_Meta`. From e4ebfbb86ab88236539d573633be9c6ab8fc90d0 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:17:01 -0500 Subject: [PATCH 065/105] version and year updates --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 77d7b6835..bc886f0a5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# scCustomize 3.X.X (202X-XX-XX) +# scCustomize 3.3.0 (2026-XX-XX) ## Added - Added `reorder`, `reorder_decreasing`, and `plot_median` parameters to `Plot_Cells_per_Sample` when grouping by sample. - Added `Read_Velocity` function to enable reading of velocyto loom output files without needing to install velocyto.R (which currently suffers from significant installation issues unrelated to reading loom files). From 6aec142870bc0498741cf4e7b53b0b4437fa2b0a Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 5 Mar 2026 13:17:47 -0500 Subject: [PATCH 066/105] styling --- R/Utilities.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Utilities.R b/R/Utilities.R index 996148818..3b21d7bed 100644 --- a/R/Utilities.R +++ b/R/Utilities.R @@ -1132,7 +1132,7 @@ Add_Pct_Diff <- function( overwrite = FALSE ) { # Check if percent difference exists already - if ("pct_diff" %in% colnames(marker_dataframe)) { + if ("pct_diff" %in% colnames(x = marker_dataframe)) { df_name <- deparse(expr = substitute(expr = marker_dataframe)) if (isFALSE(x = overwrite)) { cli_abort(message = c("{.val pct_diff} column already present in {.code marker_dataframe}: {.val {df_name}}.", From 0ca7ba02bdce575f157ea20f7ebab8f872e61ad3 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 5 Mar 2026 13:21:47 -0500 Subject: [PATCH 067/105] styling --- R/Utilities_Objects.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Utilities_Objects.R b/R/Utilities_Objects.R index 986f0a930..0eedd6b9a 100644 --- a/R/Utilities_Objects.R +++ b/R/Utilities_Objects.R @@ -892,7 +892,7 @@ Random_Cells_Downsample <- function( rownames() %>% sample(size = num_cells[x]) }) - names(random_cells) <- idents_all + names(x = random_cells) <- idents_all } else { # set seed and select random cells per ident prev_seed <- get_seed() From 42ae77b7f81da0d80e3db189c2123eba5753a966 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 5 Mar 2026 13:23:08 -0500 Subject: [PATCH 068/105] styling --- R/Utilities_Objects.R | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/R/Utilities_Objects.R b/R/Utilities_Objects.R index 0eedd6b9a..9d00c84f8 100644 --- a/R/Utilities_Objects.R +++ b/R/Utilities_Objects.R @@ -1089,7 +1089,12 @@ Store_Palette_Seurat <- function( # Check Seurat Is_Seurat(seurat_object = seurat_object) - seurat_object <- Store_Misc_Info_Seurat(seurat_object = seurat_object, data_to_store = palette, data_name = palette_name, list_as_list = list_as_list, overwrite = overwrite, verbose = verbose) + seurat_object <- Store_Misc_Info_Seurat(seurat_object = seurat_object, + data_to_store = palette, + data_name = palette_name, + list_as_list = list_as_list, + overwrite = overwrite, + verbose = verbose) return(seurat_object) } @@ -1168,7 +1173,7 @@ Add_Alt_Feature_ID <- function( # if providing features_tsv if (!is.null(x = features_tsv_file)) { features_table <- data.table::fread(file = features_tsv_file, header = FALSE, data.table = FALSE) - colnames(features_table) <- c("Ensembl_ID", "Symbol", "Modality") + colnames(x = features_table) <- c("Ensembl_ID", "Symbol", "Modality") features_table$Symbol <- make.unique(features_table$Symbol) From 62663a73d9ce8aa2384de9423e44706bd89c929b Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:45:01 -0400 Subject: [PATCH 069/105] fix issue with split plots and group levels if only one group present in split --- R/Plotting_Seurat.R | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 6d1a5c421..2ae4f5f5e 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -2188,7 +2188,14 @@ DimPlot_scCustom <- function( if (is.null(x = group.by)) { levels_overall <- levels(x = Idents(object = seurat_object)) } else { - levels_overall <- levels(x = seurat_object@meta.data[[group.by]]) + if (inherits(x = seurat_object@meta.data[[group.by]], what = "factor")) { + levels_overall <- levels(x = seurat_object@meta.data[[group.by]]) + } else { + cli_inform(message = c("The variable {.field {group.by}} is not a factor. Converting for plot.", + "i" = "To avoid this warning set meta.data column to factor before plotting.")) + seurat_object@meta.data[[group.by]] <- factor(seurat_object@meta.data[[group.by]]) + levels_overall <- levels(x = seurat_object@meta.data[[group.by]]) + } } if (length(x = levels_overall) > length(x = colors_use)) { @@ -2197,7 +2204,9 @@ DimPlot_scCustom <- function( colors_overall <- colors_use - names(x = colors_overall) <- levels_overall + if (is.null(x = names(x = colors_overall))) { + names(x = colors_overall) <- levels_overall + } # plot plots <- lapply(1:length(x = split_by_list), function(x) { From 23ee3f5b4500dbc2d989c3b4a8c01838ab3cc88f Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:48:12 -0400 Subject: [PATCH 070/105] Update changelog --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index bc886f0a5..6b853792b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -15,6 +15,7 @@ ## Fixes - Fixed default setting of `linewidth` parameter in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. - Fixed warning in `Dataset_Size_LIGER` due to deprecation in `Extract_Sample_Meta`. +- Fixed issue with group colors in in `DimPlot_scCustom` when split only contains one group Thanks @zrlewis, ([#262](https://github.com/samuel-marsh/scCustomize/issues/262)). From 02a7fc88209f1206982083f6a93a4bbe055453ef Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:48:18 -0400 Subject: [PATCH 071/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index efe511345..038b54171 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9010 -Date: 2026-03-04 +Version: 3.2.4.9011 +Date: 2026-03-25 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From ca70891b0f97fcb17bd12871f8e95cc442b6de55 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 2 Apr 2026 08:06:14 -0400 Subject: [PATCH 072/105] Update changelog --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 6b853792b..ac7e5395b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,7 @@ - **BREAKING CHANGE** The `plot_by` parameter has been soft-deprecated in `Seq_QC_Plot_*` family of functions. Please use `group.by` instead. Using `plot_by` will warn user but still work until scCustomize v3.5.0. - **BREAKING CHANGE** The parameter `cutoff_line_width` has been soft-deprecated in `QC_Plot_*` family of functions. Please use `cutoff_linewidth` instead. Using `cutoff_line_width` will warn user but still work until scCustomize v3.5.0. - **BREAKING CHANGE** The parameter `linewidth` has been soft-deprecated in `ElbowPlot_scCustom` function. Please use `cutoff_linewidth` instead. Using `linewidth` will warn user but still work until scCustomize v3.5.0. -- Add checks for appropriate `...` usage. +- Add some checks for appropriate `...` usage. ## Fixes From 0531750a922ae0fc323854b8778793cdd771db68 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 2 Apr 2026 08:06:46 -0400 Subject: [PATCH 073/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 038b54171..c652887a5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9011 -Date: 2026-03-25 +Version: 3.2.4.9012 +Date: 2026-04-02 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From 867425bc789d779c73a843b30db0fcecada24874 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 2 Apr 2026 08:11:35 -0400 Subject: [PATCH 074/105] standardize format --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c652887a5..09fed5401 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -8,8 +8,8 @@ Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), person(given = 'Velina', family = 'Kozareva', role = c('ctb')), - person("Lucas", "Graybuck", email = "lucasg@alleninstitute.org", role = c('ctb')), - person("Zoe", "Clarke", email = "zoe.clarke@utoronto.ca", role = c('ctb'), comment = c(ORCID = "0000-0003-0336-8049")) + person(given ="Lucas", family = "Graybuck", email = "lucasg@alleninstitute.org", role = c('ctb')), + person(given ="Zoe", family = "Clarke", email = "zoe.clarke@utoronto.ca", role = c('ctb'), comment = c(ORCID = "0000-0003-0336-8049")) ) URL: https://github.com/samuel-marsh/scCustomize, https://samuel-marsh.github.io/scCustomize/, https://doi.org/10.5281/zenodo.5706431 BugReports: https://github.com/samuel-marsh/scCustomize/issues From 90787ffcf44328425a887c7e396f06a06d76c4ac Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 08:41:45 -0400 Subject: [PATCH 075/105] swap qs2 for qs --- vignettes/articles/Cell_Bender_Functions.Rmd | 4 ++-- vignettes/articles/Color_Palettes.Rmd | 4 ++-- vignettes/articles/Gene_Expression_Plotting.Rmd | 8 ++++---- vignettes/articles/Helpers_and_Utilities.Rmd | 2 +- vignettes/articles/LIGER_Functions.Rmd | 8 ++++---- vignettes/articles/Markers_and_Cluster_Annotation.Rmd | 4 ++-- vignettes/articles/Object_Conversion.Rmd | 1 - vignettes/articles/Object_QC_Functions.Rmd | 7 ++++--- vignettes/articles/QC_Plots.Rmd | 4 ++-- vignettes/articles/Sequencing_QC_Plots.Rmd | 6 +++--- vignettes/articles/Statistics.Rmd | 3 +-- vignettes/articles/Update_Gene_Symbols.Rmd | 4 ++-- 12 files changed, 27 insertions(+), 28 deletions(-) diff --git a/vignettes/articles/Cell_Bender_Functions.Rmd b/vignettes/articles/Cell_Bender_Functions.Rmd index ef5538eee..fc297ef33 100644 --- a/vignettes/articles/Cell_Bender_Functions.Rmd +++ b/vignettes/articles/Cell_Bender_Functions.Rmd @@ -52,13 +52,13 @@ library(patchwork) library(viridis) library(Seurat) library(scCustomize) -library(qs) +library(qs2) ``` ```{r include=FALSE} # Read in example Cell Bender Dual Assay Object. -astrocytes_cortex <- qread("assets/astro_nuc_seq.qs") +astrocytes_cortex <- qs_read("assets/astro_nuc_seq.qs2") ``` diff --git a/vignettes/articles/Color_Palettes.Rmd b/vignettes/articles/Color_Palettes.Rmd index e0d0630cc..2f1d53b09 100644 --- a/vignettes/articles/Color_Palettes.Rmd +++ b/vignettes/articles/Color_Palettes.Rmd @@ -52,10 +52,10 @@ library(dplyr) library(magrittr) library(patchwork) library(scCustomize) -library(qs) +library(qs2) # Load Marsh et al., 2022 datasets -marsh_mouse_micro <- qread(file = "assets/marsh_2020_micro.qs") +marsh_mouse_micro <- qs_read(file = "assets/marsh_2020_micro.qs2") # Load PBMC example dataset pbmc <- pbmc3k.SeuratData::pbmc3k.final diff --git a/vignettes/articles/Gene_Expression_Plotting.Rmd b/vignettes/articles/Gene_Expression_Plotting.Rmd index 398fe0c97..9ed9900d0 100644 --- a/vignettes/articles/Gene_Expression_Plotting.Rmd +++ b/vignettes/articles/Gene_Expression_Plotting.Rmd @@ -54,11 +54,11 @@ library(patchwork) library(viridis) library(Seurat) library(scCustomize) -library(qs) +library(qs2) # Load Marsh et al., 2022 datasets -marsh_mouse_micro <- qread(file = "assets/marsh_2020_micro.qs") -marsh_human_pm <- qread(file = "assets/marsh_human_pm.qs") +marsh_mouse_micro <- qs_read(file = "assets/marsh_2020_micro.qs2") +marsh_human_pm <- qs_read(file = "assets/marsh_human_pm.qs2") # Load pbmc dataset pbmc <- pbmc3k.SeuratData::pbmc3k.final @@ -315,7 +315,7 @@ Plot_Density_Joint_Only(seurat_object = marsh_mouse_micro, features = c("Fos", " In certain situations returning a plot from two different assays within the same object may be advantageous. For instance when object contains but raw and Cell Bender corrected counts you may want to plot the same gene from both assays to view the difference. See Cell Bender Functionality vignette for more info. ```{r} -cell_bender_example <- qread("assets/astro_nuc_seq.qs") +cell_bender_example <- qs_read("assets/astro_nuc_seq.qs2") ``` ```{r include=FALSE} diff --git a/vignettes/articles/Helpers_and_Utilities.Rmd b/vignettes/articles/Helpers_and_Utilities.Rmd index 786b83cb2..9e3fb7d90 100644 --- a/vignettes/articles/Helpers_and_Utilities.Rmd +++ b/vignettes/articles/Helpers_and_Utilities.Rmd @@ -276,7 +276,7 @@ GEO_10X <- Read10X_GEO(data_dir = "assets/GSE152183_RAW_Marsh/") GEO_10X_merged <- Merge_Sparse_Data_All(matrix_list = GEO_10X, add_cell_ids = names(GEO_10X)) # Create Seurat Object and specify orig.ident location -GEO_10X_Seurat <- Seurat::CreateSeuratObject(counts = GEO_10X_merged, names.field = 1, names.delim = "_", min.features = 200, min.cells = 5) +GEO_10X_Seurat <- CreateSeuratObject(counts = GEO_10X_merged, names.field = 1, names.delim = "_", min.features = 200, min.cells = 5) ``` ### Merging List of Seurat Objects diff --git a/vignettes/articles/LIGER_Functions.Rmd b/vignettes/articles/LIGER_Functions.Rmd index 3f8dbc0e9..7fbc68996 100644 --- a/vignettes/articles/LIGER_Functions.Rmd +++ b/vignettes/articles/LIGER_Functions.Rmd @@ -54,13 +54,13 @@ library(patchwork) library(Seurat) library(rliger) library(scCustomize) -library(qs) +library(qs2) ``` ```{r eval=FALSE} # read object -marsh_micro <- qread("assets/marsh_2020_micro.qs") +marsh_micro <- qs_read("assets/marsh_2020_micro.qs2") # Convert to liger marsh_liger <- as.liger(object = marsh_micro, datasetVar = "orig.ident") @@ -68,7 +68,7 @@ marsh_liger <- as.liger(object = marsh_micro, datasetVar = "orig.ident") ```{r include=FALSE} -marsh_liger <- qread("assets/marsh_liger.qs") +marsh_liger <- qs_read("assets/marsh_liger.qs2") ``` @@ -169,7 +169,7 @@ DimPlot_LIGER(liger_object = marsh_liger, ggplot_default_colors = TRUE) ## Customized plotFactors Functionality *NOTE: For this example as "marsh_liger" was not originally a LIGER analyzed object it has no factors. So I ran a basic LIGER pipeline (with no specific parameters to demonstrate functionality of `Top_Genes_Factor`)* ```{r include=FALSE} -marsh_liger <- qread("assets/marsh_liger_factor.qs") +marsh_liger <- qs_read("assets/marsh_liger_factor.qs2") ``` scCustomize contains function `plotFactors_scCustom()` which expands the functionality and customizes the visualizes of LIGER's `plotFactors()` function. diff --git a/vignettes/articles/Markers_and_Cluster_Annotation.Rmd b/vignettes/articles/Markers_and_Cluster_Annotation.Rmd index 67b91948f..838cb75f2 100644 --- a/vignettes/articles/Markers_and_Cluster_Annotation.Rmd +++ b/vignettes/articles/Markers_and_Cluster_Annotation.Rmd @@ -51,7 +51,7 @@ library(dplyr) library(magrittr) library(Seurat) library(scCustomize) -library(qs) +library(qs2) # Load example dataset for tutorial pbmc <- pbmc3k.SeuratData::pbmc3k.final @@ -159,7 +159,7 @@ head(top_5_df, 10) %>% `Extract_Top_Markers` uses the data.frame output of `Seurat::FindAllMarkers()` by default but can be used with any data.frame by supplying few extra parameters. Let's use the function on the output from [presto package](https://github.com/immunogenomics/presto) and order the results by auc instead of log2FC. ```{r} # Read in pre-computed data.frame results -presto_markers <- qread("assets/presto_markers.qs") +presto_markers <- qs_read("assets/presto_markers.qs2") # Extract top markers top_5_presto <- Extract_Top_Markers(marker_dataframe = presto_markers, num_features = 5, group.by = "cluster", rank_by = "auc", gene_column = "gene") diff --git a/vignettes/articles/Object_Conversion.Rmd b/vignettes/articles/Object_Conversion.Rmd index 0f438f63b..aa5594312 100644 --- a/vignettes/articles/Object_Conversion.Rmd +++ b/vignettes/articles/Object_Conversion.Rmd @@ -50,7 +50,6 @@ While many packages are have some object converters they are not always as featu library(Seurat) library(rliger) library(scCustomize) -library(qs) ``` Load Seurat Object & Add QC Data diff --git a/vignettes/articles/Object_QC_Functions.Rmd b/vignettes/articles/Object_QC_Functions.Rmd index 255bccdd6..83efe52d9 100644 --- a/vignettes/articles/Object_QC_Functions.Rmd +++ b/vignettes/articles/Object_QC_Functions.Rmd @@ -51,6 +51,7 @@ library(magrittr) library(patchwork) library(Seurat) library(scCustomize) +library(qs2) pbmc <- pbmc3k.SeuratData::pbmc3k hcabm <- hcabm40k.SeuratData::hcabm40k @@ -161,7 +162,7 @@ pbmc <- Add_Mito_Ribo(object = pbmc, species = "human") Some analyses are performed with cells aligned to a genome that contains multiple species (see Cell Ranger/10X documentation for more info). scCustomize now supports adding mitochondrial and ribosomal percentages for these datasets using optional parameters. Here we will use example data provided by 10X Genomics [here](https://www.10xgenomics.com/datasets/10k-hgmm-3p-gemx). ```{r include=FALSE} -pbmc_dual_species <- qs::qread("assets/pbmc_dual_species.qs") +pbmc_dual_species <- qs_read("assets/pbmc_dual_species.qs2") ``` @@ -323,8 +324,8 @@ In Marsh et al., 2022 ([*Nature Neuroscience*](https://doi.org/10.1038/s41593-02 To demonstrate this function we will use data objects from Marsh et al., 2022. ```{r} # Load Marsh et al., 2022 datasets -marsh_mouse_micro <- qs::qread(file = "assets/marsh_2020_micro.qs") -marsh_human_pm <- qs::qread(file = "assets/marsh_human_pm.qs") +marsh_mouse_micro <- qs_read(file = "assets/marsh_2020_micro.qs2") +marsh_human_pm <- qs_read(file = "assets/marsh_human_pm.qs2") ``` diff --git a/vignettes/articles/QC_Plots.Rmd b/vignettes/articles/QC_Plots.Rmd index 2821b70b2..053be528e 100644 --- a/vignettes/articles/QC_Plots.Rmd +++ b/vignettes/articles/QC_Plots.Rmd @@ -53,7 +53,7 @@ library(magrittr) library(patchwork) library(Seurat) library(scCustomize) -library(qs) +library(qs2) # Load Example Dataset hca_bm <- hcabm40k.SeuratData::hcabm40k @@ -274,7 +274,7 @@ scCustomize also contains plotting function to plot the number of cells or nucle Since the HCA Bone Marrow dataset has exactly the same number of cells per sample we will use the microglia object from the Analysis Plots vignette. ```{r include=FALSE} -marsh_mouse_micro <- qread(file = "assets/marsh_2020_micro.qs") +marsh_mouse_micro <- qs_read(file = "assets/marsh_2020_micro.qs2") ``` diff --git a/vignettes/articles/Sequencing_QC_Plots.Rmd b/vignettes/articles/Sequencing_QC_Plots.Rmd index 8ec0b3c04..caed21a15 100644 --- a/vignettes/articles/Sequencing_QC_Plots.Rmd +++ b/vignettes/articles/Sequencing_QC_Plots.Rmd @@ -50,12 +50,12 @@ library(dplyr) library(magrittr) library(Seurat) library(scCustomize) -library(qs) +library(qs2) ``` ```{r include=FALSE} -raw_metrics <- qread("assets/seq_metrics_dataframe_RAW.qs") -meta_metrics <- qread("assets/seq_metrics_dataframe_meta.qs") +raw_metrics <- qs_read("assets/seq_metrics_dataframe_RAW.qs2") +meta_metrics <- qs_read("assets/seq_metrics_dataframe_meta.qs2") ``` diff --git a/vignettes/articles/Statistics.Rmd b/vignettes/articles/Statistics.Rmd index 711754dca..8f926e808 100644 --- a/vignettes/articles/Statistics.Rmd +++ b/vignettes/articles/Statistics.Rmd @@ -52,7 +52,6 @@ library(dplyr) library(magrittr) library(Seurat) library(scCustomize) -library(qs) # Load example dataset for tutorial pbmc <- pbmc3k.SeuratData::pbmc3k.final @@ -289,7 +288,7 @@ p2 <- Plot_Median_Genes(seurat_object = pbmc, group.by = "group") p3 <- Plot_Median_Other(seurat_object = pbmc, median_var = "module_score1", group.by = "group") -patchwork::wrap_plots(p1, p2, p3, ncol = 3) +wrap_plots(p1, p2, p3, ncol = 3) ``` diff --git a/vignettes/articles/Update_Gene_Symbols.Rmd b/vignettes/articles/Update_Gene_Symbols.Rmd index 9c994443b..cf7f81ffc 100644 --- a/vignettes/articles/Update_Gene_Symbols.Rmd +++ b/vignettes/articles/Update_Gene_Symbols.Rmd @@ -49,7 +49,7 @@ In the absence of more static identifier (Ensembl ID or Entrez ID Numbers) the o # Load Packages library(Seurat) library(scCustomize) -library(qs) +library(qs2) ``` Load Seurat Object & Add QC Data @@ -159,7 +159,7 @@ scCustomize also contains helper function to update mouse gene symbols using the ```{r message=TRUE} # Load mouse dataset -marsh_mouse_micro <- qread(file = "assets/marsh_2020_micro.qs") +marsh_mouse_micro <- qs_read(file = "assets/marsh_2020_micro.qs2") # Get updated symbols updated_symbols <- Updated_MGI_Symbols(input_data = Features(marsh_mouse_micro)) From cbd59eb53e09f141b0438b795721ee60919d2b48 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 08:42:01 -0400 Subject: [PATCH 076/105] update changelog --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index ac7e5395b..7b93e8bf9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,6 +16,7 @@ - Fixed default setting of `linewidth` parameter in `geom_hline` and `geom_vline` calls to avoid unnecessary empty aesthetic warnings in ggplot2 4.0.0+. - Fixed warning in `Dataset_Size_LIGER` due to deprecation in `Extract_Sample_Meta`. - Fixed issue with group colors in in `DimPlot_scCustom` when split only contains one group Thanks @zrlewis, ([#262](https://github.com/samuel-marsh/scCustomize/issues/262)). +- All vignettes updated to use qs2 package as qs package is now fully deprecated. From 35d68f43261d015efd2ae21e0aad60682064d2cb Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 08:42:16 -0400 Subject: [PATCH 077/105] swap qs2 for qs and bump version and date --- DESCRIPTION | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 09fed5401..dde4bc82e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9012 -Date: 2026-04-02 +Version: 3.2.4.9013 +Date: 2026-04-09 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), @@ -64,7 +64,7 @@ Suggests: rmarkdown, scuttle, tidyselect, - qs, + qs2, viridis License: GPL (>= 3) Encoding: UTF-8 From 458bb864b96b36b4fcd5c7ee26836e56386f7cda Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:08:26 -0400 Subject: [PATCH 078/105] vignette fixes --- vignettes/articles/Color_Palettes.Rmd | 2 +- vignettes/articles/Sequencing_QC_Plots.Rmd | 6 +++--- vignettes/articles/Spatial_Plotting.Rmd | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/vignettes/articles/Color_Palettes.Rmd b/vignettes/articles/Color_Palettes.Rmd index 2f1d53b09..f72c98219 100644 --- a/vignettes/articles/Color_Palettes.Rmd +++ b/vignettes/articles/Color_Palettes.Rmd @@ -172,7 +172,7 @@ To visualize these or any other palette you can use the `PalettePlot()` function ```{r eval=FALSE} PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 26, palette = "alphabet")) -PalettePlot(pal = c("color1", "color2", ...) +PalettePlot(pal = c("color1", "color2", ...)) ``` diff --git a/vignettes/articles/Sequencing_QC_Plots.Rmd b/vignettes/articles/Sequencing_QC_Plots.Rmd index caed21a15..adce43cc1 100644 --- a/vignettes/articles/Sequencing_QC_Plots.Rmd +++ b/vignettes/articles/Sequencing_QC_Plots.Rmd @@ -145,20 +145,20 @@ However, to simplify plotting there are also two wrapper functions which will re ### Basic Metrics Summary A set of basic metrics can be plotted using `Seq_QC_Plot_Basic_Combined` ```{r, fig.height=9, fig.width=13} -Seq_QC_Plot_Basic_Combined(metrics_dataframe = metrics_final, plot_by = "Full_Batch") +Seq_QC_Plot_Basic_Combined(metrics_dataframe = metrics_final, group.by = "Full_Batch") ``` ### Alignment Metrics Summary A set of alignment-based metrics can be plotted using `Seq_QC_Plot_Alignment_Combined` ```{r, fig.height=9, fig.width=13} -Seq_QC_Plot_Alignment_Combined(metrics_dataframe = metrics_final, plot_by = "Full_Batch") +Seq_QC_Plot_Alignment_Combined(metrics_dataframe = metrics_final, group.by = "Full_Batch") ``` ### Basic Statistics All of the `Seq_QC_Plot_...` functions also contain parameter to calculate significance between all groups using `ggpubr::stat_compare_means()`. ***NOTE: See function help pages and ggpubr for more info to make sure the right test is being used for your data.*** ```{r, fig.height=9, fig.width=13} -Seq_QC_Plot_Basic_Combined(metrics_dataframe = metrics_final, plot_by = "Full_Batch", significance = T) +Seq_QC_Plot_Basic_Combined(metrics_dataframe = metrics_final, group.by = "Full_Batch", significance = T) ``` ### Barcode Rank Plots diff --git a/vignettes/articles/Spatial_Plotting.Rmd b/vignettes/articles/Spatial_Plotting.Rmd index f6e8e25c0..7784cd926 100644 --- a/vignettes/articles/Spatial_Plotting.Rmd +++ b/vignettes/articles/Spatial_Plotting.Rmd @@ -53,7 +53,6 @@ library(patchwork) library(viridis) library(Seurat) library(scCustomize) -library(qs) # Load stxBrain Visium dataset and Slide-seq V2 ssHippo dataset mouse_ctx <- SeuratData::LoadData("stxBrain", type = "anterior1") From 01b83b10733416a2185af76f477885ac3e2f02db Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:08:36 -0400 Subject: [PATCH 079/105] check fixes --- R/Plotting_QC_Seq_10X.R | 20 +++++++++++++++++--- R/Plotting_Seurat.R | 4 ++-- R/Plotting_Statistics.R | 3 ++- R/Read_Write_Data.R | 22 +++++++++++++--------- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/R/Plotting_QC_Seq_10X.R b/R/Plotting_QC_Seq_10X.R index e9208f27f..211aeebe8 100644 --- a/R/Plotting_QC_Seq_10X.R +++ b/R/Plotting_QC_Seq_10X.R @@ -153,10 +153,11 @@ Seq_QC_Plot_Reads_per_Cell <- function( #' Plot the number of cells per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -297,10 +298,11 @@ Seq_QC_Plot_Number_Cells <- function( #' Plot the median genes per cell per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -431,10 +433,11 @@ Seq_QC_Plot_Genes <- function( #' Plot the median UMIs per cell per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -565,6 +568,7 @@ Seq_QC_Plot_UMIs <- function( #' Plot the total genes detected per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -699,6 +703,7 @@ Seq_QC_Plot_Total_Genes <- function( #' Plot the sequencing saturation percentage per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -840,6 +845,7 @@ Seq_QC_Plot_Saturation <- function( #' Plot the fraction of reads in cells per sample #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -981,6 +987,7 @@ Seq_QC_Plot_Reads_in_Cells <- function( #' Plot the fraction of reads confidently mapped to transcriptome #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -1121,6 +1128,7 @@ Seq_QC_Plot_Transcriptome <- function( #' Plot the fraction of reads confidently mapped to genome #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -1261,6 +1269,7 @@ Seq_QC_Plot_Genome <- function( #' Plot the fraction of reads confidently mapped to intergenic regions #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -1401,6 +1410,7 @@ Seq_QC_Plot_Intergenic <- function( #' Plot the fraction of reads confidently mapped to intronic regions #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -1541,6 +1551,7 @@ Seq_QC_Plot_Intronic <- function( #' Plot the fraction of reads confidently mapped to Exonic regions #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -1681,6 +1692,7 @@ Seq_QC_Plot_Exonic <- function( #' Plot the fraction of reads mapped Antisense to Gene #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -1826,6 +1838,7 @@ Seq_QC_Plot_Antisense <- function( #' Plot a combined plot of the basic QC metrics from sequencing output. #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. @@ -1928,6 +1941,7 @@ Seq_QC_Plot_Basic_Combined <- function( #' Plot a combined plot of the Alignment QC metrics from sequencing output. #' #' @param metrics_dataframe data.frame contain Cell Ranger QC Metrics (see \code{\link{Read_Metrics_10X}}). +#' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 2ae4f5f5e..b0bf8d8c9 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -2782,7 +2782,7 @@ ElbowPlot_scCustom <- function( if (isFALSE(x = co1_missing)) { plot <- plot + - geom_vline(xintercept = co1, linetype = "dashed", colour = line_colors[1], linewidth = linewidth) + + geom_vline(xintercept = co1, linetype = "dashed", colour = line_colors[1], linewidth = cutoff_linewidth) + annotate("text", x = co1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 0) } else { plot <- plot + @@ -2791,7 +2791,7 @@ ElbowPlot_scCustom <- function( if (isFALSE(x = co2_missing)) { plot <- plot + - geom_vline(xintercept = co2, linetype = "dashed", colour = line_colors[2], linewidth = linewidth) + + geom_vline(xintercept = co2, linetype = "dashed", colour = line_colors[2], linewidth = cutoff_linewidth) + annotate("text", x = co2, y = (y_max-0.2), label = paste0("The second cutoff is: PC", co2), vjust = -0.5, hjust = 1) } else { plot <- plot + diff --git a/R/Plotting_Statistics.R b/R/Plotting_Statistics.R index 1a28e3704..ca08d9141 100644 --- a/R/Plotting_Statistics.R +++ b/R/Plotting_Statistics.R @@ -673,7 +673,8 @@ Plot_Median_Other <- function( #' Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident") #' #' #' # Plot cells per sample individually and reorder x-axis by cell number -#' Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident", order = TRUE) +#' Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident", +#' order = TRUE) #' #' } #' diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index 4612d0e4f..ea0ce0092 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1709,17 +1709,17 @@ ReadVelocity_Multi_File_Internal <- function( # sort matrices by read type if (isTRUE(x = sort_type)) { spliced_list <- lapply(1:length(x = raw_data_list), function(x){ - data <- testing[[x]][["spliced"]] + data <- raw_data_list[[x]][["spliced"]] }) names(x = spliced_list) <- names(x = raw_data_list) unspliced_list <- lapply(1:length(x = raw_data_list), function(x){ - data <- testing[[x]][["unspliced"]] + data <- raw_data_list[[x]][["unspliced"]] }) names(x = unspliced_list) <- names(x = raw_data_list) ambiguous_list <- lapply(1:length(x = raw_data_list), function(x){ - data <- testing[[x]][["ambiguous"]] + data <- raw_data_list[[x]][["ambiguous"]] }) names(x = ambiguous_list) <- names(x = raw_data_list) @@ -1829,17 +1829,17 @@ ReadVelocity_Multi_Directory <- function( # sort matrices by read type if (isTRUE(x = sort_type)) { spliced_list <- lapply(1:length(x = raw_data_list), function(x){ - data <- testing[[x]][["spliced"]] + data <- raw_data_list[[x]][["spliced"]] }) names(x = spliced_list) <- names(x = raw_data_list) unspliced_list <- lapply(1:length(x = raw_data_list), function(x){ - data <- testing[[x]][["unspliced"]] + data <- raw_data_list[[x]][["unspliced"]] }) names(x = unspliced_list) <- names(x = raw_data_list) ambiguous_list <- lapply(1:length(x = raw_data_list), function(x){ - data <- testing[[x]][["ambiguous"]] + data <- raw_data_list[[x]][["ambiguous"]] }) names(x = ambiguous_list) <- names(x = raw_data_list) @@ -1875,6 +1875,8 @@ ReadVelocity_Multi_Directory <- function( #' #' @export #' +#' @importFrom utils capture.output +#' #' @references Function is updated from `SeuratWrappers::ReadVelocity` #' \url{https://github.com/satijalab/seurat-wrappers/blob/master/R/velocity.R} (License: GPL-3). #' Function included in scCustomize to avoid installation issues related to other aspects of @@ -1891,14 +1893,16 @@ ReadVelocity_Multi_Directory <- function( #' # Read single velocity loom file with ensembl IDs #' velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom", gene_symbol = FALSE) #' -#' # Read multiple files from a parent directory with many subdirectories & return 1 list entry per sample +#' # Read multiple files from a parent directory with many subdirectories & return 1 list entry per +#' sample #' # Each entry will contain 3 matrices (spliced, unspliced, ambiguous) #' velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/") #' #' # Sort returned list by read type instead of by sample #' # list will contain 3 entries (spliced, unspliced, ambiguous) #' # each entry will contain 1 matrix per sample -#' velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/", sort_type = TRUE) +#' velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/", +#' sort_type = TRUE) #' #' # Read multiple files from a single directory #' velo_res_list <- Read_Velocity(loom_file = "PATH/", multi_dir = FALSE) @@ -1936,7 +1940,7 @@ Read_Velocity <- function( # multi directory if (isTRUE(x = multi_dir)) { - data_list <- ReadVelocity_Multi_Dir_Internal(data_dir = data_dir, gene_symbol = gene_symbol, sample_list = sample_list, sample_names = sample_names, shared_suffix = shared_suffix, parallel = parallel, num_cores = num_cores, sort_type = sort_type) + data_list <- ReadVelocity_Multi_Directory(data_dir = data_dir, gene_symbol = gene_symbol, sample_list = sample_list, sample_names = sample_names, shared_suffix = shared_suffix, parallel = parallel, num_cores = num_cores, sort_type = sort_type) return(data_list) } } From 12dc30cf3a16e61e467f484f63a168bc55fef977 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:09:02 -0400 Subject: [PATCH 080/105] Update docs --- NAMESPACE | 1 + man/Plot_Cells_per_Sample.Rd | 3 ++- man/Read_Velocity.Rd | 6 ++++-- man/Seq_QC_Plot_Alignment_Combined.Rd | 2 ++ man/Seq_QC_Plot_Antisense.Rd | 2 ++ man/Seq_QC_Plot_Basic_Combined.Rd | 2 ++ man/Seq_QC_Plot_Exonic.Rd | 2 ++ man/Seq_QC_Plot_Genes.Rd | 4 +++- man/Seq_QC_Plot_Genome.Rd | 2 ++ man/Seq_QC_Plot_Intergenic.Rd | 2 ++ man/Seq_QC_Plot_Intronic.Rd | 2 ++ man/Seq_QC_Plot_Number_Cells.Rd | 4 +++- man/Seq_QC_Plot_Reads_in_Cells.Rd | 2 ++ man/Seq_QC_Plot_Saturation.Rd | 2 ++ man/Seq_QC_Plot_Total_Genes.Rd | 2 ++ man/Seq_QC_Plot_Transcriptome.Rd | 2 ++ man/Seq_QC_Plot_UMIs.Rd | 4 +++- 17 files changed, 38 insertions(+), 6 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 45b74d9bc..b878b3732 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -347,6 +347,7 @@ importFrom(tidyr,pivot_longer) importFrom(tidyr,pivot_wider) importFrom(tidyr,replace_na) importFrom(tidyr,separate_wider_delim) +importFrom(utils,capture.output) importFrom(utils,combn) importFrom(utils,packageVersion) importFrom(utils,read.csv) diff --git a/man/Plot_Cells_per_Sample.Rd b/man/Plot_Cells_per_Sample.Rd index e45c2a1c9..944018432 100644 --- a/man/Plot_Cells_per_Sample.Rd +++ b/man/Plot_Cells_per_Sample.Rd @@ -68,7 +68,8 @@ Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident") #' # Plot cells per sample individually and reorder x-axis by cell number -Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident", order = TRUE) +Plot_Cells_per_Sample(seurat_object = obj, sample_col = "orig.ident", group.by = "orig.ident", +order = TRUE) } diff --git a/man/Read_Velocity.Rd b/man/Read_Velocity.Rd index b05b73491..976e4cc0e 100644 --- a/man/Read_Velocity.Rd +++ b/man/Read_Velocity.Rd @@ -56,14 +56,16 @@ velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom") # Read single velocity loom file with ensembl IDs velo_res <- Read_Velocity(loom_file = "PATH/sample01.loom", gene_symbol = FALSE) -# Read multiple files from a parent directory with many subdirectories & return 1 list entry per sample +# Read multiple files from a parent directory with many subdirectories & return 1 list entry per +sample # Each entry will contain 3 matrices (spliced, unspliced, ambiguous) velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/") # Sort returned list by read type instead of by sample # list will contain 3 entries (spliced, unspliced, ambiguous) # each entry will contain 1 matrix per sample -velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/", sort_type = TRUE) +velo_res_list <- Read_Velocity(loom_file = "PATH/", secondary_path = "SEC_PATH/", +sort_type = TRUE) # Read multiple files from a single directory velo_res_list <- Read_Velocity(loom_file = "PATH/", multi_dir = FALSE) diff --git a/man/Seq_QC_Plot_Alignment_Combined.Rd b/man/Seq_QC_Plot_Alignment_Combined.Rd index 6b804b297..f23a3344a 100644 --- a/man/Seq_QC_Plot_Alignment_Combined.Rd +++ b/man/Seq_QC_Plot_Alignment_Combined.Rd @@ -21,6 +21,8 @@ Seq_QC_Plot_Alignment_Combined( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Antisense.Rd b/man/Seq_QC_Plot_Antisense.Rd index ab02d3fe8..6fd7c965f 100644 --- a/man/Seq_QC_Plot_Antisense.Rd +++ b/man/Seq_QC_Plot_Antisense.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Antisense( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Basic_Combined.Rd b/man/Seq_QC_Plot_Basic_Combined.Rd index 51e54dfac..412c73f02 100644 --- a/man/Seq_QC_Plot_Basic_Combined.Rd +++ b/man/Seq_QC_Plot_Basic_Combined.Rd @@ -21,6 +21,8 @@ Seq_QC_Plot_Basic_Combined( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Exonic.Rd b/man/Seq_QC_Plot_Exonic.Rd index 4b22d111f..98695b91e 100644 --- a/man/Seq_QC_Plot_Exonic.Rd +++ b/man/Seq_QC_Plot_Exonic.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Exonic( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Genes.Rd b/man/Seq_QC_Plot_Genes.Rd index 904edcf66..2002f117b 100644 --- a/man/Seq_QC_Plot_Genes.Rd +++ b/man/Seq_QC_Plot_Genes.Rd @@ -20,10 +20,12 @@ Seq_QC_Plot_Genes( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Genome.Rd b/man/Seq_QC_Plot_Genome.Rd index 87a55f93c..124b04b72 100644 --- a/man/Seq_QC_Plot_Genome.Rd +++ b/man/Seq_QC_Plot_Genome.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Genome( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Intergenic.Rd b/man/Seq_QC_Plot_Intergenic.Rd index ff7847a65..4f5a5d9ad 100644 --- a/man/Seq_QC_Plot_Intergenic.Rd +++ b/man/Seq_QC_Plot_Intergenic.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Intergenic( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Intronic.Rd b/man/Seq_QC_Plot_Intronic.Rd index 161962252..67c791658 100644 --- a/man/Seq_QC_Plot_Intronic.Rd +++ b/man/Seq_QC_Plot_Intronic.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Intronic( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Number_Cells.Rd b/man/Seq_QC_Plot_Number_Cells.Rd index f927a2991..a40e0c89d 100644 --- a/man/Seq_QC_Plot_Number_Cells.Rd +++ b/man/Seq_QC_Plot_Number_Cells.Rd @@ -20,10 +20,12 @@ Seq_QC_Plot_Number_Cells( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Reads_in_Cells.Rd b/man/Seq_QC_Plot_Reads_in_Cells.Rd index fb28f4057..38c4cc874 100644 --- a/man/Seq_QC_Plot_Reads_in_Cells.Rd +++ b/man/Seq_QC_Plot_Reads_in_Cells.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Reads_in_Cells( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Saturation.Rd b/man/Seq_QC_Plot_Saturation.Rd index 18fcc4aa4..0c4cf176a 100644 --- a/man/Seq_QC_Plot_Saturation.Rd +++ b/man/Seq_QC_Plot_Saturation.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Saturation( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Total_Genes.Rd b/man/Seq_QC_Plot_Total_Genes.Rd index b8397c160..2f9660fd7 100644 --- a/man/Seq_QC_Plot_Total_Genes.Rd +++ b/man/Seq_QC_Plot_Total_Genes.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Total_Genes( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_Transcriptome.Rd b/man/Seq_QC_Plot_Transcriptome.Rd index 7b955fdfd..3fb5a4777 100644 --- a/man/Seq_QC_Plot_Transcriptome.Rd +++ b/man/Seq_QC_Plot_Transcriptome.Rd @@ -20,6 +20,8 @@ Seq_QC_Plot_Transcriptome( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} diff --git a/man/Seq_QC_Plot_UMIs.Rd b/man/Seq_QC_Plot_UMIs.Rd index a8714e7b3..7c4c2f655 100644 --- a/man/Seq_QC_Plot_UMIs.Rd +++ b/man/Seq_QC_Plot_UMIs.Rd @@ -20,10 +20,12 @@ Seq_QC_Plot_UMIs( \item{group.by}{Grouping factor for the plot. Default is to plot as single group with single point per sample.} +\item{plot_by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} soft-deprecated. See \code{group.by}.} + \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} From de820260e9cf9e44e3258328c04cca6001800176 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:09:30 -0400 Subject: [PATCH 081/105] fix deprecated code --- R/Plotting_QC_Seq_10X.R | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/R/Plotting_QC_Seq_10X.R b/R/Plotting_QC_Seq_10X.R index 211aeebe8..c8d88b272 100644 --- a/R/Plotting_QC_Seq_10X.R +++ b/R/Plotting_QC_Seq_10X.R @@ -12,7 +12,7 @@ #' @param plot_by `r lifecycle::badge("deprecated")` soft-deprecated. See `group.by`. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -572,7 +572,7 @@ Seq_QC_Plot_UMIs <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -707,7 +707,7 @@ Seq_QC_Plot_Total_Genes <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -849,7 +849,7 @@ Seq_QC_Plot_Saturation <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -991,7 +991,7 @@ Seq_QC_Plot_Reads_in_Cells <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -1132,7 +1132,7 @@ Seq_QC_Plot_Transcriptome <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -1273,7 +1273,7 @@ Seq_QC_Plot_Genome <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -1414,7 +1414,7 @@ Seq_QC_Plot_Intergenic <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -1555,7 +1555,7 @@ Seq_QC_Plot_Intronic <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -1696,7 +1696,7 @@ Seq_QC_Plot_Exonic <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by #' grouping factor. Default is FALSE. @@ -1842,7 +1842,7 @@ Seq_QC_Plot_Antisense <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param patchwork_title Title to use for the patchworked plot output. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by @@ -1945,7 +1945,7 @@ Seq_QC_Plot_Basic_Combined <- function( #' @param group.by Grouping factor for the plot. Default is to plot as single group with single point per sample. #' @param colors_use colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if #' less than 8 groups and `DiscretePalette_scCustomize(palette = "polychrome")` if more than 8. -#' @param dot_size size of the dots plotted if `plot_by` is not `sample_id` Default is 1. +#' @param dot_size size of the dots plotted if `group.by` is not `sample_id` Default is 1. #' @param x_lab_rotate logical. Whether to rotate the axes labels on the x-axis. Default is FALSE. #' @param patchwork_title Title to use for the patchworked plot output. #' @param significance logical. Whether to calculate and plot p-value comparisons when plotting by From 68f5f8711f89de45f47efd99b39716b3067cfed7 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:09:45 -0400 Subject: [PATCH 082/105] Update docs --- man/Seq_QC_Plot_Alignment_Combined.Rd | 2 +- man/Seq_QC_Plot_Antisense.Rd | 2 +- man/Seq_QC_Plot_Basic_Combined.Rd | 2 +- man/Seq_QC_Plot_Exonic.Rd | 2 +- man/Seq_QC_Plot_Genome.Rd | 2 +- man/Seq_QC_Plot_Intergenic.Rd | 2 +- man/Seq_QC_Plot_Intronic.Rd | 2 +- man/Seq_QC_Plot_Reads_in_Cells.Rd | 2 +- man/Seq_QC_Plot_Reads_per_Cell.Rd | 2 +- man/Seq_QC_Plot_Saturation.Rd | 2 +- man/Seq_QC_Plot_Total_Genes.Rd | 2 +- man/Seq_QC_Plot_Transcriptome.Rd | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/man/Seq_QC_Plot_Alignment_Combined.Rd b/man/Seq_QC_Plot_Alignment_Combined.Rd index f23a3344a..840361e32 100644 --- a/man/Seq_QC_Plot_Alignment_Combined.Rd +++ b/man/Seq_QC_Plot_Alignment_Combined.Rd @@ -26,7 +26,7 @@ Seq_QC_Plot_Alignment_Combined( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Antisense.Rd b/man/Seq_QC_Plot_Antisense.Rd index 6fd7c965f..9c757e9a3 100644 --- a/man/Seq_QC_Plot_Antisense.Rd +++ b/man/Seq_QC_Plot_Antisense.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Antisense( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Basic_Combined.Rd b/man/Seq_QC_Plot_Basic_Combined.Rd index 412c73f02..e81d86b18 100644 --- a/man/Seq_QC_Plot_Basic_Combined.Rd +++ b/man/Seq_QC_Plot_Basic_Combined.Rd @@ -26,7 +26,7 @@ Seq_QC_Plot_Basic_Combined( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Exonic.Rd b/man/Seq_QC_Plot_Exonic.Rd index 98695b91e..95ceb3fa0 100644 --- a/man/Seq_QC_Plot_Exonic.Rd +++ b/man/Seq_QC_Plot_Exonic.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Exonic( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Genome.Rd b/man/Seq_QC_Plot_Genome.Rd index 124b04b72..97f913b99 100644 --- a/man/Seq_QC_Plot_Genome.Rd +++ b/man/Seq_QC_Plot_Genome.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Genome( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Intergenic.Rd b/man/Seq_QC_Plot_Intergenic.Rd index 4f5a5d9ad..83ec2a650 100644 --- a/man/Seq_QC_Plot_Intergenic.Rd +++ b/man/Seq_QC_Plot_Intergenic.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Intergenic( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Intronic.Rd b/man/Seq_QC_Plot_Intronic.Rd index 67c791658..222593c13 100644 --- a/man/Seq_QC_Plot_Intronic.Rd +++ b/man/Seq_QC_Plot_Intronic.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Intronic( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Reads_in_Cells.Rd b/man/Seq_QC_Plot_Reads_in_Cells.Rd index 38c4cc874..43d6ba7ad 100644 --- a/man/Seq_QC_Plot_Reads_in_Cells.Rd +++ b/man/Seq_QC_Plot_Reads_in_Cells.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Reads_in_Cells( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Reads_per_Cell.Rd b/man/Seq_QC_Plot_Reads_per_Cell.Rd index 5c3bce88d..8a1ef58f0 100644 --- a/man/Seq_QC_Plot_Reads_per_Cell.Rd +++ b/man/Seq_QC_Plot_Reads_per_Cell.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Reads_per_Cell( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Saturation.Rd b/man/Seq_QC_Plot_Saturation.Rd index 0c4cf176a..50bf9a838 100644 --- a/man/Seq_QC_Plot_Saturation.Rd +++ b/man/Seq_QC_Plot_Saturation.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Saturation( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Total_Genes.Rd b/man/Seq_QC_Plot_Total_Genes.Rd index 2f9660fd7..ace6ab111 100644 --- a/man/Seq_QC_Plot_Total_Genes.Rd +++ b/man/Seq_QC_Plot_Total_Genes.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Total_Genes( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} diff --git a/man/Seq_QC_Plot_Transcriptome.Rd b/man/Seq_QC_Plot_Transcriptome.Rd index 3fb5a4777..84b2b5340 100644 --- a/man/Seq_QC_Plot_Transcriptome.Rd +++ b/man/Seq_QC_Plot_Transcriptome.Rd @@ -25,7 +25,7 @@ Seq_QC_Plot_Transcriptome( \item{colors_use}{colors to use for plot if plotting by group. Defaults to RColorBrewer Dark2 palette if less than 8 groups and \code{DiscretePalette_scCustomize(palette = "polychrome")} if more than 8.} -\item{dot_size}{size of the dots plotted if \code{plot_by} is not \code{sample_id} Default is 1.} +\item{dot_size}{size of the dots plotted if \code{group.by} is not \code{sample_id} Default is 1.} \item{x_lab_rotate}{logical. Whether to rotate the axes labels on the x-axis. Default is FALSE.} From 316e4ebb68a1e35466ddb259b787f8ab3c75744e Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 9 Apr 2026 10:20:55 -0400 Subject: [PATCH 083/105] fix check errors --- R/Read_Write_Data.R | 4 +++- man/Read_Velocity.Rd | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/R/Read_Write_Data.R b/R/Read_Write_Data.R index ea0ce0092..ca118da74 100644 --- a/R/Read_Write_Data.R +++ b/R/Read_Write_Data.R @@ -1857,6 +1857,8 @@ ReadVelocity_Multi_Directory <- function( #' #' @param loom_file path and name of loom file to read #' @param data_dir path to data directory containing all loom files to read +#' @param multi_dir logical, whether or not files are contained in sub-directories or in single folder, +#' default is NULL #' @param gene_symbol logical, should row names of returned matrices have gene symbols or accession ID #s, #' default is TRUE (symbols). #' @param sort_type logical, default is FALSE and will return list with 1 sample per entry. Each @@ -1940,7 +1942,7 @@ Read_Velocity <- function( # multi directory if (isTRUE(x = multi_dir)) { - data_list <- ReadVelocity_Multi_Directory(data_dir = data_dir, gene_symbol = gene_symbol, sample_list = sample_list, sample_names = sample_names, shared_suffix = shared_suffix, parallel = parallel, num_cores = num_cores, sort_type = sort_type) + data_list <- ReadVelocity_Multi_Directory(base_path = data_dir, gene_symbol = gene_symbol, sample_list = sample_list, sample_names = sample_names, parallel = parallel, num_cores = num_cores, sort_type = sort_type) return(data_list) } } diff --git a/man/Read_Velocity.Rd b/man/Read_Velocity.Rd index 976e4cc0e..af60490d8 100644 --- a/man/Read_Velocity.Rd +++ b/man/Read_Velocity.Rd @@ -22,6 +22,9 @@ Read_Velocity( \item{data_dir}{path to data directory containing all loom files to read} +\item{multi_dir}{logical, whether or not files are contained in sub-directories or in single folder, +default is NULL} + \item{gene_symbol}{logical, should row names of returned matrices have gene symbols or accession ID #s, default is TRUE (symbols).} From 90fbdfacc9ebc5ee4bde3f263f5aeea652da5085 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 29 Apr 2026 07:48:45 -0400 Subject: [PATCH 084/105] ignore files --- .Rbuildignore | 2 ++ .gitignore | 1 + 2 files changed, 3 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index d5393a8d2..501c998fa 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -16,3 +16,5 @@ vignettes/*.orig$ ^cran-comments\.md$ ^CRAN-SUBMISSION$ ^data-raw$ +^\.positai$ +^\.claude$ diff --git a/.gitignore b/.gitignore index d261c5f93..dbd9ea977 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ README.Rmd index.Rmd figure/ vignettes/articles/assets +.positai From b9ffa3ceef76be8ea96860ac8418b0e07bb283bd Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 29 Apr 2026 07:49:00 -0400 Subject: [PATCH 085/105] Update changelog --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 7b93e8bf9..029251921 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,7 @@ # scCustomize 3.3.0 (2026-XX-XX) ## Added - Added `reorder`, `reorder_decreasing`, and `plot_median` parameters to `Plot_Cells_per_Sample` when grouping by sample. -- Added `Read_Velocity` function to enable reading of velocyto loom output files without needing to install velocyto.R (which currently suffers from significant installation issues unrelated to reading loom files). +- Added `Read_Velocity` function to enable reading of velocyto loom output files without needing to install velocyto.R package (which currently suffers from significant installation issues unrelated to reading loom files). From 2fa23d6107559266959cd4696f914cce943222fe Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 29 Apr 2026 07:57:34 -0400 Subject: [PATCH 086/105] style code --- R/Plotting_Seurat.R | 97 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 6 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index b0bf8d8c9..2f81e7bb7 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -215,22 +215,78 @@ FeaturePlot_scCustom <- function( if (is.null(x = split.by) && isTRUE(x = combine)) { # Keep until Seurat version required is > 5 if (seurat_version >= "5") { - plot <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features, order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, ncol = num_columns, combine = combine, raster.dpi = raster.dpi, label = label, alpha = alpha_exp, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...) & scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, NA), na.value = na_color)) + plot <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + ncol = num_columns, + combine = combine, + raster.dpi = raster.dpi, + label = label, + alpha = alpha_exp, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...) & + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, NA), na.value = na_color)) } else { - plot <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features, order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, ncol = num_columns, combine = combine, raster.dpi = raster.dpi, label = label, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...) & scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, NA), na.value = na_color)) + plot <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + ncol = num_columns, + combine = combine, + raster.dpi = raster.dpi, + label = label, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...) & + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, NA), na.value = na_color)) } } # plot no split & combined if (is.null(x = split.by) && isFALSE(x = combine)) { if (seurat_version >= "5") { - plot_list <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features, order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, ncol = num_columns, combine = combine, raster.dpi = raster.dpi, label = label, alpha = alpha_exp, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...)) + plot_list <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + ncol = num_columns, + combine = combine, + raster.dpi = raster.dpi, + label = label, + alpha = alpha_exp, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...)) plot <- lapply(1:length(x = plot_list), function(i) { plot_list[[i]] <- suppressMessages(plot_list[[i]] + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, NA), na.value = na_color)) }) } else { - plot_list <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features, order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, ncol = num_columns, combine = combine, raster.dpi = raster.dpi, label = label, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...)) + plot_list <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + ncol = num_columns, + combine = combine, + raster.dpi = raster.dpi, + label = label, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...)) plot <- lapply(1:length(x = plot_list), function(i) { plot_list[[i]] <- suppressMessages(plot_list[[i]] + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, NA), na.value = na_color)) @@ -286,9 +342,38 @@ FeaturePlot_scCustom <- function( min_exp_value <- min.cutoff if (seurat_version >= "5") { - plot <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features, order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, raster.dpi = raster.dpi, label = label, alpha = alpha_exp,, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...) & scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = all_found_features)) & RestoreLegend() & theme(axis.title.y.right = element_blank()) + plot <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + raster.dpi = raster.dpi, + label = label, + alpha = alpha_exp,, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...) & + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = all_found_features)) & + RestoreLegend() & + theme(axis.title.y.right = element_blank()) } else { - plot <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features, order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, raster.dpi = raster.dpi, label = label,, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...) & scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = all_found_features)) & RestoreLegend() & theme(axis.title.y.right = element_blank()) + plot <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + raster.dpi = raster.dpi, + label = label, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...) & + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = all_found_features)) & + RestoreLegend() & + theme(axis.title.y.right = element_blank()) } if (isTRUE(x = label_feature_yaxis)) { From 19823b2822983531dd1a72112124f51554ea48ce Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Wed, 29 Apr 2026 08:18:42 -0400 Subject: [PATCH 087/105] styling --- R/Plotting_Seurat.R | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 2f81e7bb7..8b8a29a3c 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -449,9 +449,38 @@ FeaturePlot_scCustom <- function( min_exp_value <- min.cutoff if (seurat_version >= "5") { - single_plot <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features[i], order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, raster.dpi = raster.dpi, label = label, alpha = alpha_exp, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...) & scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = all_found_features[i])) & RestoreLegend() & theme(axis.title.y.right = element_blank()) + single_plot <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features[i], + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + raster.dpi = raster.dpi, + label = label, + alpha = alpha_exp, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...) & + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = all_found_features[i])) & + RestoreLegend() & + theme(axis.title.y.right = element_blank()) } else { - single_plot <- suppressMessages(FeaturePlot(object = seurat_object, features = all_found_features[i], order = order, pt.size = pt.size, reduction = reduction, raster = raster, split.by = split.by, raster.dpi = raster.dpi, label = label, min.cutoff = min.cutoff, max.cutoff = max.cutoff, ...) & scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = features[i])) & RestoreLegend() & theme(axis.title.y.right = element_blank()) + single_plot <- suppressMessages(FeaturePlot(object = seurat_object, + features = all_found_features[i], + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + split.by = split.by, + raster.dpi = raster.dpi, + label = label, + min.cutoff = min.cutoff, + max.cutoff = max.cutoff, + ...) & + scale_color_gradientn(colors = colors_use, limits = c(na_cutoff, max_exp_value), na.value = na_color, name = features[i])) & + RestoreLegend() & + theme(axis.title.y.right = element_blank()) } if (isTRUE(x = label_feature_yaxis)) { From 14f671aaa42eee8274f30f132cae8ac0b057d820 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Thu, 30 Apr 2026 08:39:12 -0400 Subject: [PATCH 088/105] styling --- R/Plotting_Seurat.R | 246 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 221 insertions(+), 25 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 8b8a29a3c..b516f2a4c 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -658,15 +658,54 @@ FeaturePlot_DualAssay <- function( # Change assay and plot raw DefaultAssay(object = seurat_object) <- assay1 - plot_assay1 <- FeaturePlot_scCustom(seurat_object = seurat_object, features = features, layer = layer, colors_use = colors_use, na_color = na_color, na_cutoff = na_cutoff, order = order, pt.size = pt.size, reduction = reduction, raster = raster, alpha_exp = alpha_exp, alpha_na_exp = alpha_na_exp, raster.dpi = raster.dpi, ...) & labs(color = assay1) + plot_assay1 <- FeaturePlot_scCustom(seurat_object = seurat_object, + features = features, + layer = layer, + colors_use = colors_use, + na_color = na_color, + na_cutoff = na_cutoff, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + alpha_exp = alpha_exp, + alpha_na_exp = alpha_na_exp, + raster.dpi = raster.dpi, + ...) & labs(color = assay1) # Change to cell bender and plot DefaultAssay(object = seurat_object) <- assay2 if (is.null(x = colors_use_assay2)) { - plot_assay2 <- FeaturePlot_scCustom(seurat_object = seurat_object, features = features, layer = layer, colors_use = colors_use, na_color = na_color, na_cutoff = na_cutoff, order = order, pt.size = pt.size, reduction = reduction, raster = raster, alpha_exp = alpha_exp, alpha_na_exp = alpha_na_exp, raster.dpi = raster.dpi, ...) & labs(color = assay2) + plot_assay2 <- FeaturePlot_scCustom(seurat_object = seurat_object, + features = features, + layer = layer, + colors_use = colors_use, + na_color = na_color, + na_cutoff = na_cutoff, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + alpha_exp = alpha_exp, + alpha_na_exp = alpha_na_exp, + raster.dpi = raster.dpi, + ...) & labs(color = assay2) } else { - plot_assay2 <- FeaturePlot_scCustom(seurat_object = seurat_object, features = features, layer = layer, colors_use = colors_use_assay2, na_color = na_color, na_cutoff = na_cutoff, order = order, pt.size = pt.size, reduction = reduction, raster = raster, alpha_exp = alpha_exp, alpha_na_exp = alpha_na_exp, raster.dpi = raster.dpi, ...) & labs(color = assay2) + plot_assay2 <- FeaturePlot_scCustom(seurat_object = seurat_object, + features = features, + layer = layer, + colors_use = colors_use_assay2, + na_color = na_color, + na_cutoff = na_cutoff, + order = order, + pt.size = pt.size, + reduction = reduction, + raster = raster, + alpha_exp = alpha_exp, + alpha_na_exp = alpha_na_exp, + raster.dpi = raster.dpi, + ...) & labs(color = assay2) } @@ -833,7 +872,17 @@ VlnPlot_scCustom <- function( } # Plot - plot <- VlnPlot(object = seurat_object, features = all_found_features, cols = colors_use, pt.size = pt.size, idents = idents, group.by = group.by, split.by = split.by, ncol = num_columns, raster = raster, add.noise = add.noise, ...) + plot <- VlnPlot(object = seurat_object, + features = all_found_features, + cols = colors_use, + pt.size = pt.size, + idents = idents, + group.by = group.by, + split.by = split.by, + ncol = num_columns, + raster = raster, + add.noise = add.noise, + ...) # Add add median plot if (isTRUE(x = plot_median) && is.null(x = split.by)) { @@ -1088,9 +1137,13 @@ DotPlot_scCustom <- function( all_found_features <- Feature_PreCheck(object = seurat_object, features = features) # Plot - plot <- suppressMessages(DotPlot(object = seurat_object, features = all_found_features, group.by = group.by, ...) + - scale_color_gradientn(colors = colors_use) + plot <- suppressMessages(DotPlot(object = seurat_object, + features = all_found_features, + group.by = group.by, + ...) + + scale_color_gradientn(colors = colors_use) ) + # Modify plot if (isTRUE(x = remove_axis_titles)) { plot <- plot + @@ -2128,7 +2181,25 @@ DimPlot_scCustom <- function( # Plot if (is.null(x = split.by)) { - plot <- DimPlot(object = seurat_object, cols = colors_use, pt.size = pt.size, reduction = reduction, group.by = group.by, split.by = split.by, shuffle = shuffle, seed = seed, label = label, label.size = label.size, label.color = label.color, repel = repel, raster = raster, raster.dpi = raster.dpi, ncol = num_columns, dims = dims, label.box = label.box, ...) + plot <- DimPlot(object = seurat_object, + cols = colors_use, + pt.size = pt.size, + reduction = reduction, + group.by = group.by, + split.by = split.by, + shuffle = shuffle, + seed = seed, + label = label, + label.size = label.size, + label.color = label.color, + repel = repel, + raster = raster, + raster.dpi = raster.dpi, + ncol = num_columns, + dims = dims, + label.box = label.box, + ...) + if (isTRUE(x = figure_plot)) { # pull axis labels @@ -2168,7 +2239,13 @@ DimPlot_scCustom <- function( } if (isTRUE(x = add_prop_plot)) { - plot_figure <- plot_figure | Overall_Prop_Plot(seurat_object = seurat_object, group.by = group.by, percent = prop_plot_percent, colors_use = prop_colors_use, x_axis_log = prop_plot_x_log, prop_label = prop_plot_label) + plot_layout(widths = c(1, 0.5)) + plot_figure <- plot_figure | Overall_Prop_Plot(seurat_object = seurat_object, + group.by = group.by, + percent = prop_plot_percent, + colors_use = prop_colors_use, + x_axis_log = prop_plot_x_log, + prop_label = prop_plot_label) + + plot_layout(widths = c(1, 0.5)) } return(plot_figure) @@ -2182,7 +2259,13 @@ DimPlot_scCustom <- function( } if (isTRUE(x = add_prop_plot)) { - plot <- plot | Overall_Prop_Plot(seurat_object = seurat_object, group.by = group.by, percent = prop_plot_percent, colors_use = prop_colors_use, x_axis_log = prop_plot_x_log, prop_label = prop_plot_label) + plot_layout(widths = c(1, 0.5)) + plot <- plot | Overall_Prop_Plot(seurat_object = seurat_object, + group.by = group.by, + percent = prop_plot_percent, + colors_use = prop_colors_use, + x_axis_log = prop_plot_x_log, + prop_label = prop_plot_label) + + plot_layout(widths = c(1, 0.5)) } return(plot) @@ -2194,7 +2277,24 @@ DimPlot_scCustom <- function( if (isTRUE(x = split_downsample)) { cli_abort(message = "{.code split_downsample} requires {.split_seurat = FALSE}.") } else { - plot <- DimPlot(object = seurat_object, cols = colors_use, pt.size = pt.size, reduction = reduction, group.by = group.by, split.by = split.by, shuffle = shuffle, seed = seed, label = label, label.size = label.size, label.color = label.color, repel = repel, raster = raster, raster.dpi = raster.dpi, ncol = num_columns, dims = dims, label.box = label.box, ...) + plot <- DimPlot(object = seurat_object, + cols = colors_use, + pt.size = pt.size, + reduction = reduction, + group.by = group.by, + split.by = split.by, + shuffle = shuffle, + seed = seed, + label = label, + label.size = label.size, + label.color = label.color, + repel = repel, + raster = raster, + raster.dpi = raster.dpi, + ncol = num_columns, + dims = dims, + label.box = label.box, + ...) } if (isTRUE(x = figure_plot)) { @@ -2236,7 +2336,13 @@ DimPlot_scCustom <- function( } if (isTRUE(x = add_prop_plot)) { - plot_figure <- plot_figure | Overall_Prop_Plot(seurat_object = seurat_object, group.by = group.by, percent = prop_plot_percent, colors_use = prop_colors_use, x_axis_log = prop_plot_x_log, prop_label = prop_plot_label) + plot_layout(widths = c(1, 0.5)) + plot_figure <- plot_figure | Overall_Prop_Plot(seurat_object = seurat_object, + group.by = group.by, + percent = prop_plot_percent, + colors_use = prop_colors_use, + x_axis_log = prop_plot_x_log, + prop_label = prop_plot_label) + + plot_layout(widths = c(1, 0.5)) } return(plot_figure) @@ -2250,7 +2356,13 @@ DimPlot_scCustom <- function( } if (isTRUE(x = add_prop_plot)) { - plot <- plot | Overall_Prop_Plot(seurat_object = seurat_object, group.by = group.by, percent = prop_plot_percent, colors_use = prop_colors_use, x_axis_log = prop_plot_x_log, prop_label = prop_plot_label) + plot_layout(widths = c(1, 0.5)) + plot <- plot | Overall_Prop_Plot(seurat_object = seurat_object, + group.by = group.by, + percent = prop_plot_percent, + colors_use = prop_colors_use, + x_axis_log = prop_plot_x_log, + prop_label = prop_plot_label) + + plot_layout(widths = c(1, 0.5)) } return(plot) @@ -2324,7 +2436,23 @@ DimPlot_scCustom <- function( # plot plots <- lapply(1:length(x = split_by_list), function(x) { - plot <- DimPlot(object = seurat_object, cells = cell_names[[x]], group.by = group.by, cols = colors_use, reduction = reduction, pt.size = pt.size, raster = raster, raster.dpi = raster.dpi, shuffle = shuffle, seed = seed, label = label, label.size = label.size, label.color = label.color, repel = repel, dims = dims, label.box = label.box, ...) + + plot <- DimPlot(object = seurat_object, + cells = cell_names[[x]], + group.by = group.by, + cols = colors_use, + reduction = reduction, + pt.size = pt.size, + raster = raster, + raster.dpi = raster.dpi, + shuffle = shuffle, + seed = seed, + label = label, + label.size = label.size, + label.color = label.color, + repel = repel, + dims = dims, + label.box = label.box, + ...) + ggtitle(paste(split_by_list[[x]])) + theme(plot.title = element_text(hjust = 0.5), legend.position = "right") + @@ -2362,7 +2490,13 @@ DimPlot_scCustom <- function( } if (isTRUE(x = add_prop_plot)) { - plots <- plots | Overall_Prop_Plot(seurat_object = seurat_object, group.by = group.by, percent = prop_plot_percent, colors_use = prop_colors_use, x_axis_log = prop_plot_x_log, prop_label = prop_plot_label) + plot_layout(widths = c(1, 0.5)) + plots <- plots | Overall_Prop_Plot(seurat_object = seurat_object, + group.by = group.by, + percent = prop_plot_percent, + colors_use = prop_colors_use, + x_axis_log = prop_plot_x_log, + prop_label = prop_plot_label) + + plot_layout(widths = c(1, 0.5)) } return(plots) @@ -2481,7 +2615,15 @@ DimPlot_All_Samples <- function( # Plots plots <- lapply(1:length(x = meta_sample_list), function(x) { - plot <- DimPlot(seurat_object, cells = cell_names[[x]], group.by = meta_data_column, cols = colors_use[[x]], reduction = reduction, pt.size = pt.size, raster = raster, raster.dpi = raster.dpi, ...) + + plot <- DimPlot(object = seurat_object, + cells = cell_names[[x]], + group.by = meta_data_column, + cols = colors_use[[x]], + reduction = reduction, + pt.size = pt.size, + raster = raster, + raster.dpi = raster.dpi, + ...) + ggtitle(paste(meta_sample_list[[x]])) + theme(plot.title = element_text(hjust = 0.5, size = title_size), legend.position = "none") + @@ -2736,7 +2878,20 @@ FeatureScatter_scCustom <- function( # Plot if (is.null(x = split.by)) { - plot <- FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = feature2, cells = cells, cols = colors_use, pt.size = pt.size, group.by = group.by, split.by = split.by, shuffle = shuffle, plot.cor = plot.cor, raster = raster, raster.dpi = raster.dpi, ncol = num_columns, ...) + plot <- FeatureScatter(object = seurat_object, + feature1 = feature1, + feature2 = feature2, + cells = cells, + cols = colors_use, + pt.size = pt.size, + group.by = group.by, + split.by = split.by, + shuffle = shuffle, + plot.cor = plot.cor, + raster = raster, + raster.dpi = raster.dpi, + ncol = num_columns, + ...) # Change title plot <- plot + @@ -2757,7 +2912,19 @@ FeatureScatter_scCustom <- function( } else { # Plot with Seurat splitting if (isTRUE(x = split_seurat)) { - plot <- FeatureScatter(object = seurat_object, feature1 = feature1, feature2 = feature2, cols = colors_use, pt.size = pt.size, group.by = group.by, split.by = split.by, shuffle = shuffle, plot.cor = plot.cor, raster = raster, raster.dpi = raster.dpi, ncol = num_columns, ...) + plot <- FeatureScatter(object = seurat_object, + feature1 = feature1, + feature2 = feature2, + cols = colors_use, + pt.size = pt.size, + group.by = group.by, + split.by = split.by, + shuffle = shuffle, + plot.cor = plot.cor, + raster = raster, + raster.dpi = raster.dpi, + ncol = num_columns, + ...) # Aspect ratio changes if (!is.null(x = aspect_ratio)) { @@ -2770,7 +2937,21 @@ FeatureScatter_scCustom <- function( # return plot return(plot) } else { - plot <- scCustomze_Split_FeatureScatter(seurat_object = seurat_object, feature1 = feature1, feature2 = feature2, split.by = split.by, group.by = group.by, colors_use = colors_use, pt.size = pt.size, aspect_ratio = aspect_ratio, title_size = title_size, num_columns = num_columns, raster = raster, raster.dpi = raster.dpi, ggplot_default_colors = ggplot_default_colors, color_seed = color_seed, ...) + plot <- scCustomze_Split_FeatureScatter(seurat_object = seurat_object, + feature1 = feature1, + feature2 = feature2, + split.by = split.by, + group.by = group.by, + colors_use = colors_use, + pt.size = pt.size, + aspect_ratio = aspect_ratio, + title_size = title_size, + num_columns = num_columns, + raster = raster, + raster.dpi = raster.dpi, + ggplot_default_colors = ggplot_default_colors, + color_seed = color_seed, + ...) return(plot) } @@ -3065,15 +3246,30 @@ SpatialDimPlot_scCustom <- function( } if (isFALSE(x = interactive)) { - plot <- SpatialDimPlot(object = seurat_object, group.by = group.by, images = images, cols = colors_use, crop = crop, label = label, label.size = label.size, label.color = label.color, label.box = label.box, repel = repel, ncol = ncol, combine = combine, alpha = alpha, pt.size.factor = pt.size.factor, image.alpha = image.alpha, stroke = stroke, interactive = interactive, ...) + plot <- SpatialDimPlot(object = seurat_object, + group.by = group.by, + images = images, + cols = colors_use, + crop = crop, + label = label, + label.size = label.size, + label.color = label.color, + label.box = label.box, + repel = repel, + ncol = ncol, + combine = combine, + alpha = alpha, + pt.size.factor = pt.size.factor, + image.alpha = image.alpha, + stroke = stroke, + interactive = interactive, + ...) return(plot) } else { - return(ISpatialDimPlot( - object = seurat_object, - image = images[1], - group.by = group.by, - alpha = alpha - )) + return(ISpatialDimPlot(object = seurat_object, + image = images[1], + group.by = group.by, + alpha = alpha)) } } From 12515cc09181dd010789f8693bd02e55acf4a097 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:30:23 -0400 Subject: [PATCH 089/105] add Elbow_internal function --- R/Plotting_Utilities_Internal.R | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/R/Plotting_Utilities_Internal.R b/R/Plotting_Utilities_Internal.R index e7a14cfe7..058095b55 100644 --- a/R/Plotting_Utilities_Internal.R +++ b/R/Plotting_Utilities_Internal.R @@ -49,6 +49,66 @@ PC_Plotting <- function( } + +#' ElbowPlot alt types for Seurat Version < 5.5.0 +#' +#' Allows for creation of "variance" or "cumulative variance" plots for Seurat version's less +#' than 5.5.0 +#' +#' @param seurat_object name of Seurat object +#' @param ndims The number of dims to plot. Default is NULL and will plot all dims +#' @param reduction The reduction to use, default is "pca" +#' @param plot_type One of \code{"stdev"} (default), \code{"variance"} (per-PC \% variance), or +#' \code{"cumulative_variance"} (running sum of those percentages; equals 100\% at the last +#' stored PC when \code{ndims} spans all of them) +#' +#' @import ggplot2 +#' @importFrom cowplot theme_cowplot +#' +#' @return a ggplot2 plot +#' @noRd +#' + +Elbow_Internal <- function( + seurat_object, + ndims = NULL, + reduction = "pca", + plot_type = NULL +) { + data.use <- Stdev(object = seurat_object, reduction = reduction) + if (length(x = data.use) == 0) { + stop(paste("No standard deviation info stored for", reduction)) + } + if (anyNA(x = data.use)) { + stop("Standard deviations contain NA for reduction ", reduction, call. = FALSE) + } + if (ndims > length(x = data.use)) { + warning("The object only has information for ", length(x = data.use), " dimensions") + ndims <- length(x = data.use) + } + + den <- sum(data.use^2) + if (!is.finite(x = den) || den == 0) { + stop("Cannot compute variance explained: sum of squared standard deviations is not positive for reduction ", reduction, call. = FALSE) + } + pct <- data.use^2 / den * 100 + if (plot_type == "variance") { + y_label <- "Percentage of Variance Explained" + y_data <- pct[1:ndims] + } else { + y_label <- "Cumulative % Variance Explained" + y_data <- cumsum(pct)[1:ndims] + } + + #plot + plot <- ggplot(data = data.frame(dims = 1:ndims, y_data = y_data)) + + geom_point(mapping = aes(x = .data[["dims"]], y = .data[["y_data"]])) + + labs(x = gsub(pattern = '_$', replacement = '', x = Key(object = object[[reduction]])), y = y_label) + + theme_cowplot() + return(plot) +} + + #' Modified Violin Plot #' #' Custom Violin Plot for stacked violin function. From f734ede784b2141ac04c450828dc0c24b7cb6f3a Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:38:22 -0400 Subject: [PATCH 090/105] add plot type parameter --- R/Plotting_Seurat.R | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index b516f2a4c..18cb32c56 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -2969,6 +2969,9 @@ FeatureScatter_scCustom <- function( #' @param seurat_object name of Seurat object #' @param ndims The number of dims to plot. Default is NULL and will plot all dims #' @param reduction The reduction to use, default is "pca" +#' @param plot_type One of \code{"stdev"} (default), \code{"variance"} (per-PC \% variance), or +#' \code{"cumulative_variance"} (running sum of those percentages; equals 100\% at the last +#' stored PC when \code{ndims} spans all of them) #' @param calc_cutoffs logical, whether or not to calculate the cutoffs, default is TRUE. #' @param plot_cutoffs logical, whether to plot the cutoffs as vertical lines on plot, default is TRUE. #' @param line_colors colors for the cutoff lines, default is c("dodgerblue", "firebrick"). @@ -2993,6 +2996,7 @@ ElbowPlot_scCustom <- function( seurat_object, ndims = NULL, reduction = "pca", + plot_type = "stdev", calc_cutoffs = TRUE, plot_cutoffs = TRUE, line_colors = c("dodgerblue", "firebrick"), @@ -3008,6 +3012,11 @@ ElbowPlot_scCustom <- function( cutoff_linewidth <- linewidth } + # check plot type match + if (!plot_type %in% c("stdev", "variance", "cumulative_variance")) { + cli_abort(message = "The {.code plot_type} parameter must be one of following: {.field {glue_collapse_scCustom(input_string = c('stdev', 'variance', 'cumulative_variance'), and = FALSE)}}") + } + # check seurat Is_Seurat(seurat_object = seurat_object) @@ -3055,8 +3064,19 @@ ElbowPlot_scCustom <- function( cutoff_linewidth <- 0.6365 } + # get seurat version + seurat_version <- packageVersion("Seurat") + # Create plot - plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction) + if (seurat_version >= "5.5.0") { + plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) + } + + if (seurat_version < "5.5.0" && plot_type == "stdev") { + plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction) + } else { + plot <- Elbow_Internal(seurat_object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) + } # Add cutoffs to plot if (isTRUE(x = plot_cutoffs)) { From e048ce5c8b8663c60765b23bb936475fdd1de025 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:38:28 -0400 Subject: [PATCH 091/105] Update docs --- man/ElbowPlot_scCustom.Rd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/man/ElbowPlot_scCustom.Rd b/man/ElbowPlot_scCustom.Rd index 24cb194c1..ac01a1a2b 100644 --- a/man/ElbowPlot_scCustom.Rd +++ b/man/ElbowPlot_scCustom.Rd @@ -8,6 +8,7 @@ ElbowPlot_scCustom( seurat_object, ndims = NULL, reduction = "pca", + plot_type = "stdev", calc_cutoffs = TRUE, plot_cutoffs = TRUE, line_colors = c("dodgerblue", "firebrick"), @@ -22,6 +23,10 @@ ElbowPlot_scCustom( \item{reduction}{The reduction to use, default is "pca"} +\item{plot_type}{One of \code{"stdev"} (default), \code{"variance"} (per-PC \\% variance), or +\code{"cumulative_variance"} (running sum of those percentages; equals 100\\% at the last +stored PC when \code{ndims} spans all of them)} + \item{calc_cutoffs}{logical, whether or not to calculate the cutoffs, default is TRUE.} \item{plot_cutoffs}{logical, whether to plot the cutoffs as vertical lines on plot, default is TRUE.} From 3b526cbb8720861b516968862fddb30d0b18fd75 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:38:36 -0400 Subject: [PATCH 092/105] Update changelog --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 029251921..13d503c6d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## Added - Added `reorder`, `reorder_decreasing`, and `plot_median` parameters to `Plot_Cells_per_Sample` when grouping by sample. - Added `Read_Velocity` function to enable reading of velocyto loom output files without needing to install velocyto.R package (which currently suffers from significant installation issues unrelated to reading loom files). +- Added ability to pass `plot_type` in `ElbowPlot_scCustom` for users with Seurat version 5.5.0+. +- Added ability to create "variance" or "cumulative variance" plot types in `ElbowPlot_scCustom` for users with Seurat version below 5.5.0. From de98ad691f6068b94a37dfa39affa57c5496fbea Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:39:07 -0400 Subject: [PATCH 093/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index dde4bc82e..606bb61fd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9013 -Date: 2026-04-09 +Version: 3.2.4.9990 +Date: 2026-05-01 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From 9f42e02ae285339cf298198350e8c2353a686179 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:44:55 -0400 Subject: [PATCH 094/105] fix elbow plot errors --- R/Plotting_Seurat.R | 11 +++++++---- R/Plotting_Utilities_Internal.R | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 18cb32c56..6f0caf90b 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3072,12 +3072,15 @@ ElbowPlot_scCustom <- function( plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) } - if (seurat_version < "5.5.0" && plot_type == "stdev") { - plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction) - } else { - plot <- Elbow_Internal(seurat_object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) + if (seurat_version < "5.5.0") { + if (plot_type == "stdev") { + plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction) + } else { + plot <- Elbow_Internal(seurat_object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) + } } + # Add cutoffs to plot if (isTRUE(x = plot_cutoffs)) { y_max <- get_plot_limits(plot)[["ymax"]] diff --git a/R/Plotting_Utilities_Internal.R b/R/Plotting_Utilities_Internal.R index 058095b55..253795923 100644 --- a/R/Plotting_Utilities_Internal.R +++ b/R/Plotting_Utilities_Internal.R @@ -103,7 +103,7 @@ Elbow_Internal <- function( #plot plot <- ggplot(data = data.frame(dims = 1:ndims, y_data = y_data)) + geom_point(mapping = aes(x = .data[["dims"]], y = .data[["y_data"]])) + - labs(x = gsub(pattern = '_$', replacement = '', x = Key(object = object[[reduction]])), y = y_label) + + labs(x = gsub(pattern = '_$', replacement = '', x = Key(object = seurat_object[[reduction]])), y = y_label) + theme_cowplot() return(plot) } From b10d3e2d1e32667a27dad438825c30be27eb4142 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:48:24 -0400 Subject: [PATCH 095/105] change plotting --- R/Plotting_Seurat.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 6f0caf90b..79973c74d 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3080,7 +3080,6 @@ ElbowPlot_scCustom <- function( } } - # Add cutoffs to plot if (isTRUE(x = plot_cutoffs)) { y_max <- get_plot_limits(plot)[["ymax"]] @@ -3104,7 +3103,7 @@ ElbowPlot_scCustom <- function( annotate("text", x = co1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 0) } else { plot <- plot + - annotate("text", x = 1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 0) + annotate("text", x = 1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = -1) } if (isFALSE(x = co2_missing)) { From ebbb0f1375c9e24e5f6388d2454ef7132d1ee5f3 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:51:40 -0400 Subject: [PATCH 096/105] revert --- R/Plotting_Seurat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 79973c74d..c2a98d88c 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3103,7 +3103,7 @@ ElbowPlot_scCustom <- function( annotate("text", x = co1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 0) } else { plot <- plot + - annotate("text", x = 1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = -1) + annotate("text", x = 1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 0) } if (isFALSE(x = co2_missing)) { From 2e52ac6964ce84eefe8ea6e383167b6e876c4d4e Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:53:41 -0400 Subject: [PATCH 097/105] adjust text label positioning --- R/Plotting_Seurat.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index c2a98d88c..d3ee0871e 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3100,7 +3100,7 @@ ElbowPlot_scCustom <- function( if (isFALSE(x = co1_missing)) { plot <- plot + geom_vline(xintercept = co1, linetype = "dashed", colour = line_colors[1], linewidth = cutoff_linewidth) + - annotate("text", x = co1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 0) + annotate("text", x = co1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 1.01) } else { plot <- plot + annotate("text", x = 1, y = y_max, label = paste0("The first cutoff is: PC", co1), vjust = -0.5, hjust = 0) @@ -3109,7 +3109,7 @@ ElbowPlot_scCustom <- function( if (isFALSE(x = co2_missing)) { plot <- plot + geom_vline(xintercept = co2, linetype = "dashed", colour = line_colors[2], linewidth = cutoff_linewidth) + - annotate("text", x = co2, y = (y_max-0.2), label = paste0("The second cutoff is: PC", co2), vjust = -0.5, hjust = 1) + annotate("text", x = co2, y = (y_max-0.2), label = paste0("The second cutoff is: PC", co2), vjust = -0.5, hjust = 1.01) } else { plot <- plot + annotate("text", x = 1, y = (y_max-0.2), label = paste0("The second cutoff is: PC", co2), vjust = -0.5, hjust = 0) From 7cdc6b2d021fcafb0fb251f567cbf1812e88505f Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 08:57:10 -0400 Subject: [PATCH 098/105] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 606bb61fd..d5d0ceeb4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9990 +Version: 3.2.4.9991 Date: 2026-05-01 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), From e5d82a77074beea238c286924517d8db2a53b5f2 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 1 May 2026 09:04:57 -0400 Subject: [PATCH 099/105] style --- R/Plotting_Seurat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index d3ee0871e..8ad2e7d85 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3046,7 +3046,7 @@ ElbowPlot_scCustom <- function( # Get cut-offs co1 <- which(cumPct > 90 & pctVar < 5)[1] - co2 <- sort(which((pctVar[1:length(pctVar) - 1] - pctVar[2:length(pctVar)]) > 0.1), decreasing = T)[1] + 1 + co2 <- sort(which((pctVar[1:length(pctVar) - 1] - pctVar[2:length(pctVar)]) > 0.1), decreasing = TRUE)[1] + 1 } From cdd2611fb67f761b90899619c3f4038be405449c Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 5 May 2026 11:13:29 -0400 Subject: [PATCH 100/105] style --- R/Plotting_Seurat.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 8ad2e7d85..957c16ce7 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3042,11 +3042,11 @@ ElbowPlot_scCustom <- function( pctVar <- seurat_object[[reduction]]@stdev / sum(seurat_object[[reduction]]@stdev) * 100 # calculate cumulative percents - cumPct <- cumsum(pctVar) + cumPct <- cumsum(x = pctVar) # Get cut-offs co1 <- which(cumPct > 90 & pctVar < 5)[1] - co2 <- sort(which((pctVar[1:length(pctVar) - 1] - pctVar[2:length(pctVar)]) > 0.1), decreasing = TRUE)[1] + 1 + co2 <- sort(which((pctVar[1:length(x = pctVar) - 1] - pctVar[2:length(x = pctVar)]) > 0.1), decreasing = TRUE)[1] + 1 } From b29f747543cff5b0ec22d581e96e59a5277faa2b Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 5 May 2026 11:17:03 -0400 Subject: [PATCH 101/105] styling --- R/Plotting_Seurat.R | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 957c16ce7..35644d70b 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3022,9 +3022,9 @@ ElbowPlot_scCustom <- function( # set dims if NULL if (is.null(x = ndims)) { - ndims <- ncol(x = Embeddings(seurat_object, reduction = reduction)) + ndims <- ncol(x = Embeddings(object = seurat_object, reduction = reduction)) } else { - if (ndims > ncol(x = Embeddings(seurat_object, reduction = reduction))) { + if (ndims > ncol(x = Embeddings(object = seurat_object, reduction = reduction))) { cli_warn(message = c("Number of dimensions supplied ({.field {ndims}}) is greater than total dims for reduction {.val {reduction}} ({.field {ncol(x = Embeddings(seurat_object, reduction = reduction))}}).", "i" = "Setting {.code {ndims}} to max value of {.field {ncol(x = Embeddings(seurat_object, reduction = reduction))}}.")) } @@ -3069,20 +3069,20 @@ ElbowPlot_scCustom <- function( # Create plot if (seurat_version >= "5.5.0") { - plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) + plot <- ElbowPlot(object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) } if (seurat_version < "5.5.0") { if (plot_type == "stdev") { - plot <- ElbowPlot(seurat_object, ndims = ndims, reduction = reduction) + plot <- ElbowPlot(object = seurat_object, ndims = ndims, reduction = reduction) } else { - plot <- Elbow_Internal(seurat_object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) + plot <- Elbow_Internal(seurat_object = seurat_object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) } } # Add cutoffs to plot if (isTRUE(x = plot_cutoffs)) { - y_max <- get_plot_limits(plot)[["ymax"]] + y_max <- get_plot_limits(plot = plot)[["ymax"]] # Adjust plot if ndims is less than cutoff values if (co1 > ndims) { From 36de0626d8b9b1fac95a901f9ac5aba3e501abad Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 5 May 2026 11:18:01 -0400 Subject: [PATCH 102/105] bump version and date --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d5d0ceeb4..e5246fc9f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,8 +2,8 @@ Package: scCustomize Type: Package Title: Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing Description: Collection of functions created and/or curated to aid in the visualization and analysis of single-cell data using 'R'. 'scCustomize' aims to provide 1) Customized visualizations for aid in ease of use and to create more aesthetic and functional visuals. 2) Improve speed/reproducibility of common tasks/pieces of code in scRNA-seq analysis with a single or group of functions. For citation please use: Marsh SE (2021) "Custom Visualizations & Functions for Streamlined Analyses of Single Cell Sequencing" RRID:SCR_024675. -Version: 3.2.4.9991 -Date: 2026-05-01 +Version: 3.3.0 +Date: 2026-05-05 Authors@R: c( person(given = "Samuel", family = "Marsh", email = "sccustomize@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3012-6945")), person(given = "Ming", family = "Tang", role = c("ctb"), email = "tangming2005@gmail.com"), From 8c6e805a42a3d9a9f33b8c45d3a989a1dd4583b2 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Tue, 5 May 2026 11:19:07 -0400 Subject: [PATCH 103/105] fix error --- R/Plotting_Seurat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/Plotting_Seurat.R b/R/Plotting_Seurat.R index 35644d70b..e2ea74658 100644 --- a/R/Plotting_Seurat.R +++ b/R/Plotting_Seurat.R @@ -3076,7 +3076,7 @@ ElbowPlot_scCustom <- function( if (plot_type == "stdev") { plot <- ElbowPlot(object = seurat_object, ndims = ndims, reduction = reduction) } else { - plot <- Elbow_Internal(seurat_object = seurat_object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) + plot <- Elbow_Internal(seurat_object = seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type) } } From e5b7dd4e8859b9bf7aea7841cb5aeaaba3f94043 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 8 May 2026 08:35:45 -0400 Subject: [PATCH 104/105] Update cran comments --- cran-comments.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index d1f184790..d30636469 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,5 +1,5 @@ ## Update -This is minor patch to version 3.2.4. Contains critical bug fix accidentally introduced in 3.2.3. See News.md for full changelog. +This is minor update to version 3.3.0. Contains a couple new features and bug fixes. See News.md for full changelog. @@ -27,4 +27,10 @@ This is minor patch to version 3.2.4. Contains critical bug fix accidentally in NO errors are found when checking locally on macos platform using R 4.4.0 and none are found in GitHub Actions check on linux or windows platforms. I believe to be error in GitHub Actions workflow and I have therefore refrained from adding `dontrun` to examples that run fine on other platforms. This was also the case with v2.0.0, v2.0.1, 2.1.0, 2.1.2 which passed macos checks on CRAN, - furthering it is likely a GitHub Actions issue. + furthering it is likely a GitHub Actions issue. + +2. Users may receive following warning if installing with Seurat package version less than 5.5.0: `ElbowPlot_scCustom: possible error in ElbowPlot(seurat_object, ndims = ndims, reduction = reduction, plot_type = plot_type): unused argument (plot_type = plot_type)`. + - This is accounted for in the function's internal code with conditional statement to use internal package functions to avoid any error + messages. + + From 111a039bc3a44bf082e7c3f16e8846d2173ea1f5 Mon Sep 17 00:00:00 2001 From: Samuel Marsh <38284410+samuel-marsh@users.noreply.github.com> Date: Fri, 8 May 2026 08:38:11 -0400 Subject: [PATCH 105/105] cran submission --- CRAN-SUBMISSION | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index ce45ae797..2eae94dd1 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ -Version: 3.2.4 -Date: 2025-12-10 20:09:21 UTC -SHA: 7b188bbf6ad0e914c9d1c7d7e13e30e1857c6a69 +Version: 3.3.0 +Date: 2026-05-08 12:37:58 UTC +SHA: e5b7dd4e8859b9bf7aea7841cb5aeaaba3f94043