Skip to content

Commit ac2201e

Browse files
Add max_size parameter to fast_ssgsea
Gene sets with more than max_size genes will not be analyzed. Decreasing max_size will decrease the overall runtime proportionally, though this is less noticeable when the number of permutations is small.
1 parent a406446 commit ac2201e

8 files changed

Lines changed: 57 additions & 48 deletions

File tree

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: fast.ssgsea
22
Type: Package
33
Title: Fast Single-Sample Gene Set Enrichment Analysis (ssGSEA)
4-
Version: 0.1.0.9020
4+
Version: 0.1.0.9021
55
Date: 2025-11-11
66
Authors@R:
77
person(given = "Tyler", family = "Sagendorf",

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Greatly reduced runtime of permutation tests.
55
- Added `read_gmt` function, which reads a list of gene sets from a Gene Matrix Transposed (GMT) file.
66
- Added `alternative` parameter to `fast_ssgsea` to perform one-sided hypothesis tests.
7+
- Added `max_size` parameter to `fast_ssgsea` to limit the maximum size of sets that will be tested.
78
- Updated runtime data and figures in simulation/.
89

910

R/fast_ssgsea.R

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#' \emph{all} columns of \code{X}. The default value of 2 is the minimum
2727
#' possible set size required for testing, though higher values tend to
2828
#' produce more robust results.
29+
#' @param max_size integer or \code{Inf}; the maximum set size. Recommended to
30+
#' set this to 500.
2931
#' @param sort logical; should the results for each column of \code{X} be sorted
3032
#' by p-value? Default is \code{TRUE}.
3133
#' @param seed integer or \code{NULL}; passed to \code{\link[base]{set.seed}}.
@@ -117,6 +119,7 @@ fast_ssgsea <- function(X,
117119
batch_size = 1000L,
118120
adjust_globally = FALSE,
119121
min_size = 2L,
122+
max_size = Inf,
120123
sort = TRUE,
121124
seed = NULL,
122125
alternative = c("two.sided", "less", "greater")) {
@@ -130,6 +133,7 @@ fast_ssgsea <- function(X,
130133
batch_size = batch_size,
131134
adjust_globally = adjust_globally,
132135
min_size = min_size,
136+
max_size = max_size,
133137
sort = sort,
134138
seed = seed,
135139
n_genes = ncol(X)
@@ -171,10 +175,11 @@ fast_ssgsea <- function(X,
171175
Z_prime = Z[, rownames(A), drop = FALSE], # Z'
172176
A = A,
173177
A_d = A_d,
174-
min_size = min_size
178+
min_size = min_size,
179+
max_size = max_size
175180
)
176181

177-
# Extract list components: M, W, M_d, W_d, A (optional), A_d (optional)
182+
# Extract list components: M, W, M_d, W_d, A, A_d, max_size
178183
list2env(x = M_list, envir = environment())
179184

180185
# Enrichment score matrices with samples as rows and gene sets as columns

R/utils.R

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
batch_size = 1000L,
5353
adjust_globally = FALSE,
5454
min_size = 2L,
55+
max_size = Inf,
5556
sort = TRUE,
5657
seed = NULL,
5758
n_genes) {
@@ -103,6 +104,16 @@
103104
stop("`min_size` must be >= 2 and < nrow(X).")
104105
}
105106

107+
if (
108+
!(is.infinite(max_size) || is.vector(max_size, mode = "numeric")) ||
109+
length(max_size) != 1L ||
110+
is.na(max_size) ||
111+
max_size < min_size ||
112+
(!is.infinite(max_size) && max_size %% 1 != 0)
113+
) {
114+
stop("`max_size` must be Inf or an integer >= min_size.")
115+
}
116+
106117
if (
107118
!is.vector(adjust_globally, mode = "logical") ||
108119
length(adjust_globally) != 1L ||
@@ -319,6 +330,8 @@
319330
#' Indicates which genes are expected to be down-regulated in each sample.
320331
#' @param min_size integer; minimum gene set size required for testing. Default
321332
#' is 2.
333+
#' @param max_size integer or \code{Inf}; size of the largest gene set that will
334+
#' be tested.
322335
#'
323336
#' @returns A named list with the following components:
324337
#'
@@ -350,39 +363,44 @@
350363
Z_prime,
351364
A,
352365
A_d = NULL,
353-
min_size = 2L) {
366+
min_size = 2L,
367+
max_size = Inf) {
354368
# Matrix with samples as rows and genes as columns. Elements are the number
355369
# of genes in each set with nonmissing values in the sample.
356370
M <- .Cpp_matmult_sparse(Z_prime, A) # Z'A
357371
M[M < min_size] <- 0L
358372

359-
# Identify sets with too few or too many genes in at least one sample
360-
extreme_sets_M <- apply(M, 2L, function(m_j) {
361-
any(m_j == 0L | m_j == n)
362-
})
373+
# It is extremely unlikely that a gene set would consist of all genes with
374+
# nonmissing values, but the set size limit will be 1 less than the smallest
375+
# number of nonmissing values.
376+
max_size <- max(min_size, min(max_size, min(n) - 1L))
363377

364378
if (!is.null(A_d)) {
365379
M_d <- .Cpp_matmult_sparse(Z_prime, A_d)
366380
M_d[M_d < min_size] <- 0L
367381

368-
extreme_sets_M_d <- apply(M_d, 2L, function(m_d_j) {
369-
any(m_d_j == 0L | m_d_j == n)
370-
})
382+
small_sets_M <- apply(M == 0L, 2L, any)
383+
small_sets_M_d <- apply(M_d == 0L, 2L, any)
384+
385+
# Combined set size exceeds max_size
386+
large_sets <- apply((M + M_d) > max_size, 2L, any)
371387

372-
extreme_sets <- which(extreme_sets_M & extreme_sets_M_d)
388+
# Too small in both up and down portions or too large overall
389+
extreme_sets <- which((small_sets_M & small_sets_M_d) | large_sets)
373390
} else {
374391
M_d <- W_d <- NULL
375392

376-
extreme_sets <- which(extreme_sets_M)
393+
extreme_sets <- which(
394+
apply(M == 0 | M > max_size, 2L, any)
395+
)
377396
}
378397

379398
if (length(extreme_sets)) {
380399
# If any sets are extreme, check if they are all extreme.
381400
if (length(extreme_sets) == ncol(A)) {
382401
stop(
383-
"All sets in `gene_sets` contain fewer than `min_size` genes ",
384-
"with nonmissing values or consist of all genes with nonmissing ",
385-
"values in at least one sample."
402+
"All sets in `gene_sets` contain fewer than `min_size` genes or more ",
403+
"than `max_size` genes with nonmissing values."
386404
)
387405
}
388406

README.Rmd

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ system.time({
107107
)
108108
})
109109
110-
str(res)
111-
112110
head(res, 10L)
113111
```
114112

README.md

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,7 @@ system.time({
130130
```
131131

132132
## user system elapsed
133-
## 5.919 0.906 6.403
134-
135-
``` r
136-
str(res)
137-
```
138-
139-
## 'data.frame': 20000 obs. of 9 variables:
140-
## $ sample : Factor w/ 1 level "sample1": 1 1 1 1 1 1 1 1 1 1 ...
141-
## $ set : chr "set18791" "set16136" "set19084" "set2830" ...
142-
## $ set_size : int 138 801 841 163 706 749 450 87 161 761 ...
143-
## $ ES : num -1866 709 698 1584 759 ...
144-
## $ NES : num -5.3 4.65 4.68 4.76 4.68 ...
145-
## $ n_same_sign : int 49042 52788 52782 50951 52785 47193 47813 50722 48979 47243 ...
146-
## $ n_as_extreme: int 1 8 8 9 11 10 13 14 18 20 ...
147-
## $ p_value : num 4.08e-05 1.70e-04 1.71e-04 1.96e-04 2.27e-04 ...
148-
## $ adj_p_value : num 0.739 0.739 0.739 0.739 0.739 ...
133+
## 4.925 0.901 5.370
149134

150135
``` r
151136
head(res, 10L)
@@ -192,16 +177,16 @@ print(sessionInfo(), locale = FALSE, tzone = FALSE)
192177
## [1] stats graphics grDevices utils datasets methods base
193178
##
194179
## other attached packages:
195-
## [1] fast.ssgsea_0.1.0.9018
180+
## [1] dqrng_0.4.1 fast.ssgsea_0.1.0.9021
196181
##
197182
## loaded via a namespace (and not attached):
198-
## [1] dqrng_0.4.1 digest_0.6.37 RcppArmadillo_15.0.2-2
199-
## [4] fastmap_1.2.0 xfun_0.53 Matrix_1.7-4
200-
## [7] lattice_0.22-7 knitr_1.50 htmltools_0.5.8.1
201-
## [10] rmarkdown_2.29 cli_3.6.5 grid_4.5.2
202-
## [13] data.table_1.17.8 compiler_4.5.2 rstudioapi_0.17.1
203-
## [16] tools_4.5.2 evaluate_1.0.5 Rcpp_1.1.0
204-
## [19] yaml_2.3.10 rlang_1.1.6
183+
## [1] digest_0.6.37 RcppArmadillo_15.0.2-2 fastmap_1.2.0
184+
## [4] xfun_0.53 Matrix_1.7-4 lattice_0.22-7
185+
## [7] knitr_1.50 htmltools_0.5.8.1 rmarkdown_2.29
186+
## [10] cli_3.6.5 grid_4.5.2 data.table_1.17.8
187+
## [13] compiler_4.5.2 rstudioapi_0.17.1 tools_4.5.2
188+
## [16] evaluate_1.0.5 Rcpp_1.1.0 yaml_2.3.10
189+
## [19] rlang_1.1.6
205190

206191
## Performance
207192

man/fast_ssgsea.Rd

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-fast_ssGSEA.R

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,8 @@ test_that("extreme sets are removed", {
201201
expect_identical(
202202
object = err,
203203
expected = paste0(
204-
"All sets in `gene_sets` contain fewer than `min_size` genes with ",
205-
"nonmissing values or consist of all genes with nonmissing values ",
206-
"in at least one sample."
204+
"All sets in `gene_sets` contain fewer than `min_size` genes or ",
205+
"more than `max_size` genes with nonmissing values."
207206
)
208207
)
209208
})
@@ -243,9 +242,8 @@ test_that("extreme directional sets are removed", {
243242
expect_identical(
244243
object = err,
245244
expected = paste0(
246-
"All sets in `gene_sets` contain fewer than `min_size` genes with ",
247-
"nonmissing values or consist of all genes with nonmissing values ",
248-
"in at least one sample."
245+
"All sets in `gene_sets` contain fewer than `min_size` genes or ",
246+
"more than `max_size` genes with nonmissing values."
249247
)
250248
)
251249
})

0 commit comments

Comments
 (0)