From 99331547039e2602e026acb145a1a4bfbeb33421 Mon Sep 17 00:00:00 2001
From: zhanghao-njmu <542370159@qq.com>
Date: Wed, 25 Oct 2023 13:47:23 +0800
Subject: [PATCH] Update the requirements of SCP python environment
---
R/SCP-plot.R | 7 +-
R/SCP-workflow.R | 24 +++--
R/Seurat-function.R | 4 +-
R/utils.R | 59 ++++--------
README.Rmd | 14 +--
README.md | 90 +++++++++---------
.../__pycache__/SCP_analysis.cpython-38.pyc | Bin 24708 -> 21908 bytes
man/CellDimPlot3D.Rd | 5 +-
man/Env_requirements.Rd | 2 +-
man/FeatureDimPlot3D.Rd | 2 +-
man/Integration_SCP.Rd | 8 +-
man/check_R.Rd | 5 +-
.../figures/CellDimPlot3D-1.png | Bin
.../figures/DynamicHeatmap-1.png | Bin
.../figures/DynamicPlot-1.png | Bin
.../README-EDA-1.png => man/figures/EDA-1.png | Bin
.../README-EDA-2.png => man/figures/EDA-2.png | Bin
.../README-EDA-3.png => man/figures/EDA-3.png | Bin
.../README-EDA-4.png => man/figures/EDA-4.png | Bin
.../README-EDA-5.png => man/figures/EDA-5.png | Bin
.../figures/Enrichment_comparison-1.png | Bin
.../figures/Enrichment_enrichmap-1.png | Bin
.../figures/Example-1.jpg | Bin
.../figures/Example-2.jpg | Bin
.../figures/Example-3.jpg | Bin
.../figures/Example-4.jpg | Bin
.../figures/FeatureDimPlot3D-1.png | Bin
.../figures/FeatureHeatmap-1.png | Bin
.../figures/FeatureStatPlot-1.png | Bin
.../figures/GSEA_bar-1.png | Bin
.../figures/GSEA_comparison-1.png | Bin
.../figures/Integration-all.png | Bin
.../figures/Integration_SCP-1.png | Bin
.../figures/RunCellQC-1.png | Bin
.../figures/RunCellQC-2.png | Bin
.../figures/RunCellQC-3.png | Bin
.../figures/RunDEtest-1.png | Bin
.../figures/RunEnrichment-1.png | Bin
.../figures/RunEnrichment-2.png | Bin
.../figures/RunEnrichment-3.png | Bin
.../figures/RunEnrichment-4.png | Bin
.../figures/RunGSEA-1.png | Bin
.../figures/RunKNNMap-1.png | Bin
.../figures/RunKNNPredict-bulk-1.png | Bin
.../figures/RunKNNPredict-scrna-1.png | Bin
.../figures/RunKNNPredict-scrna-2.png | Bin
.../figures/RunKNNPredict-scrna-3.png | Bin
.../figures/RunPAGA-1.png | Bin
.../figures/RunSCVELO-1.png | Bin
.../figures/RunSCVELO-2.png | Bin
.../figures/RunSlingshot-1.png | Bin
.../figures/RunSlingshot-2.png | Bin
.../figures/RunSlingshot-3.png | Bin
.../figures/SCExplorer-1.png | Bin
.../figures/SCExplorer-2.png | Bin
.../figures/Standard_SCP-1.png | Bin
56 files changed, 100 insertions(+), 120 deletions(-)
rename README/README-CellDimPlot3D-1.png => man/figures/CellDimPlot3D-1.png (100%)
rename README/README-DynamicHeatmap-1.png => man/figures/DynamicHeatmap-1.png (100%)
rename README/README-DynamicPlot-1.png => man/figures/DynamicPlot-1.png (100%)
rename README/README-EDA-1.png => man/figures/EDA-1.png (100%)
rename README/README-EDA-2.png => man/figures/EDA-2.png (100%)
rename README/README-EDA-3.png => man/figures/EDA-3.png (100%)
rename README/README-EDA-4.png => man/figures/EDA-4.png (100%)
rename README/README-EDA-5.png => man/figures/EDA-5.png (100%)
rename README/README-Enrichment_comparison-1.png => man/figures/Enrichment_comparison-1.png (100%)
rename README/README-Enrichment_enrichmap-1.png => man/figures/Enrichment_enrichmap-1.png (100%)
rename README/README-Example-1.jpg => man/figures/Example-1.jpg (100%)
rename README/README-Example-2.jpg => man/figures/Example-2.jpg (100%)
rename README/README-Example-3.jpg => man/figures/Example-3.jpg (100%)
rename README/README-Example-4.jpg => man/figures/Example-4.jpg (100%)
rename README/README-FeatureDimPlot3D-1.png => man/figures/FeatureDimPlot3D-1.png (100%)
rename README/README-FeatureHeatmap-1.png => man/figures/FeatureHeatmap-1.png (100%)
rename README/README-FeatureStatPlot-1.png => man/figures/FeatureStatPlot-1.png (100%)
rename README/README-GSEA_bar-1.png => man/figures/GSEA_bar-1.png (100%)
rename README/README-GSEA_comparison-1.png => man/figures/GSEA_comparison-1.png (100%)
rename README/README-Integration-all.png => man/figures/Integration-all.png (100%)
rename README/README-Integration_SCP-1.png => man/figures/Integration_SCP-1.png (100%)
rename README/README-RunCellQC-1.png => man/figures/RunCellQC-1.png (100%)
rename README/README-RunCellQC-2.png => man/figures/RunCellQC-2.png (100%)
rename README/README-RunCellQC-3.png => man/figures/RunCellQC-3.png (100%)
rename README/README-RunDEtest-1.png => man/figures/RunDEtest-1.png (100%)
rename README/README-RunEnrichment-1.png => man/figures/RunEnrichment-1.png (100%)
rename README/README-RunEnrichment-2.png => man/figures/RunEnrichment-2.png (100%)
rename README/README-RunEnrichment-3.png => man/figures/RunEnrichment-3.png (100%)
rename README/README-RunEnrichment-4.png => man/figures/RunEnrichment-4.png (100%)
rename README/README-RunGSEA-1.png => man/figures/RunGSEA-1.png (100%)
rename README/README-RunKNNMap-1.png => man/figures/RunKNNMap-1.png (100%)
rename README/README-RunKNNPredict-bulk-1.png => man/figures/RunKNNPredict-bulk-1.png (100%)
rename README/README-RunKNNPredict-scrna-1.png => man/figures/RunKNNPredict-scrna-1.png (100%)
rename README/README-RunKNNPredict-scrna-2.png => man/figures/RunKNNPredict-scrna-2.png (100%)
rename README/README-RunKNNPredict-scrna-3.png => man/figures/RunKNNPredict-scrna-3.png (100%)
rename README/README-RunPAGA-1.png => man/figures/RunPAGA-1.png (100%)
rename README/README-RunSCVELO-1.png => man/figures/RunSCVELO-1.png (100%)
rename README/README-RunSCVELO-2.png => man/figures/RunSCVELO-2.png (100%)
rename README/README-RunSlingshot-1.png => man/figures/RunSlingshot-1.png (100%)
rename README/README-RunSlingshot-2.png => man/figures/RunSlingshot-2.png (100%)
rename README/README-RunSlingshot-3.png => man/figures/RunSlingshot-3.png (100%)
rename README/README-SCExplorer-1.png => man/figures/SCExplorer-1.png (100%)
rename README/README-SCExplorer-2.png => man/figures/SCExplorer-2.png (100%)
rename README/README-Standard_SCP-1.png => man/figures/Standard_SCP-1.png (100%)
diff --git a/R/SCP-plot.R b/R/SCP-plot.R
index e3d82e4d..b47b7007 100644
--- a/R/SCP-plot.R
+++ b/R/SCP-plot.R
@@ -2763,12 +2763,13 @@ FeatureDimPlot <- function(srt, features, reduction = NULL, dims = c(1, 2), spli
#' Plotting cell points on a reduced 3D space and coloring according to the groups of the cells.
#'
#' @inheritParams CellDimPlot
+#' @param dims Dimensions to plot, must be a three-length numeric vector specifying x-, y- and z-dimensions
#' @param axis_labs A character vector of length 3 indicating the labels for the axes.
#' @param span A numeric value specifying the span of the loess smoother for lineages line.
#' @param shape.highlight Shape of the cell to highlight. See \href{https://plotly.com/r/reference/scattergl/#scattergl-marker-symbol}{scattergl-marker-symbol}
#' @param width Width in pixels, defaults to automatic sizing.
#' @param height Height in pixels, defaults to automatic sizing.
-#' @param save The name of the file to save the plot to. Must end in .html.
+#' @param save The name of the file to save the plot to. Must end in ".html".
#' @seealso \code{\link{CellDimPlot}} \code{\link{FeatureDimPlot3D}}
#'
#' @examples
@@ -2778,6 +2779,7 @@ FeatureDimPlot <- function(srt, features, reduction = NULL, dims = c(1, 2), spli
#'
#' pancreas_sub <- RunSlingshot(pancreas_sub, group.by = "SubCellType", reduction = "StandardpcaUMAP3D")
#' CellDimPlot3D(pancreas_sub, group.by = "SubCellType", reduction = "StandardpcaUMAP3D", lineages = "Lineage1")
+#'
#' @importFrom Seurat Reductions Embeddings Key
#' @importFrom utils askYesNo
#' @importFrom plotly plot_ly add_trace layout as_widget
@@ -2857,9 +2859,6 @@ CellDimPlot3D <- function(srt, group.by, reduction = NULL, dims = c(1, 2, 3), ax
dat_lineages <- srt@meta.data[, unique(lineages), drop = FALSE]
dat_use <- cbind(dat_use, dat_lineages[row.names(dat_use), , drop = FALSE])
}
- if (!is.factor(dat_use[[group.by]])) {
- dat_use[[group.by]] <- factor(dat_use[[group.by]], levels = unique(dat_use[[group.by]]))
- }
dat_use[["group.by"]] <- dat_use[[group.by]]
if (any(is.na(dat_use[[group.by]]))) {
n <- as.character(dat_use[[group.by]])
diff --git a/R/SCP-workflow.R b/R/SCP-workflow.R
index c90761f9..38ed6087 100644
--- a/R/SCP-workflow.R
+++ b/R/SCP-workflow.R
@@ -838,7 +838,8 @@ RunDimReduction <- function(srt, prefix = "", features = NULL, assay = NULL, slo
srt@misc[["Default_reduction"]] <- paste0(prefix, linear_reduction)
return(srt)
} else {
- message("assay.used is ", srt[[linear_reduction]]@assay.used, ", which is not the same as the ", assay, " specified. Recalculate the linear reduction")
+ message("assay.used is ", srt[[linear_reduction]]@assay.used, ", which is not the same as the ", assay, " specified. Recalculate the linear reduction(pca)")
+ linear_reduction <- "pca"
}
}
}
@@ -933,7 +934,8 @@ RunDimReduction <- function(srt, prefix = "", features = NULL, assay = NULL, slo
srt@misc[["Default_reduction"]] <- paste0(prefix, nonlinear_reduction)
return(srt)
} else {
- message("assay.used is ", srt[[nonlinear_reduction]]@assay.used, ", which is not the same as the ", assay, " specified. Recalculate the linear reduction")
+ message("assay.used is ", srt[[nonlinear_reduction]]@assay.used, ", which is not the same as the ", assay, " specified. Recalculate the nonlinear reduction(umap)")
+ nonlinear_reduction <- "umap"
}
}
}
@@ -1031,7 +1033,7 @@ DefaultReduction <- function(srt, pattern = NULL, min_dim = 2, max_distance = 0.
if (length(srt@reductions) == 0) {
stop("Unable to find any reductions.")
}
- pattern_default <- c("umap", "tsne", "dm", "phate", "pacmap", "trimap", "largevis", "pca", "svd", "ica", "nmf", "mds", "glmpca")
+ pattern_default <- c("umap", "tsne", "dm", "phate", "pacmap", "trimap", "largevis", "fr", "pca", "svd", "ica", "nmf", "mds", "glmpca")
pattern_dim <- c("2D", "3D")
reduc_all <- names(srt@reductions)
reduc_all <- reduc_all[unlist(lapply(reduc_all, function(x) {
@@ -3204,11 +3206,11 @@ Conos_integrate <- function(srtMerge = NULL, batch = NULL, append = TRUE, srtLis
}
cat(paste0("[", Sys.time(), "]", " Perform linear dimension reduction (", linear_reduction, ") on the data ", i, " ...\n"))
srt <- RunDimReduction(
- srt = srt, prefix = "", features = HVF, assay = DefaultAssay(srt),
+ srt = srt, prefix = "Conos", features = HVF, assay = DefaultAssay(srt),
linear_reduction = linear_reduction, linear_reduction_dims = linear_reduction_dims, linear_reduction_params = linear_reduction_params, force_linear_reduction = force_linear_reduction,
verbose = FALSE, seed = seed
)
- srt[["pca"]] <- srt[[linear_reduction]]
+ srt[["pca"]] <- srt[[paste0("Conos", linear_reduction)]]
srtList[[i]] <- srt
}
if (is.null(names(srtList))) {
@@ -3216,13 +3218,13 @@ Conos_integrate <- function(srtMerge = NULL, batch = NULL, append = TRUE, srtLis
}
if (is.null(linear_reduction_dims_use)) {
- maxdims <- max(unlist(sapply(srtList, function(srt) max(srt@reductions[[paste0("", linear_reduction)]]@misc[["dims_estimate"]]))))
+ maxdims <- max(unlist(sapply(srtList, function(srt) max(srt@reductions[[paste0("Conos", linear_reduction)]]@misc[["dims_estimate"]]))))
} else {
maxdims <- max(linear_reduction_dims_use)
}
cat(paste0("[", Sys.time(), "]", " Perform integration(Conos) on the data...\n"))
- message("Conos using ", linear_reduction, "(dims_max:", maxdims, ") as input")
+ message("Conos integration using Reduction(", linear_reduction, ", dims_max:", maxdims, ") as input")
srtList_con <- conos::Conos$new(srtList, n.cores = num_threads)
params <- list(
ncomps = maxdims,
@@ -3739,14 +3741,18 @@ Standard_SCP <- function(srt, prefix = "Standard", assay = NULL,
#' for (method in integration_methods) {
#' panc8_sub <- Integration_SCP(
#' srtMerge = panc8_sub, batch = "tech",
-#' integration_method = method, linear_reduction_dims_use = 1:50, nonlinear_reduction = "umap"
+#' integration_method = method,
+#' linear_reduction_dims_use = 1:50,
+#' nonlinear_reduction = "umap"
#' )
#' print(CellDimPlot(panc8_sub, group.by = c("tech", "celltype"), reduction = paste0(method, "UMAP2D"), theme_use = "theme_blank"))
#' }
#'
#' nonlinear_reductions <- c("umap", "tsne", "dm", "phate", "pacmap", "trimap", "largevis", "fr")
#' panc8_sub <- Integration_SCP(
-#' srtMerge = panc8_sub, batch = "tech", integration_method = "Seurat",
+#' srtMerge = panc8_sub, batch = "tech",
+#' integration_method = "Seurat",
+#' linear_reduction_dims_use = 1:50,
#' nonlinear_reduction = nonlinear_reductions
#' )
#' for (nr in nonlinear_reductions) {
diff --git a/R/Seurat-function.R b/R/Seurat-function.R
index 0b03fd57..4ea2a9de 100644
--- a/R/Seurat-function.R
+++ b/R/Seurat-function.R
@@ -117,7 +117,7 @@ RunNMF.default <- function(object, assay = NULL, slot = "data", nbes = 50,
}
nbes <- min(nbes, nrow(x = object) - 1)
if (nmf.method == "RcppML") {
- check_R("zdebruine/RcppML@0.5.6")
+ check_R("zdebruine/RcppML")
options("RcppML.verbose" = FALSE)
options("RcppML.threads" = 0)
nmf.results <- RcppML::nmf(
@@ -1602,7 +1602,7 @@ RunLargeVis.Seurat <- function(object, reduction = "pca", dims = NULL, features
search_k = search_k, n_threads = n_threads, n_sgd_threads = n_sgd_threads, grain_size = grain_size,
kernel = kernel, pca = pca, pca_center = pca_center, pcg_rand = pcg_rand, fast_sgd = fast_sgd,
batch = batch, opt_args = opt_args, epoch_callback = epoch_callback, pca_method = pca_method,
- reduction.key = reduction.key, verbose = verbose, seed.use = seed.use, ...
+ reduction.key = reduction.key, verbose = verbose, seed.use = seed.use
)
object <- LogSeuratCommand(object = object)
return(object)
diff --git a/R/utils.R b/R/utils.R
index e51f8408..bf559893 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -9,7 +9,6 @@
#' If a conda environment with the specified name already exists and \code{force} is set to \code{FALSE}, the function will use the existing environment. If \code{force} set to \code{TRUE}, the existing environment will be recreated. Note that recreating the environment will remove any existing data in the environment.
#' The function also checks if the package versions in the environment meet the requirements specified by the \code{version} parameter. The default is \code{3.8-1}.
#'
-#'
#' @export
PrepareEnv <- function(conda = "auto", miniconda_repo = "https://repo.anaconda.com/miniconda",
envname = NULL, version = "3.8-1", force = FALSE, ...) {
@@ -142,8 +141,8 @@ PrepareEnv <- function(conda = "auto", miniconda_repo = "https://repo.anaconda.c
#' Env_requirements("3.8-1")
#'
#' @export
-Env_requirements <- function(version = c("3.8-1", "3.8-2", "3.9-1", "3.10-1", "3.11-1")) {
- version <- match.arg(version)
+Env_requirements <- function(version = "3.8-1") {
+ version <- match.arg(version, choices = c("3.8-1", "3.8-2", "3.9-1", "3.10-1", "3.11-1"))
requirements <- switch(version,
"3.8-1" = list(
python = "3.8",
@@ -159,7 +158,10 @@ Env_requirements <- function(version = c("3.8-1", "3.8-2", "3.9-1", "3.10-1", "3
"scikit-learn" = "scikit-learn==1.1.2",
"scipy" = "scipy==1.10.1",
"scvelo" = "scvelo==0.2.5",
- "wot" = "wot==1.0.8.post2"
+ "wot" = "wot==1.0.8.post2",
+ "trimap" = "trimap==1.1.4",
+ "pacmap" = "pacmap==0.7.0",
+ "phate" = "phate==1.0.11"
# "tables" = "git+https://github.com/PyTables/PyTables", # Fixed: PyTables install fails on macOS M1
)
),
@@ -168,7 +170,7 @@ Env_requirements <- function(version = c("3.8-1", "3.8-2", "3.9-1", "3.10-1", "3
packages = c(
"leidenalg" = "leidenalg==0.10.1",
"matplotlib" = "matplotlib==3.7.3",
- "numba" = "numba==0.58.0",
+ "numba" = "numba==0.58.1",
"numpy" = "numpy==1.24.4",
"palantir" = "palantir==1.3.0",
"pandas" = "pandas==1.5.3",
@@ -185,7 +187,7 @@ Env_requirements <- function(version = c("3.8-1", "3.8-2", "3.9-1", "3.10-1", "3
packages = c(
"leidenalg" = "leidenalg==0.10.1",
"matplotlib" = "matplotlib==3.8.0",
- "numba" = "numba==0.58.0",
+ "numba" = "numba==0.58.1",
"numpy" = "numpy==1.25.2",
"palantir" = "palantir==1.3.0",
"pandas" = "pandas==1.5.3",
@@ -202,7 +204,7 @@ Env_requirements <- function(version = c("3.8-1", "3.8-2", "3.9-1", "3.10-1", "3
packages = c(
"leidenalg" = "leidenalg==0.10.1",
"matplotlib" = "matplotlib==3.8.0",
- "numba" = "numba==0.58.0",
+ "numba" = "numba==0.58.1",
"numpy" = "numpy==1.25.2",
"palantir" = "palantir==1.3.0",
"pandas" = "pandas==1.5.3",
@@ -219,7 +221,7 @@ Env_requirements <- function(version = c("3.8-1", "3.8-2", "3.9-1", "3.10-1", "3
packages = c(
"leidenalg" = "leidenalg==0.10.1",
"matplotlib" = "matplotlib==3.8.0",
- "numba" = "numba==0.58.0",
+ "numba" = "numba==0.58.1",
"numpy" = "numpy==1.25.2",
"palantir" = "palantir==1.3.0",
"pandas" = "pandas==1.5.3",
@@ -519,8 +521,7 @@ check_Python <- function(packages, envname = NULL, conda = "auto", force = FALSE
#' Check and install R packages
#'
-#' @param packages Package to be installed. Package source can be CRAN, Bioconductor or Github, e.g. scmap, davidsjoberg/ggsankey.
-#' @param package_names The name of the package that corresponds to the \code{packages} parameter, used to check if the package is already installed.
+#' @param packages Package to be installed. Package source can be CRAN, Bioconductor or Github, e.g. scmap, quadbiolab/simspec.
#' By default, the package name is extracted according to the \code{packages} parameter.
#' @param install_methods Functions used to install R packages.
#' @param lib The location of the library directories where to install the packages.
@@ -528,31 +529,11 @@ check_Python <- function(packages, envname = NULL, conda = "auto", force = FALSE
#'
#' @importFrom utils packageVersion
#' @export
-check_R <- function(packages, package_names = NULL, install_methods = c("BiocManager::install", "install.packages", "devtools::install_github"), lib = .libPaths()[1], force = FALSE) {
- if (length(package_names) != 0 && length(package_names) != length(packages)) {
- stop("package_names must be NULL or a vector of the same length with packages")
- }
+check_R <- function(packages, install_methods = c("BiocManager::install", "install.packages", "devtools::install_github"), lib = .libPaths()[1], force = FALSE) {
status_list <- list()
- for (n in seq_along(packages)) {
- pkg <- packages[n]
- pkg_info <- pkg
- if (!grepl("/", pkg_info)) {
- pkg_info <- paste0("/", pkg_info)
- }
- if (!grepl("@", pkg_info)) {
- pkg_info <- paste0(pkg_info, "@")
- }
- git <- grep("/", sub(pattern = "(.*/)(.*)(@.*)", replacement = "\\1", x = pkg_info), value = TRUE)
- git <- gsub("/", "", git)
- pkg_name <- package_names[n] %||% sub(pattern = "(.*/)(.*)(@.*)", replacement = "\\2", x = pkg_info)
- version <- grep("@", sub(pattern = "(.*/)(.*)(@.*)", replacement = "\\3", x = pkg_info), value = TRUE)
- version <- gsub("@", "", version)
- if (version != "") {
- force_update <- isTRUE(packageVersion(pkg_name) < package_version(version)) || isTRUE(force)
- } else {
- force_update <- isTRUE(force)
- }
- if (!suppressPackageStartupMessages(requireNamespace(pkg_name, quietly = TRUE)) || isTRUE(force_update)) {
+ for (pkg in packages) {
+ pkg_name <- sub(pattern = "(.*)/(.*)", replacement = "\\2", x = pkg)
+ if (!suppressPackageStartupMessages(requireNamespace(pkg_name, quietly = TRUE)) || isTRUE(force)) {
message("Install package: \"", pkg_name, "\" ...")
status_list[[pkg]] <- FALSE
i <- 1
@@ -577,15 +558,7 @@ check_R <- function(packages, package_names = NULL, install_methods = c("BiocMan
}, error = function(e) {
status_list[[pkg]] <- FALSE
})
- if (version == "") {
- status_list[[pkg]] <- requireNamespace(pkg_name, quietly = TRUE)
- } else {
- if (requireNamespace(pkg_name, quietly = TRUE)) {
- status_list[[pkg]] <- packageVersion(pkg_name) >= package_version(version)
- } else {
- status_list[[pkg]] <- FALSE
- }
- }
+ status_list[[pkg]] <- requireNamespace(pkg_name, quietly = TRUE)
i <- i + 1
if (i > length(install_methods)) {
break
diff --git a/README.Rmd b/README.Rmd
index 6abe7b58..8221f50f 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -11,7 +11,7 @@ knitr::opts_chunk$set(
results = "hide",
message = FALSE,
warning = FALSE,
- fig.path = "README/README-",
+ fig.path = "man/figures/",
fig.height = 5,
fig.width = 10,
fig.align = "center",
@@ -57,7 +57,7 @@ if (!require("devtools", quietly = TRUE)) {
devtools::install_github("zhanghao-njmu/SCP")
```
-#### Create SCP python environment
+#### Create a python environment for SCP
To run functions such as `RunPAGA` or `RunSCVELO`, SCP requires [conda](https://docs.conda.io/en/latest/miniconda.html) to create a separate python environment. The default environment name is `"SCP_env"`. You can specify the environment name for SCP by setting `options(SCP_env_name="new_name")`
@@ -282,13 +282,13 @@ CellDimPlot(
CellDimPlot3D(srt = pancreas_sub, group.by = "SubCellType")
```
-![CellDimPlot3D](README/README-CellDimPlot3D-1.png)
+![CellDimPlot3D](man/figures/CellDimPlot3D-1.png)
```{r FeatureDimPlot3D,eval=FALSE}
FeatureDimPlot3D(srt = pancreas_sub, features = c("Sox9", "Neurog3", "Fev", "Rbp4"))
```
-![FeatureDimPlot3D](README/README-FeatureDimPlot3D-1.png)
+![FeatureDimPlot3D](man/figures/FeatureDimPlot3D-1.png)
### Integration pipeline
@@ -330,7 +330,7 @@ grob <- gtable_add_grob(grob, legend, t = 1, l = min(grob$layout[grepl(pattern =
panel_fix(grob, height = 2)
```
-![Integration-all](README/README-Integration-all.png)
+![Integration-all](man/figures/Integration-all.png)
### Cell projection between single-cell datasets
@@ -540,10 +540,10 @@ if (interactive()) {
}
```
-![SCExplorer1](README/README-SCExplorer-1.png) ![SCExplorer2](README/README-SCExplorer-2.png)
+![SCExplorer1](man/figures/SCExplorer-1.png) ![SCExplorer2](man/figures/SCExplorer-2.png)
### Other visualization examples
-[**CellDimPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellDimPlot.html)![Example1](README/README-Example-1.jpg) [**CellStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellStatPlot.html)![Example2](README/README-Example-2.jpg) [**FeatureStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/FeatureStatPlot.html)![Example3](README/README-Example-3.jpg) [**GroupHeatmap**](https://zhanghao-njmu.github.io/SCP/reference/GroupHeatmap.html)![Example3](README/README-Example-4.jpg)
+[**CellDimPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellDimPlot.html)![Example1](man/figures/Example-1.jpg) [**CellStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellStatPlot.html)![Example2](man/figures/Example-2.jpg) [**FeatureStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/FeatureStatPlot.html)![Example3](man/figures/Example-3.jpg) [**GroupHeatmap**](https://zhanghao-njmu.github.io/SCP/reference/GroupHeatmap.html)![Example3](man/figures/Example-4.jpg)
You can also find more examples in the documentation of the function: [Integration_SCP](https://zhanghao-njmu.github.io/SCP/reference/Integration_SCP.html), [RunKNNMap](https://zhanghao-njmu.github.io/SCP/reference/RunKNNMap.html), [RunMonocle3](https://zhanghao-njmu.github.io/SCP/reference/RunMonocle3.html), [RunPalantir](https://zhanghao-njmu.github.io/SCP/reference/RunPalantir.html), etc.
diff --git a/README.md b/README.md
index fe1e9dd2..e4b1694c 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ if (!require("devtools", quietly = TRUE)) {
devtools::install_github("zhanghao-njmu/SCP")
```
-#### Create SCP python environment
+#### Create a python environment for SCP
To run functions such as `RunPAGA` or `RunSCVELO`, SCP requires
[conda](https://docs.conda.io/en/latest/miniconda.html) to create a
@@ -253,7 +253,7 @@ CellDimPlot(
)
```
-
+
``` r
CellDimPlot(
@@ -262,7 +262,7 @@ CellDimPlot(
)
```
-
+
``` r
FeatureDimPlot(
@@ -271,7 +271,7 @@ FeatureDimPlot(
)
```
-
+
``` r
FeatureDimPlot(
@@ -281,7 +281,7 @@ FeatureDimPlot(
)
```
-
+
``` r
ht <- GroupHeatmap(
@@ -303,7 +303,7 @@ ht <- GroupHeatmap(
print(ht$plot)
```
-
+
### CellQC
@@ -312,13 +312,13 @@ pancreas_sub <- RunCellQC(srt = pancreas_sub)
CellDimPlot(srt = pancreas_sub, group.by = "CellQC", reduction = "UMAP")
```
-
+
``` r
CellStatPlot(srt = pancreas_sub, stat.by = "CellQC", group.by = "CellType", label = TRUE)
```
-
+
``` r
CellStatPlot(
@@ -331,7 +331,7 @@ CellStatPlot(
)
```
-
+
### Standard pipeline
@@ -343,19 +343,19 @@ CellDimPlot(
)
```
-
+
``` r
CellDimPlot3D(srt = pancreas_sub, group.by = "SubCellType")
```
-![CellDimPlot3D](README/README-CellDimPlot3D-1.png)
+![CellDimPlot3D](man/figures/CellDimPlot3D-1.png)
``` r
FeatureDimPlot3D(srt = pancreas_sub, features = c("Sox9", "Neurog3", "Fev", "Rbp4"))
```
-![FeatureDimPlot3D](README/README-FeatureDimPlot3D-1.png)
+![FeatureDimPlot3D](man/figures/FeatureDimPlot3D-1.png)
### Integration pipeline
@@ -371,11 +371,11 @@ CellDimPlot(
)
```
-
+
UMAP embeddings based on different integration methods in SCP:
-![Integration-all](README/README-Integration-all.png)
+![Integration-all](man/figures/Integration-all.png)
### Cell projection between single-cell datasets
@@ -392,7 +392,7 @@ ProjectionPlot(
)
```
-
+
### Cell annotation using bulk RNA-seq datasets
@@ -402,7 +402,7 @@ pancreas_sub <- RunKNNPredict(srt_query = pancreas_sub, bulk_ref = ref_scMCA, fi
CellDimPlot(srt = pancreas_sub, group.by = "KNNPredict_classification", reduction = "UMAP", label = TRUE)
```
-
+
### Cell annotation using single-cell datasets
@@ -414,7 +414,7 @@ pancreas_sub <- RunKNNPredict(
CellDimPlot(srt = pancreas_sub, group.by = "KNNPredict_classification", reduction = "UMAP", label = TRUE)
```
-
+
``` r
@@ -426,7 +426,7 @@ pancreas_sub <- RunKNNPredict(
CellDimPlot(srt = pancreas_sub, group.by = "KNNPredict_classification", reduction = "UMAP", label = TRUE)
```
-
+
``` r
@@ -439,7 +439,7 @@ ht <- CellCorHeatmap(
print(ht$plot)
```
-
+
### PAGA analysis
@@ -451,7 +451,7 @@ pancreas_sub <- RunPAGA(
PAGAPlot(srt = pancreas_sub, reduction = "UMAP", label = TRUE, label_insitu = TRUE, label_repel = TRUE)
```
-
+
### Velocity analysis
@@ -470,13 +470,13 @@ pancreas_sub <- RunSCVELO(
VelocityPlot(srt = pancreas_sub, reduction = "UMAP", group_by = "SubCellType")
```
-
+
``` r
VelocityPlot(srt = pancreas_sub, reduction = "UMAP", plot_type = "stream")
```
-
+
### Differential expression analysis
@@ -485,7 +485,7 @@ pancreas_sub <- RunDEtest(srt = pancreas_sub, group_by = "CellType", fc.threshol
VolcanoPlot(srt = pancreas_sub, group_by = "CellType")
```
-
+
``` r
DEGs <- pancreas_sub@tools$DEtest_CellType$AllMarkers_wilcox
@@ -501,7 +501,7 @@ ht <- FeatureHeatmap(
print(ht$plot)
```
-
+
### Enrichment analysis(over-representation)
@@ -516,7 +516,7 @@ EnrichmentPlot(
)
```
-
+
``` r
EnrichmentPlot(
@@ -525,7 +525,7 @@ EnrichmentPlot(
)
```
-
+
``` r
EnrichmentPlot(
@@ -534,7 +534,7 @@ EnrichmentPlot(
)
```
-
+
``` r
EnrichmentPlot(
@@ -543,7 +543,7 @@ EnrichmentPlot(
)
```
-
+
> To ensure that labels are visible, you can adjust the size of the
> viewer panel on Rstudio IDE.
@@ -555,13 +555,13 @@ EnrichmentPlot(
)
```
-
+
``` r
EnrichmentPlot(srt = pancreas_sub, group_by = "CellType", plot_type = "comparison")
```
-
+
### Enrichment analysis(GSEA)
@@ -573,7 +573,7 @@ pancreas_sub <- RunGSEA(
GSEAPlot(srt = pancreas_sub, group_by = "CellType", group_use = "Endocrine", id_use = "GO:0007186")
```
-
+
``` r
GSEAPlot(
@@ -582,13 +582,13 @@ GSEAPlot(
)
```
-
+
``` r
GSEAPlot(srt = pancreas_sub, group_by = "CellType", plot_type = "comparison")
```
-
+
### Trajectory inference
@@ -596,19 +596,19 @@ GSEAPlot(srt = pancreas_sub, group_by = "CellType", plot_type = "comparison")
pancreas_sub <- RunSlingshot(srt = pancreas_sub, group.by = "SubCellType", reduction = "UMAP")
```
-
+
``` r
FeatureDimPlot(pancreas_sub, features = paste0("Lineage", 1:3), reduction = "UMAP", theme_use = "theme_blank")
```
-
+
``` r
CellDimPlot(pancreas_sub, group.by = "SubCellType", reduction = "UMAP", lineages = paste0("Lineage", 1:3), lineages_span = 0.1)
```
-
+
### Dynamic features
@@ -627,7 +627,7 @@ ht <- DynamicHeatmap(
print(ht$plot)
```
-
+
``` r
DynamicPlot(
@@ -637,7 +637,7 @@ DynamicPlot(
)
```
-
+
``` r
FeatureStatPlot(
@@ -651,7 +651,7 @@ FeatureStatPlot(
)
```
-
+
### Interactive data visualization with SCExplorer
@@ -665,15 +665,15 @@ if (interactive()) {
}
```
-![SCExplorer1](README/README-SCExplorer-1.png)
-![SCExplorer2](README/README-SCExplorer-2.png)
+![SCExplorer1](man/figures/SCExplorer-1.png)
+![SCExplorer2](man/figures/SCExplorer-2.png)
### Other visualization examples
-[**CellDimPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellDimPlot.html)![Example1](README/README-Example-1.jpg)
-[**CellStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellStatPlot.html)![Example2](README/README-Example-2.jpg)
-[**FeatureStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/FeatureStatPlot.html)![Example3](README/README-Example-3.jpg)
-[**GroupHeatmap**](https://zhanghao-njmu.github.io/SCP/reference/GroupHeatmap.html)![Example3](README/README-Example-4.jpg)
+[**CellDimPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellDimPlot.html)![Example1](man/figures/Example-1.jpg)
+[**CellStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/CellStatPlot.html)![Example2](man/figures/Example-2.jpg)
+[**FeatureStatPlot**](https://zhanghao-njmu.github.io/SCP/reference/FeatureStatPlot.html)![Example3](man/figures/Example-3.jpg)
+[**GroupHeatmap**](https://zhanghao-njmu.github.io/SCP/reference/GroupHeatmap.html)![Example3](man/figures/Example-4.jpg)
You can also find more examples in the documentation of the function:
[Integration_SCP](https://zhanghao-njmu.github.io/SCP/reference/Integration_SCP.html),
diff --git a/inst/python/__pycache__/SCP_analysis.cpython-38.pyc b/inst/python/__pycache__/SCP_analysis.cpython-38.pyc
index bd20026c47b0377e9943bee5aebcd1b2faf27f95..c569e89cdff4a36ee06472a8a0dc4b60a3b6b154 100644
GIT binary patch
delta 7041
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
delta 9065
zcmcgxd2pM@b^pE(ATE;P34#>wn;^ma5HIl(MahR~N}?{x6a;ZW3ZFoLT0mAL?-wYQ
zWXlIz+M7ueXC?+`632>T=TPG$9e1j9GE>)WJ#pN)>6gZF+$OPG*OR!ZGu1S0-`fua
zL5cG5Pk_M>Z{O~|-M9Pp?Y`YlKO(njKDAQ
z@?%X69vhK}g`~mPPRzsszjXLzkW6ADTY$`2X
z-B4Oub!iSeyY|@ugcE)y_(lFWQ<8{Gq@c7YYn8G=D_WJ{nY3#0Z`NwWf0|ayYE=tS
zqE=#BR%9uWvTaD&jZ{ojacFg{E}p(BY4z}*!Rpk^_!d^aDzD0k#s-k(Ahq=8@fmtrr
z7%yZVY-lCp{BgcdX_l+_1!a$1&0kgy09|7Wq`Qdolx;6|<%+}<
z7-|^oWix15Vw9mjW|i^QRS7s{D+>J|R;jj;%6NOUgGj7`R4phMl~tLQl4>zFRXk`e
z&uV7PYBzJRbW*#lXf6B+bLCu1yyuFfR*||QX;l_f&Y;9v;@bpWpXBBNw@NKhd!av>
zYzs4!2GJkuxU^!Q{i@c=S{G!kjg$kn6A7?`H~~9ZD=$l{jdiguXr-}8(z*rJ1XK@F
z@d2TQ!EJz9v2f^bXQd
z1RZ(YQsk^rcLHOabV615URJP&yv0&GY!s~`IYm%mRo40#lx2O%QhjC=TSdACr3BSI
zXmEOjjK?jtau@%Oz}GFcZo>}J=x$z
z>}*$e!|e2fz4R}eARp8Nd$Q0aA!i^d2TUGvK@Rk)kHAo<6JTF`%d)x)tfv6w8S9PJg$>(O
zHaP{ow?O}g$sGxe%GJF>BjhT~#Ijiqxl^p^yOz^IH)Bm(>7S>pX)AqmKLWyMZV_&$yHgag!!p|7WT8_>6S8ATPfPA4vygF2i1oUp
zdGok5Tc?e%5ilT+I(*8qVyBk`eSnP+@R8&=uGJO$=}Tfg99$m-;)A+vnyAS}gtdD>
z_6d+Z;*x}!dQ>4LmLlf55OYY(T1rRAT+$fV29}6U`a$>kTXc8Ou@v1MRJ}#_g_LoP
z8M}AeE>;_5qk?sw4ZuKvzX31RBgEZ{ijez_#gM4T
zVB@)MJvOQigX5KF6>Ur?i?fW*W|WPAgP#S*z7-uibVnnxEU>&!vN32h20z>eo#X=i
za4~;sIXk(&GU%fzBa}g(ziEWVK-?d}7@0PnHejsLuPd824sFL$8)p`Bkz86(;9QE$
zUtZplY(A4ZHZ5di4X|`fIy>dwEmc&`F9yheZ(s>Vz_c2oWAPmVd
zas|*!9wHA1Wb()|o_>yzL=GRxa>JB3n37q%SS-$FQ-@36l^~j*){HrYswNt?jrxXt3p1)UvUk|$9Q&Ow>-lq3ahO%Y19`w<>ikRj#ebQM9ZRBQK8NrG!sm_5bJ3IG
z&{_H&{+DG>Y&nEHbJR~4b%o6H#qwI~YY;d{jtrjN)WI|NTluTK`TUpVPs@e;Pbwa9
zV1@8uJz&68B4B`E
z0#gnnd=TgUbP+vdB%+5*h#t1YvshV5^pGv0hnz(8@Kz#fFrtUNMD&oajbixV6yZaG
z2p_%=VM9S8d?<*!HiQoaB77)>=%FYPJt*hjFrs%}?P8Ql#wLVt`fhVV}aI)YdRdy)DH!awt?qtH
zNd6Szb%f&xVp;zTsW%XQj_@XcZjE>s{2_ltw=Z-o8YIOap7tPgAp9%BFAxs!`TD66
zW5r|ohX8IfjUb)y13#?ym;Vma*tMC=pdX|Y@2Rssx)7nqFykyg*iZ+)LTf18c@Y_x
z5H2G;fbbxIyN_N$`XPje0cLD-{$LQDiEdf)g@`XgAH_Ue%=`xp;e&5s>Wc_pLU;<{
zSp-~P^f`pDA$%R-8wlS-xQ6f*1YDr>D#CSyR}j9;pLBQ1uku&j?fpMO#%loXW@A47
z5gB4q(9eFzq{KdWQvM4iypMpBk}^kPzHd7pzr@170??H?sw+!`zKxuuhok?7N%U@=
zH@P?Z@0in&1P@TUZ3m3;J{aTe;MpQ?a$D2Ge5L8$LfD_6g?aj`Cq9Rt?+(A6j}`B~
zX7+sBBEQF9=%|v-{AV26ZcYj3wWKPpIIde%gurZy`L7@NF#N
zAk=r(yFh(QCw23gMc)#A5%c~5^DK*gk`wTS^fWjf_|DP4!<=WiysbOM>f1hw)%Rn~
z0R#tM+SVv%@Xv4SQwva07eXPz2b;54$ij@bV&UWZ}4A?*3I3>$9+B!@&&!<
zbt3&0lVBM)vTx>ImBk=lHPJj2(~DBi09=)IOUUaFEJUu_b?aipif`zB*!5Qix|Lfu#|zAmH1z7$%Z-I&ey?kHKjk(-nWhshI>7R=tn$lbfw
z?OS(%B`*cT(O}>N74ub`oV29r)89iIx@}GRn$JFWxCF}zYZr!|G)TjHS7L4zf?1z?Lz0(km1a-ka{k%0EDO
zp119E#c=)5daNf_3@#S>BLMg4$1-?53#KjAi|96B_<~C(ePTupd(hJjBUqr}GfR3F
z7*w-iXMz!-gU}Cs%SJn+=#A+R!Z82Ooh`8uB*n(ifYb*sr@OGo`bt_~U2s1u(Yp~g
z*)BF+U2Z6>XZtIJ8H)}Z#@vWPnh-n)&HVaAMNWzqhO+!O6Zyq@*3z60XG8VRMFZhb
zM7O{w!R9~*c*U+eEpXEdQH(rqcJIlBV;4CHfU!GZlb~PpJ1S=Tpt{
zB>&!&vqm`PuY$Chw0U0?dX8qRTcY70IQPV9gWs5HkD(D62ZoMKElEYmL4-ws89T0P
z?>r4J&R7K*4buylkxu<{zTn)MAhh-&lf6E>Tjd@QEaq5v&@i_1Q6`$dvG*A{#vk3c
zT{iKT_Wf<_GSr+y*SYpVACDe$2mB%jEh!HpFuWqNP_z>9Z_-NPUkREQ)3mZgo<%Dc
zc~-4L{M)oj@o(3R#}tQF&8pROVv1%EGn~p}QX-itl4~h=EW#tZsG6nKz?C>WjX>a3
z6VHL0;M{l~D@qA}@9HHiO0%?b+Y9mcXk_DQm=FVHLa)(UOIGXP$K!?j;KT)cZA=xQZ0YoAvt
zAl7OnIY>egs0QjNr=Md@ct0PlW^Md4gPsnS3EJ3K%(RPT3B7;<=~>aHXfw-9T(HZt
zk_IIiyiRDHylvQ7)OiYo!rPRjHZY3_>S{3_f=7Zk23+v`f|_@2s`(oCX3f|5Vw{BL
zYn+d*d2AESO{ag&vS4_U+Fyi+IOF93u5Q|r%I}Vrk^GA=Rv`yaPL_4i2qRmBs^+!V
z7`WiFURH2qfe$y4@WRy%7h!D>Y<9Dlo!OX!xR%ZE=!DD;cxFl`g-~c4q&w9vwoN=Y
z*zj^5ZqW1K4!vmEuJy7W43gvBt0=aC6c54!6)6#o^oXFj0#xW#x2e4le}cu3GI#=m
zsa;is1@y5#s8<_Pd*SBS40nZ)fcJ|&cz&%QmEz{td|Ghh{UBx_K1jrs0+YP8SXOYi
z16Mp#Zs5YZkVu!SL+UUD#1>KpFFsY`nzwKzjXutb)e%x1?~jfWSm0YpP2%yuh0lKw
zcdu70-%#BK$@VQj7MFS8|}|7-@jJxG~}e
z+yT$XO>iUUSqA;qa|WeDQV8M`{2q})%3+ugcw}y#q*>r2sW^hhKKuwu+tEpPAao&g
zBlI9_L+C~5M;JvIL)d{Zj<6G90$^Gk0qHJGcVY9pk?Ix~0CymHC&F#F(DC)d9bG>=
zBsb2KZB^{3$pZug;pbu>`#@(LzU@A)G*%Lm&tP2!4cjv0OtEJV5D|@pB>HVmM~Pn*m@*HvZVI
zQzLS&;*f2!O>rpsvRTdrx