Skip to content

Commit 49e35b5

Browse files
authored
Merge pull request #211 from satijalab/develop
v0.4.3
2 parents bc8d121 + 4ab7547 commit 49e35b5

24 files changed

+299
-330
lines changed

DESCRIPTION

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: sctransform
22
Type: Package
33
Title: Variance Stabilizing Transformations for Single Cell UMI Data
4-
Version: 0.4.2
5-
Date: 2025-04-30
4+
Version: 0.4.3
5+
Date: 2025-12-25
66
Authors@R: c(
77
person(given = "Christoph", family = "Hafemeister", email = "christoph.hafemeister@nyu.edu", role = "aut", comment = c(ORCID = "0000-0001-6365-8254")),
88
person(given = "Saket", family = "Choudhary", email = "saketc@iitb.ac.in", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-5202-7633")),
@@ -31,6 +31,7 @@ Imports:
3131
methods,
3232
future.apply,
3333
future,
34+
parallelly,
3435
ggplot2,
3536
reshape2,
3637
rlang,
@@ -42,4 +43,4 @@ Suggests:
4243
knitr
4344
Enhances:
4445
glmGamPoi
45-
RoxygenNote: 7.3.2
46+
RoxygenNote: 7.3.3

NEWS.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# News
22
All notable changes will be documented in this file.
33

4+
## [0.4.3] - 2025-12-25
5+
6+
- Fixed imports for supportsMulticore() to use parallely [#209](https://github.com/satijalab/sctransform/issues/209)
7+
- Switch to future_apply [#210](https://github.com/satijalab/sctransform/issues/210)
8+
- Remove deprecated argument 'verbose' in favor of 'verbosity'
9+
- Added helper functions for progress bar and parsing formulas
10+
411
## [0.4.2] - 2025-04-30
512

613
### Fixed
@@ -41,7 +48,7 @@ All notable changes will be documented in this file.
4148
## [0.3.4] - 2022-08-19
4249

4350
### Added
44-
- Add `make.sparse` to handle `dgCMatrix` coercsions
51+
- Add `make.sparse` to handle `dgCMatrix` coercions
4552

4653
### Fixed
4754
- Convert bitwise operators to boolean operators in utils.cpp

R/data.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#' There are 914 rows (genes) and 283 columns (cells). This is a downsampled
77
#' version of a 3K PBMC dataset available from 10x Genomics.
88
#'
9-
#' @source \url{https://support.10xgenomics.com/single-cell-gene-expression/datasets/1.1.0/pbmc3k}
9+
#' @source \url{https://www.10xgenomics.com/datasets/3-k-pbm-cs-from-a-healthy-donor-1-standard-1-1-0}
1010
"pbmc"
1111

1212
#' Transformation functions for umify

R/denoise.R

Lines changed: 19 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ smooth_via_pca <- function(x, elbow_th = 0.025, dims_use = NULL, max_pc = 100, d
6666
#' @param do_pos Set negative values in the result to zero
6767
#' @param scale_factor Replace all values of UMI in the regression model by this value. Default is NA
6868
#' which uses median of total UMI as the latent factor.
69-
#' @param verbosity An integer specifying whether to show only messages (1), messages and progress bars (2) or nothing (0) while the function is running; default is 2
70-
#' @param verbose Deprecated; use verbosity instead
71-
#' @param show_progress Deprecated; use verbosity instead
69+
#' @param verbosity An integer specifying the verbosity level: 0 (silent, no messages), 1 (show messages only), or 2 (show messages and progress bars); default is 2
7270
#'
7371
#' @return Corrected data as UMI counts
7472
#'
@@ -81,22 +79,7 @@ smooth_via_pca <- function(x, elbow_th = 0.025, dims_use = NULL, max_pc = 100, d
8179
#' }
8280
#'
8381
correct <- function(x, data = 'y', cell_attr = x$cell_attr, as_is = FALSE,
84-
do_round = TRUE, do_pos = TRUE, scale_factor=NA, verbosity = 2,
85-
verbose = NULL, show_progress = NULL) {
86-
# Take care of deprecated arguments
87-
if (!is.null(verbose)) {
88-
warning("The 'verbose' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
89-
verbosity <- as.numeric(verbose)
90-
}
91-
if (!is.null(show_progress)) {
92-
warning("The 'show_progress' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
93-
if (show_progress) {
94-
verbosity <- 2
95-
} else {
96-
verbosity <- min(verbosity, 1)
97-
}
98-
}
99-
82+
do_round = TRUE, do_pos = TRUE, scale_factor=NA, verbosity = 2) {
10083
if (is.character(data)) {
10184
data <- x[[data]]
10285
}
@@ -121,18 +104,17 @@ correct <- function(x, data = 'y', cell_attr = x$cell_attr, as_is = FALSE,
121104
}
122105
cell_attr[, "log_umi"] <- log10(scale_factor)
123106
}
124-
regressor_data <- model.matrix(as.formula(gsub('^y', '', x$model_str)), cell_attr)
107+
regressor_data <- model.matrix(get_model_formula(x$model_str), cell_attr)
125108

126109
genes <- rownames(data)
127110
bin_size <- x$arguments$bin_size
128-
bin_ind <- ceiling(x = 1:length(x = genes) / bin_size)
129-
max_bin <- max(bin_ind)
130111
if (verbosity > 0) {
131112
message('Computing corrected count matrix for ', length(genes), ' genes')
132113
}
133-
if (verbosity > 1) {
134-
pb <- txtProgressBar(min = 0, max = max_bin, style = 3)
135-
}
114+
pb_setup <- setup_progress_bar(length(genes), bin_size, verbosity)
115+
bin_ind <- pb_setup$bin_ind
116+
max_bin <- pb_setup$max_bin
117+
pb <- pb_setup$pb
136118
corrected_data <- matrix(NA_real_, length(genes), nrow(regressor_data), dimnames = list(genes, rownames(regressor_data)))
137119
for (i in 1:max_bin) {
138120
genes_bin <- genes[bin_ind == i]
@@ -142,13 +124,9 @@ correct <- function(x, data = 'y', cell_attr = x$cell_attr, as_is = FALSE,
142124
mu <- exp(tcrossprod(coefs, regressor_data))
143125
variance <- mu + mu^2 / theta
144126
corrected_data[genes_bin, ] <- mu + pearson_residual * sqrt(variance)
145-
if (verbosity > 1) {
146-
setTxtProgressBar(pb, i)
147-
}
148-
}
149-
if (verbosity > 1) {
150-
close(pb)
127+
update_progress_bar(pb, i, verbosity)
151128
}
129+
close_progress_bar(pb, verbosity)
152130

153131
if (do_round) {
154132
corrected_data <- round(corrected_data, 0)
@@ -170,9 +148,7 @@ correct <- function(x, data = 'y', cell_attr = x$cell_attr, as_is = FALSE,
170148
#' @param cell_attr Provide cell meta data holding latent data info
171149
#' @param scale_factor Replace all values of UMI in the regression model by this value. Default is NA
172150
#' which uses median of total UMI as the latent factor.
173-
#' @param verbosity An integer specifying whether to show only messages (1), messages and progress bars (2) or nothing (0) while the function is running; default is 2
174-
#' @param verbose Deprecated; use verbosity instead
175-
#' @param show_progress Deprecated; use verbosity instead
151+
#' @param verbosity An integer specifying the verbosity level: 0 (silent, no messages), 1 (show messages only), or 2 (show messages and progress bars); default is 2
176152
#'
177153
#' @return Corrected data as UMI counts
178154
#'
@@ -186,23 +162,8 @@ correct <- function(x, data = 'y', cell_attr = x$cell_attr, as_is = FALSE,
186162
#' umi_corrected <- correct_counts(vst_out, pbmc)
187163
#' }
188164
#'
189-
correct_counts <- function(x, umi, cell_attr = x$cell_attr, scale_factor = NA, verbosity = 2,
190-
verbose = NULL, show_progress = NULL) {
191-
# Take care of deprecated arguments
192-
if (!is.null(verbose)) {
193-
warning("The 'verbose' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
194-
verbosity <- as.numeric(verbose)
195-
}
196-
if (!is.null(show_progress)) {
197-
warning("The 'show_progress' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
198-
if (show_progress) {
199-
verbosity <- 2
200-
} else {
201-
verbosity <- min(verbosity, 1)
202-
}
203-
}
204-
205-
regressor_data_orig <- model.matrix(as.formula(gsub('^y', '', x$model_str)), cell_attr)
165+
correct_counts <- function(x, umi, cell_attr = x$cell_attr, scale_factor = NA, verbosity = 2) {
166+
regressor_data_orig <- model.matrix(get_model_formula(x$model_str), cell_attr)
206167
# when correcting, set all latent variables to median values
207168
cell_attr[, x$arguments$latent_var] <- apply(cell_attr[, x$arguments$latent_var, drop=FALSE], 2, function(x) rep(median(x), length(x)))
208169

@@ -215,18 +176,17 @@ correct_counts <- function(x, umi, cell_attr = x$cell_attr, scale_factor = NA, v
215176
}
216177
cell_attr[, "log_umi"] <- log10(scale_factor)
217178
}
218-
regressor_data <- model.matrix(as.formula(gsub('^y', '', x$model_str)), cell_attr)
179+
regressor_data <- model.matrix(get_model_formula(x$model_str), cell_attr)
219180

220181
genes <- rownames(umi)[rownames(umi) %in% rownames(x$model_pars_fit)]
221182
bin_size <- x$arguments$bin_size
222-
bin_ind <- ceiling(x = 1:length(x = genes) / bin_size)
223-
max_bin <- max(bin_ind)
224183
if (verbosity > 0) {
225184
message('Computing corrected UMI count matrix')
226185
}
227-
if (verbosity > 1) {
228-
pb <- txtProgressBar(min = 0, max = max_bin, style = 3)
229-
}
186+
pb_setup <- setup_progress_bar(length(genes), bin_size, verbosity)
187+
bin_ind <- pb_setup$bin_ind
188+
max_bin <- pb_setup$max_bin
189+
pb <- pb_setup$pb
230190
#corrected_data <- matrix(NA_real_, length(genes), nrow(regressor_data), dimnames = list(genes, rownames(regressor_data)))
231191
corrected_data <- list()
232192
for (i in 1:max_bin) {
@@ -245,13 +205,9 @@ correct_counts <- function(x, umi, cell_attr = x$cell_attr, scale_factor = NA, v
245205
y.res <- round(y.res, 0)
246206
y.res[y.res < 0] <- 0
247207
corrected_data[[length(corrected_data) + 1]] <- make.sparse(mat = y.res)
248-
if (verbosity > 1) {
249-
setTxtProgressBar(pb, i)
250-
}
251-
}
252-
if (verbosity > 1) {
253-
close(pb)
208+
update_progress_bar(pb, i, verbosity)
254209
}
210+
close_progress_bar(pb, verbosity)
255211
corrected_data <- do.call(what = rbind, args = corrected_data)
256212

257213
return(corrected_data)

R/differential_expression.R

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@
88
#' @param method Either 'LRT' for likelihood ratio test, or 't_test' for t-test
99
#' @param bin_size Number of genes that are processed between updates of progress bar
1010
#' @param cell_attr Data frame of cell meta data
11-
#' @param y Only used if methtod = 't_test', this is the residual matrix; default is x$y
11+
#' @param y Only used if method = 't_test', this is the residual matrix; default is x$y
1212
#' @param min_cells A gene has to be detected in at least this many cells in at least one of the groups being compared to be tested
1313
#' @param weighted Balance the groups by using the appropriate weights
1414
#' @param randomize Boolean indicating whether to shuffle group labels - only set to TRUE when testing methods
15-
#' @param verbosity An integer specifying whether to show only messages (1), messages and progress bars (2) or nothing (0) while the function is running; default is 2
16-
#' @param verbose Deprecated; use verbosity instead
17-
#' @param show_progress Deprecated; use verbosity instead
15+
#' @param verbosity An integer specifying the verbosity level: 0 (silent, no messages), 1 (show messages only), or 2 (show messages and progress bars); default is 2
1816
#'
1917
#' @return Data frame of results
2018
#'
@@ -25,27 +23,7 @@
2523
#'
2624
compare_expression <- function(x, umi, group, val1, val2, method = 'LRT', bin_size = 256,
2725
cell_attr = x$cell_attr, y = x$y, min_cells = 5,
28-
weighted = TRUE, randomize = FALSE, verbosity = 2,
29-
verbose = NULL, show_progress = NULL) {
30-
if (nbrOfWorkers() == 1){
31-
my.lapply <- function(X, FUN, future.seed = TRUE) lapply(X, FUN)
32-
} else {
33-
my.lapply <- future_lapply
34-
}
35-
# Take care of deprecated arguments
36-
if (!is.null(verbose)) {
37-
warning("The 'verbose' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
38-
verbosity <- as.numeric(verbose)
39-
}
40-
if (!is.null(show_progress)) {
41-
warning("The 'show_progress' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
42-
if (show_progress) {
43-
verbosity <- 2
44-
} else {
45-
verbosity <- min(verbosity, 1)
46-
}
47-
}
48-
26+
weighted = TRUE, randomize = FALSE, verbosity = 2) {
4927
if (! method %in% c('LRT', 'LRT_free', 'LRT_reg', 't_test')) {
5028
stop('method needs to be either \'LRT\', \'LRT_free\', \'LRT_reg\' or \'t_test\'')
5129
}
@@ -99,16 +77,16 @@ compare_expression <- function(x, umi, group, val1, val2, method = 'LRT', bin_si
9977
for (i in 1:max_bin) {
10078
genes_bin <- genes[bin_ind == i]
10179
if (method == 't_test') {
102-
bin_res <- my.lapply(
103-
X = genes_bin,
80+
bin_res <- future_lapply(
81+
X = genes_bin,
10482
FUN = function(gene) {model_comparison_ttest(y[gene, use_cells], group)},
10583
future.seed = TRUE)
10684
}
10785
if (method == 'LRT') {
10886
mu <- x$model_pars_fit[genes_bin, -1, drop=FALSE] %*% t(regressor_data) # in log space
10987
y <- as.matrix(umi[genes_bin, use_cells])
110-
bin_res <- my.lapply(
111-
X = genes_bin,
88+
bin_res <- future_lapply(
89+
X = genes_bin,
11290
FUN = function(gene) {
11391
model_comparison_lrt(y[gene, ], mu[gene, ], x$model_pars_fit[gene, 'theta'], group, weights)},
11492
future.seed = TRUE)
@@ -181,11 +159,11 @@ compare_expression <- function(x, umi, group, val1, val2, method = 'LRT', bin_si
181159
y_theta[o] <- 10 ^ ksmooth(x = x$genes_log_mean_step1, y = log10(x$model_pars[, 'theta']),
182160
x.points = y_log_mean, bandwidth = bw, kernel='normal')$y
183161
names(y_theta) <- genes_bin
184-
bin_res <- my.lapply(
185-
X = genes_bin,
162+
bin_res <- future_lapply(
163+
X = genes_bin,
186164
FUN = function(gene) {
187165
return(model_comparison_lrt_free3(gene, y[gene, ], y_theta[gene], x$model_str, cell_attr, group, weights, randomize))
188-
},
166+
},
189167
future.seed = TRUE)
190168
}
191169
res[[i]] <- do.call(rbind, bin_res)

R/plotting.R

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
#' @param xaxis Variable to plot on X axis; default is "gmean"
55
#' @param show_theta Whether to show the theta parameter; default is FALSE (only the overdispersion factor is shown)
66
#' @param show_var Whether to show the average model variance; default is FALSE
7-
#' @param verbosity An integer specifying whether to show only messages (1), messages and progress bars (2) or nothing (0) while the function is running; default is 2
8-
#' @param verbose Deprecated; use verbosity instead
9-
#' @param show_progress Deprecated; use verbosity instead
7+
#' @param verbosity An integer specifying the verbosity level: 0 (silent, no messages), 1 (show messages only), or 2 (show messages and progress bars); default is 2
108
#'
119
#' @return A ggplot object
1210
#'
@@ -22,21 +20,7 @@
2220
#' }
2321
#'
2422
plot_model_pars <- function(vst_out, xaxis="gmean", show_theta = FALSE, show_var = FALSE,
25-
verbosity = 2, verbose = NULL, show_progress = NULL) {
26-
# Take care of deprecated arguments
27-
if (!is.null(verbose)) {
28-
warning("The 'verbose' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
29-
verbosity <- as.numeric(verbose)
30-
}
31-
if (!is.null(show_progress)) {
32-
warning("The 'show_progress' argument is deprecated as of v0.3. Use 'verbosity' instead. (in sctransform::vst)", immediate. = TRUE, call. = FALSE)
33-
if (show_progress) {
34-
verbosity <- 2
35-
} else {
36-
verbosity <- min(verbosity, 1)
37-
}
38-
}
39-
23+
verbosity = 2) {
4024
if (! 'gmean' %in% names(vst_out$gene_attr)) {
4125
stop('vst_out must contain a data frame named gene_attr with a column named gmean (perhaps call vst with return_gene_attr = TRUE)')
4226
}

0 commit comments

Comments
 (0)