-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREADME.Rmd
More file actions
187 lines (136 loc) · 7.17 KB
/
Copy pathREADME.Rmd
File metadata and controls
187 lines (136 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# RidgeR: Ridge Regression with Significance Testing
## Installation
To install `RidgeR`, we recommend using `devtools`:
``` r
# install.packages("devtools")
devtools::install_github("beibeiru/RidgeR")
```
**System Requirements:** GNU Scientific Library (GSL)
The package has been installed successfully on Operating Systems:
* Red Hat Enterprise Linux 8.10 (Ootpa)
* macOS Sequoia 15.3.1
* Windows 10
### Troubleshooting: GSL not found on macOS
If you see this error during installation:
```
Checking for GSL...
ERROR: GSL is not installed or gsl-config is not found.
ERROR: configuration failed for package 'RidgeR'
```
Install GSL using [Homebrew](https://brew.sh/):
``` bash
brew install gsl
```
After installation, verify that `gsl-config` is available:
``` bash
gsl-config --version
```
Then retry installing RidgeR. If `gsl-config` is still not found after installing GSL (e.g., Homebrew is not in your PATH), you can set the path explicitly before installing:
``` r
Sys.setenv(PATH = paste("/opt/homebrew/bin", Sys.getenv("PATH"), sep = ":"))
devtools::install_github("beibeiru/RidgeR")
```
For **OpenMP** multi-threading support (optional), also install `libomp`:
``` bash
brew install libomp
```
Without `libomp`, RidgeR will still work but will default to single-threaded backends on macOS.
## Functions
### Main function
`SecAct.inference.gsl.new` is the primary interface. It dispatches to one of 4 optimized C backends via the `method` parameter:
``` r
SecAct.inference.gsl.new(Y, method = "Tcol.mt") # default: T-col, multi-threaded
SecAct.inference.gsl.new(Y, method = "Tcol.st") # T-col, single-threaded
SecAct.inference.gsl.new(Y, method = "Yrow.mt") # Y-row, multi-threaded
SecAct.inference.gsl.new(Y, method = "Yrow.st") # Y-row, single-threaded
```
### All variants
| # | Function | Permutation | Threading | Interface | Description |
|---|----------|-------------|-----------|-----------|-------------|
| 1 | `SecAct.inference.naive` | T-col (pure R) | Single (R) | `.Call` (perm table only) | Pure R reference implementation |
| 2 | `SecAct.inference.Yrow.st` | Y-row | Single | `.Call` (ncores=1) | Single-threaded Y-row permutation |
| 3 | `SecAct.inference.Tcol.st` | T-col | Single | `.Call` (ncores=1) | Single-threaded T-col permutation |
| 4 | `SecAct.inference.Yrow.mt` | Y-row | Multi (OMP) | `.Call` | Multi-threaded Y-row permutation |
| 5 | `SecAct.inference.Tcol.mt` | T-col | Multi (OMP) | `.Call` | Multi-threaded T-col permutation |
| — | `SecAct.inference.gsl.old` | Y-row | Single | `.C` (legacy, 32-bit) | Legacy single-threaded (preserved) |
| — | `SecAct.inference.gsl.new` | Dispatches | Dispatches | `.Call` (64-bit) | Dispatcher (default: `method="Tcol.mt"`) |
**Permutation strategies:**
* **Y-row**: Permutes rows of the response matrix Y, then multiplies T * Y_perm. Parallelizes over sample strips.
* **T-col**: Permutes columns of the projection matrix T, then multiplies T_perm * Y. Mathematically equivalent (`T[:, inv_perm] @ Y == T @ Y[perm, :]`). Parallelizes over permutations. Matches [SecActPy](https://github.com/data2intelligence/SecActpy) approach.
**Legacy:** `gsl.old` is preserved for backward compatibility. `gsl.new` now dispatches to the 4 variants (previously it was Y-row multi-threaded only).
### Key Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| `Y` | — | Gene expression matrix (genes x samples) |
| `SigMat` | `"SecAct"` | Signature matrix: `"SecAct"` (bundled) or path to file |
| `lambda` | `5e+05` | Ridge regularization parameter |
| `nrand` | `1000` | Number of permutations |
| `ncores` | `NULL` | Number of CPU cores (`NULL` = auto-detect; multi-threaded variants only) |
| `rng_method` | `"srand"` | RNG backend: `"srand"` (C stdlib, matches R SecAct) or `"gsl"` (cross-platform GSL MT19937) |
| `method` | `"Tcol.mt"` | Backend variant: `"Tcol.mt"`, `"Tcol.st"`, `"Yrow.mt"`, or `"Yrow.st"` (`gsl.new` only) |
| `is.group.sig` | `TRUE` | Group correlated signatures before regression |
| `is.group.cor` | `0.9` | Correlation threshold for signature grouping |
## Example
``` r
library(RidgeR)
dataPath <- file.path(system.file(package = "RidgeR"), "extdata/")
expr.diff <- read.table(paste0(dataPath, "Ly86-Fc_vs_Vehicle_logFC.txt"))
# ---- Compare all variants ----
t_naive <- system.time({res.naive <- SecAct.inference.naive(expr.diff)})
t_yrow_st <- system.time({res.yrow.st <- SecAct.inference.Yrow.st(expr.diff)})
t_tcol_st <- system.time({res.tcol.st <- SecAct.inference.Tcol.st(expr.diff)})
t_yrow_mt <- system.time({res.yrow.mt <- SecAct.inference.Yrow.mt(expr.diff)})
t_tcol_mt <- system.time({res.tcol.mt <- SecAct.inference.Tcol.mt(expr.diff)})
# ---- Verify equivalence (all should be ~0) ----
cat("naive vs Tcol.st:", max(abs(res.naive$zscore - res.tcol.st$zscore)), "\n")
cat("Yrow.st vs Yrow.mt:", max(abs(res.yrow.st$zscore - res.yrow.mt$zscore)), "\n")
cat("Tcol.st vs Tcol.mt:", max(abs(res.tcol.st$zscore - res.tcol.mt$zscore)), "\n")
# ---- Elapsed times ----
cat("naive:", t_naive[3], "Yrow.st:", t_yrow_st[3], "Tcol.st:", t_tcol_st[3],
"Yrow.mt:", t_yrow_mt[3], "Tcol.mt:", t_tcol_mt[3], "\n")
```
## Compatibility with R SecAct
RidgeR's `is.group.sig` parameter controls signature grouping. The original
[R SecAct](https://github.com/data2intelligence/SecAct) package has different
functions with and without grouping:
| R SecAct Function | Grouping | RidgeR Equivalent |
|---|---|---|
| `SecAct.inference.gsl` | No | `SecAct.inference.gsl.new(Y, is.group.sig = FALSE)` |
| `SecAct.activity.inference(Y, is.differential = TRUE)` | Yes (default) | `SecAct.inference.gsl.new(Y, is.group.sig = TRUE)` |
``` r
# Match SecAct.inference.gsl (no grouping)
res <- SecAct.inference.gsl.new(expr.diff, is.group.sig = FALSE)
# Match SecAct.activity.inference (with grouping, default)
res <- SecAct.inference.gsl.new(expr.diff, is.group.sig = TRUE)
```
Verified equivalence (max |zscore diff| < 5e-14, correlation = 1.0) for both
cases against the original R SecAct package.
## Reproducibility
RidgeR supports two RNG backends via the `rng_method` parameter:
| `rng_method` | Description | Use case |
|---|---|---|
| `"srand"` (default) | C stdlib `srand()`/`rand()` | Match original R SecAct results **on the same platform** |
| `"gsl"` | GSL Mersenne Twister (MT19937) | **Cross-platform** reproducibility; matches [SecActPy](https://github.com/data2intelligence/SecActpy) `rng_method='gsl'` |
``` r
# Default: match R SecAct on same platform (C stdlib rand, platform-dependent)
res <- SecAct.inference.Yrow.mt(expr.diff, rng_method = "srand")
# Cross-platform: matches SecActPy rng_method='gsl' on any OS
res <- SecAct.inference.Yrow.mt(expr.diff, rng_method = "gsl")
```
> **Note:** C `rand()` implementations differ across operating systems, so
> `rng_method="srand"` produces platform-dependent results. Use
> `rng_method="gsl"` when results must be reproducible across Linux, macOS,
> and Windows, or when comparing with
> [SecActPy](https://github.com/data2intelligence/SecActpy).