# SVG: Spatially Variable Genes Detection Methods

<!-- badges: start -->
[![R-CMD-check](https://github.com/Zaoqu-Liu/SVG/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/Zaoqu-Liu/SVG/actions/workflows/R-CMD-check.yaml)
[![R-universe](https://zaoqu-liu.r-universe.dev/badges/SVG)](https://zaoqu-liu.r-universe.dev/SVG)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Documentation](https://img.shields.io/badge/docs-pkgdown-blue)](https://zaoqu-liu.github.io/SVG/)
<!-- badges: end -->

A unified R package for detecting spatially variable genes (SVGs) in spatial transcriptomics data, integrating multiple state-of-the-art methods with optimized performance.

📚 **Documentation**: [https://zaoqu-liu.github.io/SVG/](https://zaoqu-liu.github.io/SVG/)

## Overview

SVG detection is a fundamental step in spatial transcriptomics analysis, identifying genes whose expression patterns exhibit significant spatial structure. This package provides:

- **Four SVG detection methods** with a unified interface
- **Optimized implementations** with C++ acceleration
- **Comprehensive documentation** with scientific details
- **Flexible parameters** for method customization

## Installation

### From R-Universe (Recommended)

```r
# Install from R-Universe
install.packages("SVG", repos = "https://zaoqu-liu.r-universe.dev")
```

### From GitHub

```r
# Install from GitHub
devtools::install_github("Zaoqu-Liu/SVG")

# Or install with dependencies
devtools::install_github("Zaoqu-Liu/SVG", dependencies = TRUE)
```

### From Bioconductor (Coming Soon)

```r
# Install from Bioconductor (after acceptance)
BiocManager::install("SVG")
```

### Dependencies

Core dependencies (automatically installed):
- `Matrix`, `Rcpp`, `RcppArmadillo`

Optional dependencies for specific methods:
```r
# For Delaunay triangulation
install.packages("geometry")

# For KNN network
install.packages("RANN")

# For nnSVG method (required)
install.packages("BRISC")

# For accurate p-values
install.packages("CompQuadForm")
```

## Quick Start

```r
library(SVG)

# Load your data
# expr_matrix: genes x spots (rows x columns)
# spatial_coords: spots x coordinates (x, y)

# Unified interface
results <- CalSVG(expr_matrix, spatial_coords, method = "meringue")

# Or use method-specific functions
results_meringue <- CalSVG_MERINGUE(expr_matrix, spatial_coords)
results_binspect <- CalSVG_binSpect(expr_matrix, spatial_coords)
results_sparkx <- CalSVG_SPARKX(expr_matrix, spatial_coords)
results_nnsvg <- CalSVG_nnSVG(expr_matrix, spatial_coords)

# Get significant SVGs
sig_genes <- results$gene[results$p.adj < 0.05]
```

## Methods

### 1. MERINGUE (Moran's I with Network)

Spatial autocorrelation using Moran's I with binary adjacency network.

```r
results <- CalSVG_MERINGUE(
    expr_matrix,
    spatial_coords,
    network_method = "delaunay",  # or "knn"
    k = 10,                       # neighbors for KNN
    alternative = "greater",      # test for clustering
    adjust_method = "BH"
)
```

**Best for:** General SVG detection with explicit spatial network

### 2. Seurat (Moran's I with Distance Weights)

Moran's I using inverse distance squared weights (Seurat default).

```r
results <- CalSVG_Seurat(
    expr_matrix,
    spatial_coords,
    weight_scheme = "inverse_squared",  # 1/d^2 (default)
    adjust_method = "BH"
)
```

**Best for:** Compatible with Seurat workflow, continuous distance weighting

### 3. binSpect (Giotto)

Binary spatial enrichment test using Fisher's exact test.

```r
results <- CalSVG_binSpect(
    expr_matrix,
    spatial_coords,
    bin_method = "kmeans",   # or "rank"
    rank_percent = 30,       # for rank method
    do_fisher_test = TRUE
)
```

**Best for:** Fast computation, robust to outliers

### 4. SPARK-X

Non-parametric kernel-based test using multiple spatial kernels.

```r
results <- CalSVG_SPARKX(
    expr_matrix,
    spatial_coords,
    kernel_option = "mixture",  # or "single"
    n_threads = 4
)
```

**Best for:** Large datasets, diverse pattern types

### 5. nnSVG

Nearest-neighbor Gaussian processes for spatial modeling.

```r
results <- CalSVG_nnSVG(
    expr_matrix,
    spatial_coords,
    n_neighbors = 10,
    cov_model = "exponential",
    n_threads = 4
)
```

**Best for:** Statistical rigor, effect size estimation

### 6. Mark Variogram

Spatial pattern detection using mark variogram from spatstat.

```r
results <- CalSVG_MarkVario(
    expr_matrix,
    spatial_coords,
    r_metric = 5,       # distance to evaluate variogram
    normalize = TRUE
)
```

**Best for:** Different perspective on spatial patterns

## Method Comparison

| Method | Principle | Speed | Scalability | Effect Size |
|--------|-----------|-------|-------------|-------------|
| MERINGUE | Moran's I (network) | Fast | Medium | Moderate |
| Seurat | Moran's I (1/d²) | Fast | Medium | Moderate |
| binSpect | Fisher test | Very Fast | High | Odds ratio |
| SPARK-X | Kernel test | Fast | Very High | No |
| nnSVG | Gaussian process | Slow | Medium | Yes (prop_sv) |
| MarkVario | Variogram | Moderate | Medium | Variogram value |

## Output Columns

All methods return a data.frame with **unified column names**:

| Column | Description |
|--------|-------------|
| `gene` | Gene identifier |
| `p.value` | Raw p-value |
| `p.adj` | Adjusted p-value (BH/FDR) |

**Method-specific columns:**

| Method | Additional Columns |
|--------|-------------------|
| MERINGUE | `observed`, `expected`, `sd`, `z_score` |
| Seurat | `observed`, `expected`, `sd`, `rank` |
| binSpect | `estimate` (odds ratio), `score` |
| SPARK-X | `stat_*`, `pval_*` (per kernel) |
| nnSVG | `sigma.sq`, `tau.sq`, `phi`, `prop_sv`, `LR_stat` |
| MarkVario | `r.metric.value`, `rank` (no p-values) |

## Tutorials

| Tutorial | Description |
|----------|-------------|
| [Introduction](https://zaoqu-liu.github.io/SVG/articles/SVG-introduction.html) | Complete guide with all methods, benchmarks, and visualizations |

## Examples

### Basic Workflow

```r
library(SVG)

# Simulate data
set.seed(42)
n_spots <- 500
n_genes <- 100

# Expression matrix (genes x spots)
expr <- matrix(rpois(n_genes * n_spots, lambda = 10), 
               nrow = n_genes)
rownames(expr) <- paste0("gene_", 1:n_genes)
colnames(expr) <- paste0("spot_", 1:n_spots)

# Add spatial pattern to first 10 genes
coords <- cbind(x = runif(n_spots, 0, 100),
                y = runif(n_spots, 0, 100))
rownames(coords) <- colnames(expr)

# Create spatial gradient for first genes
for (i in 1:10) {
    expr[i, ] <- expr[i, ] + round(coords[, 1] / 10)
}

# Run SVG detection
results <- CalSVG(expr, coords, method = "meringue")

# Top SVGs
head(results)

# Significant genes
sig_genes <- results$gene[results$p.adj < 0.05]
print(sig_genes)
```

### Integration with SpatialExperiment

```r
library(SpatialExperiment)
library(SVG)

# From SpatialExperiment object
spe <- readRDS("your_spe.rds")

expr_matrix <- as.matrix(logcounts(spe))
spatial_coords <- spatialCoords(spe)

results <- CalSVG(expr_matrix, spatial_coords, method = "meringue")
```

### Parallel Processing

```r
# Use multiple cores for faster computation
results <- CalSVG(
    expr_matrix, spatial_coords,
    method = "sparkx",
    n_threads = parallel::detectCores() - 1
)
```

## Citation

If you use this package, please cite:

```
Liu Z. (2024). SVG: Spatially Variable Genes Detection Methods. 
R package version 1.0.0. https://github.com/Zaoqu-Liu/SVG
```

And cite the original method papers:
- MERINGUE: Miller et al. (2021) Genome Research
- binSpect: Dries et al. (2021) Genome Biology  
- SPARK-X: Zhu et al. (2021) Genome Biology
- nnSVG: Weber et al. (2023) Nature Communications

## License

MIT License

## Author

**Zaoqu Liu**  
Chinese Academy of Medical Sciences and Peking Union Medical College  
Email: liuzaoqu@163.com  
ORCID: [0000-0002-0452-742X](https://orcid.org/0000-0002-0452-742X)

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## See Also

- [Giotto](https://github.com/drieslab/Giotto) - Spatial transcriptomics analysis suite
- [MERINGUE](https://github.com/JEFworks-Lab/MERINGUE) - Original MERINGUE package
- [SPARK](https://github.com/xzhoulab/SPARK) - Original SPARK/SPARK-X package
- [nnSVG](https://github.com/lmweber/nnSVG) - Original nnSVG package
