Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ README.md
tests/*
^\.positai$
^\.claude$
^\.github$
70 changes: 70 additions & 0 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Continuous integration: R CMD check on Linux, macOS and Windows.
on:
push:
branches: [main, master]
pull_request:
workflow_dispatch:

name: R-CMD-check

permissions: read-all

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}

name: ${{ matrix.config.os }} (${{ matrix.config.r }})

strategy:
fail-fast: false
matrix:
config:
- {os: macos-latest, r: 'release'}
- {os: windows-latest, r: 'release'}
- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
- {os: ubuntu-latest, r: 'release'}
- {os: ubuntu-latest, r: 'oldrel-1'}

env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes

steps:
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-pandoc@v2

- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check

- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'

# tests/ is excluded from the source tarball via .Rbuildignore, so
# R CMD check skips them; run the testthat suite from the repo instead.
# Install first: the parallel tests start future workers that attach the
# installed package, so pkgload::load_all() is not enough.
- name: Run testthat suite
shell: Rscript {0}
Comment thread
dosorio marked this conversation as resolved.
Resolved
env:
NOT_CRAN: 'true'
run: |
options(testthat.progress.max_fails = Inf)
install.packages(".", repos = NULL, type = "source")
testthat::test_dir("tests/testthat", package = "SCORPION", load_package = "installed",
stop_on_failure = TRUE,
reporter = testthat::ProgressReporter$new(show_praise = FALSE))
93 changes: 93 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Continuous delivery: on a version tag, build and check the source
# tarball, then attach it to a GitHub release.
on:
push:
tags: ['v*', '[0-9]*']
workflow_dispatch:

name: release

permissions: read-all

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-pandoc@v2

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check

# Tags may be written as 1.2.3, v1.2.3 or v.1.2.3.
- name: Verify tag matches DESCRIPTION version
if: startsWith(github.ref, 'refs/tags/')
run: |
pkg_version=$(grep '^Version:' DESCRIPTION | sed 's/Version:[[:space:]]*//')
tag_version=${GITHUB_REF_NAME#v}
tag_version=${tag_version#.}
if [ "$tag_version" != "$pkg_version" ]; then
echo "::error::Tag $GITHUB_REF_NAME does not match DESCRIPTION version $pkg_version"
exit 1
fi

# tests/ is excluded from the source tarball via .Rbuildignore, so
# run the testthat suite from the checkout before releasing.
# Install first: the parallel tests start future workers that attach the
# installed package, so pkgload::load_all() is not enough.
- name: Run testthat suite
shell: Rscript {0}
env:
NOT_CRAN: 'true'
run: |
install.packages(".", repos = NULL, type = "source")
testthat::test_dir("tests/testthat", package = "SCORPION", load_package = "installed",
stop_on_failure = TRUE,
reporter = testthat::ProgressReporter$new(show_praise = FALSE))

- name: Build source tarball
run: R CMD build --no-manual .

- name: Check source tarball
shell: Rscript {0}
run: |
tarball <- Sys.glob("*.tar.gz")
stopifnot(length(tarball) == 1)
rcmdcheck::rcmdcheck(tarball, args = c("--no-manual", "--as-cran"),
error_on = "warning", check_dir = "check")

- uses: actions/upload-artifact@v4
with:
name: source-tarball
path: '*.tar.gz'
if-no-files-found: error

publish:
needs: build
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
name: source-tarball

- name: Create GitHub release
Comment thread
dosorio marked this conversation as resolved.
Resolved
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "$GITHUB_REF_NAME" *.tar.gz \
--repo "$GITHUB_REPOSITORY" \
--title "$GITHUB_REF_NAME" --generate-notes
18 changes: 12 additions & 6 deletions R/runSCORPION.R
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,21 @@ runSCORPION <- function(gexMatrix,

# Removing batch effect
if (removeBatchEffect) {
if (showProgress) {
cli::cli_alert_success("Correcting for batch effects")
}
if (is.null(batch)) {
cli::cli_abort('batch is needed for batch effect correction')
}
mean_expr <- apply(gexMatrix, 1, median)
gexMatrix <- remove_batch(X = gexMatrix, batch = batch)
gexMatrix <- gexMatrix + mean_expr
if (length(unique(batch[!is.na(batch)])) < 2) {
# A single batch leaves nothing to correct; skip so the per-gene median
# is not added to uncorrected data.
cli::cli_alert_warning("batch has fewer than two levels; skipping batch effect correction")
} else {
if (showProgress) {
cli::cli_alert_success("Correcting for batch effects")
}
mean_expr <- apply(gexMatrix, 1, median)
gexMatrix <- remove_batch(X = gexMatrix, batch = batch)
gexMatrix <- gexMatrix + mean_expr
}
}
rm(batch)

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# <img src="https://raw.githubusercontent.com/kuijjerlab/SCORPION/main/inst/logoSCORPION.png" width="30" title="SCORPION"> SCORPION

[![R-CMD-check](https://github.com/kuijjerlab/SCORPION/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/kuijjerlab/SCORPION/actions/workflows/R-CMD-check.yaml)

**SCORPION** (**S**ingle-**C**ell **O**riented **R**econstruction of **P**ANDA **I**ndividually **O**ptimized Gene Regulatory **N**etworks) is an R package for constructing gene regulatory networks from single-cell and single-nucleus RNA sequencing data. The package addresses the sparsity inherent in single-cell expression data through coarse-graining, which aggregates similar cells to improve correlation structure detection. Network reconstruction is performed using the PANDA (Passing Attributes between Networks for Data Assimilation) message-passing algorithm, integrating transcription factor motifs, protein-protein interactions, and gene expression data. By using consistent baseline priors across samples, SCORPION produces comparable, fully-connected, weighted regulatory networks suitable for population-level analyses.


Expand Down
26 changes: 26 additions & 0 deletions tests/testthat/test_data_preprocessing.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,29 @@ test_that("runSCORPION() batch effect correction works with valid batch", {
expect_true(is.data.frame(result))
expect_true(all(c("tf", "target") %in% colnames(result)))
})

test_that("runSCORPION() skips batch correction when batch has a single level", {
data(scorpionTest)

args <- list(
gexMatrix = scorpionTest$gex,
tfMotifs = scorpionTest$tf,
ppiNet = scorpionTest$ppi,
cellsMetadata = scorpionTest$metadata,
groupBy = "region",
showProgress = FALSE
)

set.seed(1)
uncorrected <- do.call(runSCORPION, args)
set.seed(1)
expect_message(
single_batch <- do.call(runSCORPION, c(args, list(
removeBatchEffect = TRUE,
batch = rep("b1", ncol(scorpionTest$gex))
))),
"fewer than two levels"
)

expect_equal(single_batch, uncorrected)
})
Loading