From 3a18fe4df6bb925dc4c5c0a112f7db6dca043fca Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 7 Mar 2023 16:31:45 -0500 Subject: [PATCH 001/259] Bump version to 1.11.9 --- .Rbuildignore | 1 + DESCRIPTION | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index 6ca55cba..4ee9d1c6 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -14,3 +14,4 @@ $run_dev.* ^pkgdown$ ^codecov\.yml$ ^\.github$ +^spatialLIBD\.Rproj$ diff --git a/DESCRIPTION b/DESCRIPTION index 67777959..c6cfca24 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.8 +Version: 1.11.9 Date: 2023-02-22 Authors@R: c( From 5e6afb7f3b17a5f8f5fded499965a0a516b9e398 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 7 Mar 2023 17:42:56 -0500 Subject: [PATCH 002/259] Remove un-needed gene_in_set line from test --- tests/testthat/test-gene_set_enrichment.R | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-gene_set_enrichment.R b/tests/testthat/test-gene_set_enrichment.R index 019707cd..015d7b6f 100644 --- a/tests/testthat/test-gene_set_enrichment.R +++ b/tests/testthat/test-gene_set_enrichment.R @@ -20,23 +20,22 @@ asd_sfari <- utils::read.csv( modeling_results <- fetch_data(type = "modeling_results") } - + ## Compute the gene set enrichment results asd_sfari_enrichment <- gene_set_enrichment( gene_list = asd_sfari_geneList, modeling_results = modeling_results, model_type = "enrichment" ) - + test_that("result for each gene list & model test", { - expect_equal(nrow(asd_sfari_enrichment), + expect_equal(nrow(asd_sfari_enrichment), length(asd_sfari_geneList)*length(grep("fdr",colnames(modeling_results$enrichment)))) }) ## check behavior for OR < 1 results WM_enriched <- modeling_results$enrichment$fdr_WM < 0.1 & modeling_results$enrichment$t_stat_WM > 0 -gene_in_set <- experiment_genes %in% asd_sfari_geneList$Gene_SFARI_all safari_no_wm_enrich <- asd_sfari_geneList$Gene_SFARI_all[asd_sfari_geneList$Gene_SFARI_all %in% modeling_results$enrichment$ensembl[!WM_enriched]] From 694c1165a2c3f8bcedcbc9e60914971b928d4bee Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 10 Mar 2023 10:12:57 -0500 Subject: [PATCH 003/259] Update code style --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 ++-- R/annotate_registered_clusters.R | 16 ++-- R/check_sce.R | 69 ++++++++-------- R/check_spe.R | 15 ++-- R/fetch_data.R | 31 ++++---- R/frame_limits.R | 21 +++-- R/gene_set_enrichment.R | 39 ++++++---- R/gene_set_enrichment_plot.R | 23 +++--- R/geom_spatial.R | 17 ++-- R/img_edit.R | 37 +++++---- R/img_update.R | 13 ++-- R/img_update_all.R | 11 ++- R/layer_boxplot.R | 27 ++++--- R/layer_matrix_plot.R | 27 ++++--- R/layer_stat_cor.R | 11 ++- R/layer_stat_cor_plot.R | 11 ++- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 +++-- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 ++-- R/registration_stats_anova.R | 17 ++-- R/registration_stats_enrichment.R | 15 ++-- R/registration_stats_pairwise.R | 15 ++-- R/registration_wrapper.R | 19 +++-- R/run_app.R | 95 +++++++++++------------ R/sig_genes_extract.R | 11 +-- R/sig_genes_extract_all.R | 7 +- R/vis_clus.R | 47 ++++++----- R/vis_clus_p.R | 23 +++--- R/vis_gene.R | 29 ++++--- R/vis_gene_p.R | 35 ++++----- R/vis_grid_clus.R | 31 ++++---- R/vis_grid_gene.R | 37 +++++---- tests/testthat/test-gene_set_enrichment.R | 92 ++++++++++++---------- 35 files changed, 447 insertions(+), 458 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index dbe49f86..de4f5fee 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,9 +29,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function( - spe, - visium_analysis) { +add10xVisiumAnalysis <- function(spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index e7b09e5c..bfdddbe5 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,13 +43,12 @@ #' )) #' } add_images <- - function( - spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function(spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index 13e1d5ab..c2a9ec43 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,10 +48,9 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function( - cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function(cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -87,11 +86,10 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function( - remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function(remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 1d625342..0d17423b 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,41 +24,40 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function( - sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function(sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index d0344daa..47de3c0a 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,14 +25,13 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function( - spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function(spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index 6540ea21..89bfe53e 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -55,21 +55,22 @@ #' ## Explore the data #' sce_layer fetch_data <- - function(type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function( + type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index 320cc643..b22b5c8a 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,17 +37,16 @@ #' } #' frame_limits <- - function( - spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function(spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index 2fcb944f..1accea28 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -3,7 +3,7 @@ #' Using the layer-level (group-level) data, this function evaluates whether #' list of gene sets (Ensembl gene IDs) are enriched among the significant #' genes (FDR < 0.1 by default) genes for a given model type result. Test the -#' alternative hypothesis that OR > 1, i.e. that gene set is over-represented in the +#' alternative hypothesis that OR > 1, i.e. that gene set is over-represented in the #' set of enriched genes. If you want to check depleted genes, change `reverse` #' to `TRUE`. #' @@ -58,12 +58,11 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function( - gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function(gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present @@ -71,16 +70,18 @@ gene_set_enrichment <- x <- x[!is.na(x)] x[x %in% model_results$ensembl] }) - + ## warn about low power for small geneLists geneList_length <- sapply(geneList_present, length) min_genes <- 25 - if(any(geneList_length < min_genes)){ - warning( - "Gene list with n < ",min_genes," may have insufficent power for enrichment analysis: ", - paste(names(geneList_length)[geneList_length < 200], collapse = " ,") - ) - } + if (any(geneList_length < min_genes)) { + warning( + "Gene list with n < ", + min_genes, + " may have insufficent power for enrichment analysis: ", + paste(names(geneList_length)[geneList_length < 200], collapse = " ,") + ) + } tstats <- model_results[, grep("[f|t]_stat_", colnames(model_results))] @@ -95,7 +96,10 @@ gene_set_enrichment <- paste(rev(x), collapse = "-") }, character(1)) } else if (model_type == "anova") { - stop("reverse = TRUE does not work with model_type = anova since F-statistics cannot have negative values.", call. = FALSE) + stop( + "reverse = TRUE does not work with model_type = anova since F-statistics cannot have negative values.", + call. = FALSE + ) } } @@ -112,8 +116,9 @@ gene_set_enrichment <- Layer = factor(layer, c(FALSE, TRUE)) ) }) - - enrichList <- lapply(tabList, fisher.test, alternative = "greater") + + enrichList <- + lapply(tabList, fisher.test, alternative = "greater") o <- data.frame( OR = vapply(enrichList, "[[", numeric(1), "estimate"), Pval = vapply(enrichList, "[[", numeric(1), "p.value"), diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index c155e672..4ccbfcbc 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,18 +84,17 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function( - enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function(enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 965db758..64f00cc3 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,15 +58,14 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function( - mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function(mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index 93aceee3..ec6fae90 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,25 +58,24 @@ #' plot(x) #' } img_edit <- - function( - spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function(spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index fdfe5b83..db6dfcb1 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,13 +41,12 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function( - spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 314b9b0d..31c368c9 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,12 +22,11 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function( - spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 6a671a5e..345d5499 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,20 +114,19 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function( - i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function(i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index 4a44fd18..f1530fb1 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,20 +55,19 @@ #' cex = 2 #' ) layer_matrix_plot <- - function( - matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function(matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index f484c912..0ccf0bf2 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,12 +49,11 @@ #' top_n = 10 #' )) layer_stat_cor <- - function( - stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function(stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 0d2653b8..c0f4e924 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,12 +72,11 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function( - cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function(cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 7864f0b6..83dffc38 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,9 +24,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 7be0b325..2b9d862e 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,17 +44,16 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 6921dbb9..3f36260c 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,10 +24,9 @@ #' head(registration_mod) #' registration_model <- - function( - sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function(sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 1e115847..2e4a0e96 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,13 +51,12 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index d1d0b135..c899459d 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,15 +50,14 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index cd3ee182..d186547e 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,13 +34,14 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index 09bb3ff9..afb9771a 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,13 +32,14 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function(sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 19cc3097..5c8cb982 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,16 +50,15 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { sce_pseudo <- registration_pseudobulk(sce, var_registration = var_registration, diff --git a/R/run_app.R b/R/run_app.R index 21fb0ebc..dd6820f3 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -182,54 +182,53 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function( - spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - ...) { +run_app <- function(spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index fac5f65b..b21902c1 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,11 +59,12 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index 0d68b880..d2c3c01f 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,9 +27,10 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index 58ee8289..a4b006c8 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -75,30 +75,29 @@ #' ) #' print(p3) #' } -vis_clus <- function( - spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - ...) { +vis_clus <- function(spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index cd8b720a..34aecaef 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,18 +42,17 @@ #' rm(spe_sub) #' } vis_clus_p <- - function( - spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE) { + function(spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE) { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 708e4f53..712800de 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -113,21 +113,20 @@ #' print(p5) #' } vis_gene <- - function( - spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 9bc3dc0a..e659d477 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,24 +48,23 @@ #' rm(spe_sub) #' } vis_gene_p <- - function( - spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function(spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 40ec7aee..6c90221c 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,22 +47,21 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function( - spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - ...) { + function(spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index 2504cce5..e21b5bf1 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,25 +35,24 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function( - spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/tests/testthat/test-gene_set_enrichment.R b/tests/testthat/test-gene_set_enrichment.R index 015d7b6f..e0e1a0f2 100644 --- a/tests/testthat/test-gene_set_enrichment.R +++ b/tests/testthat/test-gene_set_enrichment.R @@ -1,51 +1,59 @@ - asd_sfari <- utils::read.csv( - system.file( - "extdata", - "SFARI-Gene_genes_01-03-2020release_02-04-2020export.csv", - package = "spatialLIBD" - ), - as.is = TRUE - ) + system.file( + "extdata", + "SFARI-Gene_genes_01-03-2020release_02-04-2020export.csv", + package = "spatialLIBD" + ), + as.is = TRUE +) - ## Format them appropriately - asd_sfari_geneList <- list( - Gene_SFARI_all = asd_sfari$ensembl.id, - Gene_SFARI_high = asd_sfari$ensembl.id[asd_sfari$gene.score < 3], - Gene_SFARI_syndromic = asd_sfari$ensembl.id[asd_sfari$syndromic == 1] - ) +## Format them appropriately +asd_sfari_geneList <- list( + Gene_SFARI_all = asd_sfari$ensembl.id, + Gene_SFARI_high = asd_sfari$ensembl.id[asd_sfari$gene.score < 3], + Gene_SFARI_syndromic = asd_sfari$ensembl.id[asd_sfari$syndromic == 1] +) - ## Obtain the necessary data - if (!exists("modeling_results")) { - modeling_results <- fetch_data(type = "modeling_results") - } +## Obtain the necessary data +if (!exists("modeling_results")) { + modeling_results <- fetch_data(type = "modeling_results") +} - ## Compute the gene set enrichment results - asd_sfari_enrichment <- gene_set_enrichment( - gene_list = asd_sfari_geneList, - modeling_results = modeling_results, - model_type = "enrichment" - ) +## Compute the gene set enrichment results +asd_sfari_enrichment <- gene_set_enrichment( + gene_list = asd_sfari_geneList, + modeling_results = modeling_results, + model_type = "enrichment" +) test_that("result for each gene list & model test", { - expect_equal(nrow(asd_sfari_enrichment), - length(asd_sfari_geneList)*length(grep("fdr",colnames(modeling_results$enrichment)))) + expect_equal( + nrow(asd_sfari_enrichment), + length(asd_sfari_geneList) * length(grep( + "fdr", colnames(modeling_results$enrichment) + )) + ) }) ## check behavior for OR < 1 results -WM_enriched <- modeling_results$enrichment$fdr_WM < 0.1 & modeling_results$enrichment$t_stat_WM > 0 +WM_enriched <- + modeling_results$enrichment$fdr_WM < 0.1 & + modeling_results$enrichment$t_stat_WM > 0 -safari_no_wm_enrich <- asd_sfari_geneList$Gene_SFARI_all[asd_sfari_geneList$Gene_SFARI_all %in% modeling_results$enrichment$ensembl[!WM_enriched]] +safari_no_wm_enrich <- + asd_sfari_geneList$Gene_SFARI_all[asd_sfari_geneList$Gene_SFARI_all %in% modeling_results$enrichment$ensembl[!WM_enriched]] -safari_edge_cases <- list(no_WM_enrich = safari_no_wm_enrich, - short = asd_sfari_geneList$Gene_SFARI_all[1:20]) +safari_edge_cases <- list( + no_WM_enrich = safari_no_wm_enrich, + short = asd_sfari_geneList$Gene_SFARI_all[1:20] +) edge_safari_enrichment <- gene_set_enrichment( - gene_list = safari_edge_cases["no_WM_enrich"], - modeling_results = modeling_results, - model_type = "enrichment" + gene_list = safari_edge_cases["no_WM_enrich"], + modeling_results = modeling_results, + model_type = "enrichment" ) ## with alternative = "two.sided" @@ -53,15 +61,15 @@ edge_safari_enrichment <- gene_set_enrichment( # 1 0.0000000 5.752600e-72 WM 0 638 no_WM_enrich enrichment 0.1 test_that("warn for small gene list", { - expect_warning(gene_set_enrichment( - gene_list = safari_edge_cases["short"], - modeling_results = modeling_results, - model_type = "enrichment") - ) + expect_warning( + gene_set_enrichment( + gene_list = safari_edge_cases["short"], + modeling_results = modeling_results, + model_type = "enrichment" + ) + ) }) -test_that("Not signficant for OR==0",{ - expect_true(all(edge_safari_enrichment$Pval[edge_safari_enrichment$OR == 0] > 0.05)) +test_that("Not signficant for OR==0", { + expect_true(all(edge_safari_enrichment$Pval[edge_safari_enrichment$OR == 0] > 0.05)) }) - - From b0c3ec9443317149c24fefe0883bcc7667f60f2f Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 10 Mar 2023 12:52:03 -0500 Subject: [PATCH 004/259] Mention changes by @lahuuki on the NEWS --- NEWS.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NEWS.md b/NEWS.md index e43f212a..cd88c4b6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# spatialLIBD 1.11.9 + +SIGNIFICANT USER-VISIBLE CHANGES + +* `gene_set_enrichment()` now internally uses +`fisher.test(alternative = "greater")` to test for odds ratios greater than 1. +Otherwise odds ratios of 0 could be significant. + # spatialLIBD 1.11.4 SIGNIFICANT USER-VISIBLE CHANGES From 4272b3c1362c3a904a091b56e4b35df65ba54eff Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 10 Mar 2023 16:58:18 -0500 Subject: [PATCH 005/259] Update GHA workflow to biocthis version 1.9.3 --- .github/workflows/check-bioc.yml | 79 ++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index 930e71a2..c0f04dd5 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -52,8 +52,8 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-latest, r: '4.2', bioc: '3.16', cont: "bioconductor/bioconductor_docker:RELEASE_3_16", rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest" } - #- { os: macOS-latest, r: '4.2', bioc: '3.16'} + - { os: ubuntu-latest, r: '4.2', bioc: '3.16', cont: "bioconductor/bioconductor_docker:RELEASE_3_16", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } + # - { os: macOS-latest, r: '4.2', bioc: '3.16'} - { os: windows-latest, r: '4.2', bioc: '3.16'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent @@ -210,13 +210,13 @@ jobs: shell: Rscript {0} - name: Install covr - if: github.ref == 'refs/heads/master' && env.run_covr == 'true' && runner.os == 'Linux' + if: github.ref == 'refs/heads/devel' && env.run_covr == 'true' && runner.os == 'Linux' run: | remotes::install_cran("covr") shell: Rscript {0} - name: Install pkgdown - if: github.ref == 'refs/heads/master' && env.run_pkgdown == 'true' && runner.os == 'Linux' + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' run: | remotes::install_cran("pkgdown") shell: Rscript {0} @@ -267,17 +267,17 @@ jobs: shell: Rscript {0} - name: Test coverage - if: github.ref == 'refs/heads/master' && env.run_covr == 'true' && runner.os == 'Linux' + if: github.ref == 'refs/heads/devel' && env.run_covr == 'true' && runner.os == 'Linux' run: | covr::codecov() shell: Rscript {0} - name: Install package - if: github.ref == 'refs/heads/master' && env.run_pkgdown == 'true' && runner.os == 'Linux' + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' run: R CMD INSTALL . - name: Build pkgdown site - if: github.ref == 'refs/heads/master' && env.run_pkgdown == 'true' && runner.os == 'Linux' + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) shell: Rscript {0} ## Note that you need to run pkgdown::deploy_to_branch(new_process = FALSE) @@ -286,12 +286,12 @@ jobs: ## makes the git history recognizable by pkgdown. - name: Install deploy dependencies - if: github.ref == 'refs/heads/master' && env.run_pkgdown == 'true' && runner.os == 'Linux' + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' run: | apt-get update && apt-get -y install rsync - name: Deploy pkgdown site to GitHub pages 🚀 - if: github.ref == 'refs/heads/master' && env.run_pkgdown == 'true' && runner.os == 'Linux' + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' uses: JamesIves/github-pages-deploy-action@releases/v4 with: clean: false @@ -305,18 +305,51 @@ jobs: name: ${{ runner.os }}-biocversion-RELEASE_3_16-r-4.2-results path: check - ## Note that DOCKER_PASSWORD is really a token for your dockerhub - ## account, not your actual dockerhub account password. - ## This comes from - ## https://seandavi.github.io/BuildABiocWorkshop/articles/HOWTO_BUILD_WORKSHOP.html#6-add-secrets-to-github-repo - ## Check https://github.com/docker/build-push-action/tree/releases/v1 - ## for more details. - - uses: docker/build-push-action@v1 - if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && runner.os == 'Linux' " + + ## Code adapted from + ## https://github.com/waldronlab/cBioPortalData/blob/e0440a4445f0cc731e426363a76faa22ee5e0f9d/.github/workflows/devel_check_dock.yml#L65-L92 + docker-build-and-push: + runs-on: ubuntu-latest + needs: build-check + steps: + - name: Checkout Repository + if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && github.ref == 'refs/heads/devel'" + uses: actions/checkout@v3 + + - name: Register repo name + if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && github.ref == 'refs/heads/devel'" + id: reg_repo_name + run: | + echo CONT_IMG_NAME=$(echo ${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV + + - name: Set up QEMU + if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && github.ref == 'refs/heads/devel'" + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && github.ref == 'refs/heads/devel'" + uses: docker/setup-buildx-action@v2 + + - name: Login to Docker Hub + if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && github.ref == 'refs/heads/devel'" + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + ## Note that DOCKERHUB_TOKEN is really a token for your dockerhub + ## account, not your actual dockerhub account password. You can get it + ## from https://hub.docker.com/settings/security. + ## Check https://github.com/docker/build-push-action/tree/v4.0.0 + ## for more details. + ## Alternatively, try checking + ## https://seandavi.github.io/BuildABiocWorkshop/articles/HOWTO_BUILD_WORKSHOP.html. + + - name: Build and Push Docker + if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && github.ref == 'refs/heads/devel' && success()" + uses: docker/build-push-action@v4 with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - repository: lieberinstitute/spatiallibd - tag_with_ref: true - tag_with_sha: true - tags: latest + context: . + push: true + tags: > + ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.CONT_IMG_NAME }}:latest, + ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.CONT_IMG_NAME }}:devel From 97b852686515a271f4db3e185a9a9180a09a5db6 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Mon, 13 Mar 2023 09:55:19 -0400 Subject: [PATCH 006/259] Added support for spaceranger version 2023.0208.0 (internal 10x version) Co-authored-by: Heena Divecha --- R/read10xVisiumAnalysis.R | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 83dffc38..54236389 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -39,10 +39,13 @@ read10xVisiumAnalysis <- function(samples = "", } names(samples) <- sids - dir <- file.path(samples, "analysis") + analysis_options <- c("analysis", "analysis_csv") + dir <- file.path(rep(samples, each = length(analysis_options)), analysis_options) + dir <- dir[file.exists(dir)] + stopifnot(length(dir) == length(samples)) - current_dir <- dir[1] - current_sample <- sids[1] + # current_dir <- dir[1] + # current_sample <- sids[1] clusters_all <- do.call(rbind, mapply(function(current_dir, current_sample) { clustering_files <- @@ -101,7 +104,7 @@ read_barcoded_csv <- function(x) { colnames(df) <- tolower(colnames(df)) if (colnames(df)[2] == "cluster") { - colnames(df)[2] <- basename(dirname(x)) + colnames(df)[2] <- gsub("gene_expression_", "", basename(dirname(x))) } return(df) } From d6c8016772c56d2312d9bc4b65d82114aba11f25 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Mon, 13 Mar 2023 09:55:31 -0400 Subject: [PATCH 007/259] Auto-style code --- R/read10xVisiumAnalysis.R | 116 ++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 42 deletions(-) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 54236389..ef76f1d0 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,8 +24,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { @@ -40,60 +41,90 @@ read10xVisiumAnalysis <- function(samples = "", names(samples) <- sids analysis_options <- c("analysis", "analysis_csv") - dir <- file.path(rep(samples, each = length(analysis_options)), analysis_options) + dir <- + file.path(rep(samples, each = length(analysis_options)), analysis_options) dir <- dir[file.exists(dir)] stopifnot(length(dir) == length(samples)) # current_dir <- dir[1] # current_sample <- sids[1] - clusters_all <- do.call(rbind, mapply(function(current_dir, current_sample) { - clustering_files <- - list.files( - current_dir, - pattern = "clusters.csv", - all.files = TRUE, - full.names = TRUE, - recursive = TRUE + clusters_all <- + do.call( + rbind, + mapply( + function(current_dir, current_sample) { + clustering_files <- + list.files( + current_dir, + pattern = "clusters.csv", + all.files = TRUE, + full.names = TRUE, + recursive = TRUE + ) + + clusters_list <- lapply(clustering_files, read_barcoded_csv) + clusters <- + Reduce( + function(...) { + merge(..., by = "barcode", all = TRUE) + }, + clusters_list + ) + clusters$sample_id <- current_sample + return(clusters) + }, + dir, + sids, + SIMPLIFY = FALSE, + USE.NAMES = FALSE ) + ) - clusters_list <- lapply(clustering_files, read_barcoded_csv) - clusters <- Reduce(function(...) merge(..., by = "barcode", all = TRUE), clusters_list) - clusters$sample_id <- current_sample - return(clusters) - }, dir, sids, SIMPLIFY = FALSE, USE.NAMES = FALSE)) + projection_all <- mapply( + function(current_dir, current_sample) { + projection_files <- + list.files( + current_dir, + pattern = "projection.csv", + all.files = TRUE, + full.names = TRUE, + recursive = TRUE + ) - projection_all <- mapply(function(current_dir, current_sample) { - projection_files <- - list.files( - current_dir, - pattern = "projection.csv", - all.files = TRUE, - full.names = TRUE, - recursive = TRUE - ) + projection_list <- lapply(projection_files, function(x) { + res <- read_barcoded_csv(x) + res$sample_id <- current_sample + return(res) + }) + names(projection_list) <- + paste0("10x_", basename(dirname(dirname( + projection_files + )))) - projection_list <- lapply(projection_files, function(x) { - res <- read_barcoded_csv(x) - res$sample_id <- current_sample - return(res) - }) - names(projection_list) <- paste0("10x_", basename(dirname(dirname(projection_files)))) + return(projection_list) + }, + dir, + sids, + SIMPLIFY = FALSE, + USE.NAMES = FALSE + ) - return(projection_list) - }, dir, sids, SIMPLIFY = FALSE, USE.NAMES = FALSE) - - projection_names <- unique(unlist(lapply(projection_all, names))) - projections_combined <- lapply(projection_names, function(projection_name) { - one_projection_list <- lapply(projection_all, "[[", projection_name) - do.call(rbind, one_projection_list) - }) + projection_names <- + unique(unlist(lapply(projection_all, names))) + projections_combined <- + lapply(projection_names, function(projection_name) { + one_projection_list <- lapply(projection_all, "[[", projection_name) + do.call(rbind, one_projection_list) + }) names(projections_combined) <- projection_names - cluster_cols <- which(!colnames(clusters_all) %in% c("barcode", "sample_id")) - colnames(clusters_all)[cluster_cols] <- paste0("10x_", colnames(clusters_all)[cluster_cols]) + cluster_cols <- + which(!colnames(clusters_all) %in% c("barcode", "sample_id")) + colnames(clusters_all)[cluster_cols] <- + paste0("10x_", colnames(clusters_all)[cluster_cols]) return(list(clusters = clusters_all, projections = projections_combined)) } @@ -104,7 +135,8 @@ read_barcoded_csv <- function(x) { colnames(df) <- tolower(colnames(df)) if (colnames(df)[2] == "cluster") { - colnames(df)[2] <- gsub("gene_expression_", "", basename(dirname(x))) + colnames(df)[2] <- + gsub("gene_expression_", "", basename(dirname(x))) } return(df) } From 1ff74a8be040bf4cdbc906700913ad12fc929232 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Mon, 13 Mar 2023 09:58:56 -0400 Subject: [PATCH 008/259] v1.1.10 -- bump version and mention https://github.com/LieberInstitute/spatial_DG_lifespan/blob/main/code/02_build_spe/01_build_spe.R --- DESCRIPTION | 4 ++-- NEWS.md | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c6cfca24..d7373cce 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.9 -Date: 2023-02-22 +Version: 1.11.10 +Date: 2023-03-13 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index cd88c4b6..520dd92b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,14 @@ +# spatialLIBD 1.11.10 + +BUG FIXES + +* `read10xVisiumAnalysis()` now supports `spaceranger` version 2023.0208.0 +(internal 10x Genomics version) output files that store analysis CSVs under the +`outs/analysis_csv` directory instead of `outs/analysis` and also use the +`gene_expression_` prefix for each of the analysis directories. This was +tested with @heenadivecha on files from +. + # spatialLIBD 1.11.9 SIGNIFICANT USER-VISIBLE CHANGES From a158a2aa3101ccf0f1971f3d27d628217ddccb44 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 12:46:43 -0400 Subject: [PATCH 009/259] Finally enable fetch_data("spatialDLPFC_snRNAseq"). Sorry for the delay! With help from @lahuuki for finding the JHPCE paths as well as the function required for loading the data. Co-authored-by: Louise Huuki --- R/fetch_data.R | 57 ++++++++++++++++------- inst/extdata/metadata_spatialDLPFC.csv | 2 +- inst/scripts/make-metadata_spatialDLPFC.R | 4 +- man/fetch_data.Rd | 23 +++++++++ 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index 89bfe53e..5348d937 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -54,6 +54,29 @@ #' #' ## Explore the data #' sce_layer +#' +#' ## How to download and load "spatialDLPFC_snRNAseq" +#' \dontrun{ +#' sce_path_zip <- fetch_data("spatialDLPFC_snRNAseq") +#' sce_path <- unzip(sce_path_zip, exdir = tempdir()) +#' sce <- HDF5Array::loadHDF5SummarizedExperiment( +#' file.path(tempdir(), "sce_DLPFC_annotated") +#' ) +#' sce +#' #> class: SingleCellExperiment +#' #> dim: 36601 77604 +#' #> metadata(3): Samples cell_type_colors cell_type_colors_broad +#' #> assays(2): counts logcounts +#' #> rownames(36601): MIR1302-2HG FAM138A ... AC007325.4 AC007325.2 +#' #> rowData names(7): source type ... gene_type binomial_deviance +#' #> colnames(77604): 1_AAACCCAAGTTCTCTT-1 1_AAACCCACAAGGTCTT-1 ... 19_TTTGTTGTCTCATTGT-1 19_TTTGTTGTCTTAAGGC-1 +#' #> colData names(32): Sample Barcode ... cellType_layer layer_annotation +#' #> reducedDimNames(4): GLMPCA_approx TSNE UMAP HARMONY +#' #> mainExpName: NULL +#' #> altExpNames(0): +#' lobstr::obj_size(sce) +#' #> 172.28 MB +#' } fetch_data <- function( type = c( @@ -98,7 +121,7 @@ fetch_data <- ) ) } - + tag <- "Human_Pilot_DLPFC_Visium_spatialLIBD" hub_title <- "Human_Pilot_DLPFC_Visium_spatialLIBD_spot_level_SCE" @@ -108,6 +131,7 @@ fetch_data <- url <- "https://www.dropbox.com/s/f4wcvtdq428y73p/Human_DLPFC_Visium_processedData_sce_scran_spatialLIBD.Rdata?dl=1" } else if (type == "sce_layer") { + tag <- "Human_Pilot_DLPFC_Visium_spatialLIBD" hub_title <- "Human_Pilot_DLPFC_Visium_spatialLIBD_layer_level_SCE" ## While EH is not set-up @@ -116,6 +140,7 @@ fetch_data <- url <- "https://www.dropbox.com/s/bg8xwysh2vnjwvg/Human_DLPFC_Visium_processedData_sce_scran_sce_layer_spatialLIBD.Rdata?dl=1" } else if (type == "modeling_results") { + tag <- "Human_Pilot_DLPFC_Visium_spatialLIBD" hub_title <- "Human_Pilot_DLPFC_Visium_spatialLIBD_modeling_results" ## While EH is not set-up @@ -123,6 +148,7 @@ fetch_data <- url <- "https://www.dropbox.com/s/se6rrgb9yhm5gfh/Human_DLPFC_Visium_modeling_results.Rdata?dl=1" } else if (type == "sce_example") { + tag <- "Human_Pilot_DLPFC_Visium_spatialLIBD" hub_title <- "Human_DLPFC_Visium_sce_example" ## While EH is not set-up @@ -138,7 +164,7 @@ fetch_data <- ) ) } - + tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" hub_title <- "spatialDLPFC_Visium_spe" ## While EH is not set-up @@ -147,6 +173,7 @@ fetch_data <- url <- "https://www.dropbox.com/s/y2ifv5v8g68papf/spe_filtered_final_with_clusters_and_deconvolution_results.rds?dl=1" } else if (type == "spatialDLPFC_Visium_pseudobulk") { + tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" hub_title <- "spatialDLPFC_Visium_pseudobulk_spe" ## While EH is not set-up @@ -155,6 +182,7 @@ fetch_data <- url <- "https://www.dropbox.com/s/pbti4strsfk1m55/sce_pseudo_BayesSpace_k09.rds?dl=1" } else if (type == "spatialDLPFC_Visium_modeling_results") { + tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" hub_title <- "spatialDLPFC_Visium_modeling_results" ## While EH is not set-up @@ -163,6 +191,7 @@ fetch_data <- url <- "https://www.dropbox.com/s/srkb2ife75px2yz/modeling_results_BayesSpace_k09.Rdata?dl=1" } else if (type == "spatialDLPFC_Visium_SPG") { + tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" hub_title <- "spatialDLPFC_Visium_SPG_spe" ## While EH is not set-up @@ -171,22 +200,14 @@ fetch_data <- url <- "https://www.dropbox.com/s/nbf13dna9ibqfaa/spe.rds?dl=1" } else if (type == "spatialDLPFC_snRNAseq") { - if (!enough_ram(10e+09)) { - warning( - paste( - "Your system might not have enough memory available (10GB).", - "Try with a machine that has more memory." - ) - ) - } - + tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" hub_title <- "spatialDLPFC_snRNAseq" ## While EH is not set-up file_name <- - "TBD" + "sce_DLPFC_annotated.zip" url <- - "TBD?dl=1" + "https://www.dropbox.com/s/5919zt00vm1ht8e/sce_DLPFC_annotated.zip?dl=1" } file_path <- file.path(destdir, file_name) @@ -194,7 +215,7 @@ fetch_data <- if (!file.exists(file_path)) { q <- AnnotationHub::query(eh, - pattern = c("Human_Pilot_DLPFC_Visium_spatialLIBD", hub_title) + pattern = c(tag, hub_title) ) if (length(q) == 1) { @@ -212,7 +233,7 @@ fetch_data <- } } - ## Now load the data + ## Now load the data if possible message(Sys.time(), " loading file ", file_path) if (grepl(".Rdata", file_path)) { load(file_path, verbose = FALSE) @@ -225,8 +246,12 @@ fetch_data <- } else if (type == "sce_example") { return(.update_sce(sce_sub)) } + } else if (grepl(".rds", file_path)) { + return(readRDS(file_path)) + } else { + file_path } - readRDS(file_path) + } diff --git a/inst/extdata/metadata_spatialDLPFC.csv b/inst/extdata/metadata_spatialDLPFC.csv index f5d66b39..4e6d8b78 100644 --- a/inst/extdata/metadata_spatialDLPFC.csv +++ b/inst/extdata/metadata_spatialDLPFC.csv @@ -3,4 +3,4 @@ "spatialDLPFC_Visium_pseudobulk_spe","Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/sce_pseudo_BayesSpace_k09.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" "spatialDLPFC_Visium_modeling_results","List of modeling results at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","list","Rda","spatialLIBD/spatialLIBD_files/modeling_results_BayesSpace_k09.Rdata","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" "spatialDLPFC_Visium_SPG","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 4) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spe.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" -"spatialDLPFC_snRNAseq","SingleCellExperiment object for the spatialDLPFC human brain (DLPFC) single nucleus transcriptomics data (snRNA-seq, n = 19) from the Chromium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SingleCellExperiment","Rds","spatialLIBD/spatialLIBD_files/TBD.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" +"spatialDLPFC_snRNAseq","SingleCellExperiment object for the spatialDLPFC human brain (DLPFC) single nucleus transcriptomics data (snRNA-seq, n = 19) from the Chromium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SingleCellExperiment","FilePath","spatialLIBD/spatialLIBD_files/sce_DLPFC_annotated.zip","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" diff --git a/inst/scripts/make-metadata_spatialDLPFC.R b/inst/scripts/make-metadata_spatialDLPFC.R index f502414a..f93e751b 100644 --- a/inst/scripts/make-metadata_spatialDLPFC.R +++ b/inst/scripts/make-metadata_spatialDLPFC.R @@ -38,7 +38,7 @@ meta <- data.frame( "SpatialExperiment", "SingleCellExperiment" ), - DispatchClass = c("Rds", "Rds", "Rda", "Rds", "Rds"), + DispatchClass = c("Rds", "Rds", "Rda", "Rds", "FilePath"), RDataPath = file.path( pkgname, outdir, @@ -47,7 +47,7 @@ meta <- data.frame( "sce_pseudo_BayesSpace_k09.rds", "modeling_results_BayesSpace_k09.Rdata", "spe.rds", - "TBD.rds" + "sce_DLPFC_annotated.zip" ) ), Tags = "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD", diff --git a/man/fetch_data.Rd b/man/fetch_data.Rd index a14c2cc3..3f755c0d 100644 --- a/man/fetch_data.Rd +++ b/man/fetch_data.Rd @@ -70,4 +70,27 @@ if (!exists("sce_layer")) sce_layer <- fetch_data("sce_layer") ## Explore the data sce_layer + +## How to download and load "spatialDLPFC_snRNAseq" +\dontrun{ +sce_path_zip <- fetch_data("spatialDLPFC_snRNAseq") +sce_path <- unzip(sce_path_zip, exdir = tempdir()) +sce <- HDF5Array::loadHDF5SummarizedExperiment( + file.path(tempdir(), "sce_DLPFC_annotated") +) +sce +#> class: SingleCellExperiment +#> dim: 36601 77604 +#> metadata(3): Samples cell_type_colors cell_type_colors_broad +#> assays(2): counts logcounts +#> rownames(36601): MIR1302-2HG FAM138A ... AC007325.4 AC007325.2 +#> rowData names(7): source type ... gene_type binomial_deviance +#> colnames(77604): 1_AAACCCAAGTTCTCTT-1 1_AAACCCACAAGGTCTT-1 ... 19_TTTGTTGTCTCATTGT-1 19_TTTGTTGTCTTAAGGC-1 +#> colData names(32): Sample Barcode ... cellType_layer layer_annotation +#> reducedDimNames(4): GLMPCA_approx TSNE UMAP HARMONY +#> mainExpName: NULL +#> altExpNames(0): +lobstr::obj_size(sce) +#> 172.28 MB +} } From cc640380cbb31e6d9d63601ff9daa74aaf428910 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 12:47:10 -0400 Subject: [PATCH 010/259] v1.11.11 -- bump version number --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d7373cce..6f457809 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.10 -Date: 2023-03-13 +Version: 1.11.11 +Date: 2023-03-17 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From c730374f1be7c484cf3849718a5428838bb44808 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 16:20:50 -0400 Subject: [PATCH 011/259] Copy make-metadata_spatialDLPFC.R as make-metadata_Visium_SPG_AD.R --- inst/scripts/make-metadata_Visium_SPG_AD.R | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 inst/scripts/make-metadata_Visium_SPG_AD.R diff --git a/inst/scripts/make-metadata_Visium_SPG_AD.R b/inst/scripts/make-metadata_Visium_SPG_AD.R new file mode 100644 index 00000000..280c603e --- /dev/null +++ b/inst/scripts/make-metadata_Visium_SPG_AD.R @@ -0,0 +1,75 @@ +library("here") +library("sessioninfo") + + +outdir <- "spatialLIBD_files" +pkgname <- "spatialLIBD" + + +meta <- data.frame( + Title = c( + "spatialDLPFC_Visium_spe", + "spatialDLPFC_Visium_pseudobulk_spe", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq" + ), + Description = c( + "SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "List of modeling results at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 4) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "SingleCellExperiment object for the spatialDLPFC human brain (DLPFC) single nucleus transcriptomics data (snRNA-seq, n = 19) from the Chromium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package." + ), + BiocVersion = "3.17", + Genome = "GRCh38", + SourceType = "GTF", + SourceUrl = "https://bioconductor.org/packages/spatialLIBD", + SourceVersion = "Feb 13 2022", + Species = "Homo sapiens", + TaxonomyId = 9606, + Coordinate_1_based = TRUE, + DataProvider = "LIBD", + Maintainer = "Leonardo Collado-Torres ", + RDataClass = c( + "SpatialExperiment", + "SpatialExperiment", + "list", + "SpatialExperiment", + "SingleCellExperiment" + ), + DispatchClass = c("Rds", "Rds", "Rda", "Rds", "FilePath"), + RDataPath = file.path( + pkgname, + outdir, + c( + "spe_filtered_final_with_clusters_and_deconvolution_results.rds", + "sce_pseudo_BayesSpace_k09.rds", + "modeling_results_BayesSpace_k09.Rdata", + "spe.rds", + "sce_DLPFC_annotated.zip" + ) + ), + Tags = "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD", + row.names = NULL, + stringsAsFactors = FALSE +) + +write.csv( + meta, + file = here::here("inst", "extdata", "metadata_spatialDLPFC.csv"), + row.names = FALSE +) + +## Check +if (FALSE) { + AnnotationHubData::makeAnnotationHubMetadata(here::here(), fileName = "metadata_spatialDLPFC.csv") +} + +## Reproducibility information +print("Reproducibility information:") +Sys.time() +proc.time() +options(width = 120) +session_info() + From 0df0b9068ee6880abfdb5a0508c59ce66a7fbf90 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 16:56:59 -0400 Subject: [PATCH 012/259] Update the NEWS to mention that fetch_data("spatialDLPFC_snRNAseq") now works --- NEWS.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS.md b/NEWS.md index 520dd92b..c0636674 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +# spatialLIBD 1.11.11 + +SIGNIFICANT USER-VISIBLE CHANGES + +* `fetch_data("spatialDLPFC_snRNAseq")` now works if you want to download +the snRNA-seq data used in . + # spatialLIBD 1.11.10 BUG FIXES From dd617e426519095c85c2b8a453fa07f83c36d47f Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 16:59:02 -0400 Subject: [PATCH 013/259] Fix date --- inst/extdata/metadata_spatialDLPFC.csv | 10 +++++----- inst/scripts/make-metadata_spatialDLPFC.R | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/inst/extdata/metadata_spatialDLPFC.csv b/inst/extdata/metadata_spatialDLPFC.csv index 4e6d8b78..eed6daaa 100644 --- a/inst/extdata/metadata_spatialDLPFC.csv +++ b/inst/extdata/metadata_spatialDLPFC.csv @@ -1,6 +1,6 @@ "Title","Description","BiocVersion","Genome","SourceType","SourceUrl","SourceVersion","Species","TaxonomyId","Coordinate_1_based","DataProvider","Maintainer","RDataClass","DispatchClass","RDataPath","Tags" -"spatialDLPFC_Visium_spe","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spe_filtered_final_with_clusters_and_deconvolution_results.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" -"spatialDLPFC_Visium_pseudobulk_spe","Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/sce_pseudo_BayesSpace_k09.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" -"spatialDLPFC_Visium_modeling_results","List of modeling results at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","list","Rda","spatialLIBD/spatialLIBD_files/modeling_results_BayesSpace_k09.Rdata","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" -"spatialDLPFC_Visium_SPG","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 4) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spe.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" -"spatialDLPFC_snRNAseq","SingleCellExperiment object for the spatialDLPFC human brain (DLPFC) single nucleus transcriptomics data (snRNA-seq, n = 19) from the Chromium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Feb 13 2022","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SingleCellExperiment","FilePath","spatialLIBD/spatialLIBD_files/sce_DLPFC_annotated.zip","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" +"spatialDLPFC_Visium_spe","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spe_filtered_final_with_clusters_and_deconvolution_results.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" +"spatialDLPFC_Visium_pseudobulk_spe","Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/sce_pseudo_BayesSpace_k09.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" +"spatialDLPFC_Visium_modeling_results","List of modeling results at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","list","Rda","spatialLIBD/spatialLIBD_files/modeling_results_BayesSpace_k09.Rdata","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" +"spatialDLPFC_Visium_SPG","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 4) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spe.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" +"spatialDLPFC_snRNAseq","SingleCellExperiment object for the spatialDLPFC human brain (DLPFC) single nucleus transcriptomics data (snRNA-seq, n = 19) from the Chromium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SingleCellExperiment","FilePath","spatialLIBD/spatialLIBD_files/sce_DLPFC_annotated.zip","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" diff --git a/inst/scripts/make-metadata_spatialDLPFC.R b/inst/scripts/make-metadata_spatialDLPFC.R index f93e751b..7e250d79 100644 --- a/inst/scripts/make-metadata_spatialDLPFC.R +++ b/inst/scripts/make-metadata_spatialDLPFC.R @@ -25,7 +25,7 @@ meta <- data.frame( Genome = "GRCh38", SourceType = "GTF", SourceUrl = "https://bioconductor.org/packages/spatialLIBD", - SourceVersion = "Feb 13 2022", + SourceVersion = "Mar 17 2023", Species = "Homo sapiens", TaxonomyId = 9606, Coordinate_1_based = TRUE, From 7793546517cf3db79b3da9d03c9ef98de6c35ef3 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 16:59:47 -0400 Subject: [PATCH 014/259] Create metadata for ExperimentHub entries for the ]Visium_SPG_AD data. Related to https://github.com/LieberInstitute/Visium_SPG_AD/issues/53 --- inst/extdata/metadata_Visium_SPG_AD.csv | 5 +++ inst/scripts/make-metadata_Visium_SPG_AD.R | 40 ++++++++++------------ 2 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 inst/extdata/metadata_Visium_SPG_AD.csv diff --git a/inst/extdata/metadata_Visium_SPG_AD.csv b/inst/extdata/metadata_Visium_SPG_AD.csv new file mode 100644 index 00000000..7fb11177 --- /dev/null +++ b/inst/extdata/metadata_Visium_SPG_AD.csv @@ -0,0 +1,5 @@ +"Title","Description","BiocVersion","Genome","SourceType","SourceUrl","SourceVersion","Species","TaxonomyId","Coordinate_1_based","DataProvider","Maintainer","RDataClass","DispatchClass","RDataPath","Tags" +"Visium_SPG_AD_Visium_wholegenome_spe","SpatialExperiment object at the spot-level for the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (at the whole genome level) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rda","spatialLIBD/spatialLIBD_files/Visium_SPG_AD_spe_wholegenome.Rdata","Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" +"Visium_SPG_AD_Visium_targeted_spe","SpatialExperiment object at the spot-level for the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (with a targeted sequencing panel) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rda","spatialLIBD/spatialLIBD_files/Visium_SPG_AD_spe_targeted.Rdata","Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" +"Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe","Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) for the seven Alzheimer's Disease (AD) pathology levels from the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (at the whole genome level) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/sce_pseudo_pathology_wholegenome.rds","Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" +"Visium_SPG_AD_Visium_wholegenome_modeling_results","List of modeling results for the seven Alzheimer's Disease (AD) pathology levels from the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (at the whole genome level) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","list","Rds","spatialLIBD/spatialLIBD_files/Visium_IF_AD_modeling_results.Rdata","Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" diff --git a/inst/scripts/make-metadata_Visium_SPG_AD.R b/inst/scripts/make-metadata_Visium_SPG_AD.R index 280c603e..2c14dc1f 100644 --- a/inst/scripts/make-metadata_Visium_SPG_AD.R +++ b/inst/scripts/make-metadata_Visium_SPG_AD.R @@ -8,24 +8,22 @@ pkgname <- "spatialLIBD" meta <- data.frame( Title = c( - "spatialDLPFC_Visium_spe", - "spatialDLPFC_Visium_pseudobulk_spe", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq" + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" ), Description = c( - "SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", - "Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", - "List of modeling results at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", - "SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 4) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", - "SingleCellExperiment object for the spatialDLPFC human brain (DLPFC) single nucleus transcriptomics data (snRNA-seq, n = 19) from the Chromium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package." + "SpatialExperiment object at the spot-level for the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (at the whole genome level) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "SpatialExperiment object at the spot-level for the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (with a targeted sequencing panel) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) for the seven Alzheimer's Disease (AD) pathology levels from the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (at the whole genome level) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "List of modeling results for the seven Alzheimer's Disease (AD) pathology levels from the Visium_SPG_AD human brain (inferior temporal cortex ITC) Alzheimer's Disease (AD) spatial transcriptomics data (n = 10) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics (at the whole genome level) generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package." ), BiocVersion = "3.17", Genome = "GRCh38", SourceType = "GTF", SourceUrl = "https://bioconductor.org/packages/spatialLIBD", - SourceVersion = "Feb 13 2022", + SourceVersion = "Mar 17 2023", Species = "Homo sapiens", TaxonomyId = 9606, Coordinate_1_based = TRUE, @@ -34,36 +32,34 @@ meta <- data.frame( RDataClass = c( "SpatialExperiment", "SpatialExperiment", - "list", "SpatialExperiment", - "SingleCellExperiment" + "list" ), - DispatchClass = c("Rds", "Rds", "Rda", "Rds", "FilePath"), + DispatchClass = c("Rda", "Rda", "Rds", "Rds"), RDataPath = file.path( pkgname, outdir, c( - "spe_filtered_final_with_clusters_and_deconvolution_results.rds", - "sce_pseudo_BayesSpace_k09.rds", - "modeling_results_BayesSpace_k09.Rdata", - "spe.rds", - "sce_DLPFC_annotated.zip" + "Visium_SPG_AD_spe_wholegenome.Rdata", + "Visium_SPG_AD_spe_targeted.Rdata", + "sce_pseudo_pathology_wholegenome.rds", + "Visium_IF_AD_modeling_results.Rdata" ) ), - Tags = "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD", + Tags = "Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD", row.names = NULL, stringsAsFactors = FALSE ) write.csv( meta, - file = here::here("inst", "extdata", "metadata_spatialDLPFC.csv"), + file = here::here("inst", "extdata", "metadata_Visium_SPG_AD.csv"), row.names = FALSE ) ## Check if (FALSE) { - AnnotationHubData::makeAnnotationHubMetadata(here::here(), fileName = "metadata_spatialDLPFC.csv") + AnnotationHubData::makeAnnotationHubMetadata(here::here(), fileName = "metadata_Visium_SPG_AD.csv") } ## Reproducibility information From a4809e3a3b3026ed3b7d18ad60d19d3fcd05af98 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 17:00:11 -0400 Subject: [PATCH 015/259] Update fetch_data() to now enable access to the data from Visium_SPG_AD Resolve https://github.com/LieberInstitute/Visium_SPG_AD/issues/53 --- R/fetch_data.R | 68 ++++++++++++++++++++++++++++++++++++++--------- man/fetch_data.Rd | 31 +++++++++++++-------- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index 5348d937..d9db9f63 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -1,12 +1,14 @@ #' Download the Human DLPFC Visium data from LIBD #' -#' This function downloads from `ExperimentHub` the dorsolateral prefrontal -#' cortex (DLPFC) human Visium data and results analyzed by LIBD. If -#' `ExperimentHub` is not available, it will download the files from Dropbox -#' using [utils::download.file()] unless the files are present already at -#' `destdir`. Note that `ExperimentHub` will cache the data and automatically -#' detect if you have previously downloaded it, thus making it the preferred -#' way to interact with the data. +#' This function downloads from `ExperimentHub` Visium, Visium Spatial +#' Proteogenomics (Visium-SPG), or single nucleus RNA-seq (snRNA-seq) data +#' and results analyzed by LIBD from multiple projects. +#' If `ExperimentHub` is not available, this function will +#' download the files from Dropbox using [BiocFileCache::bfcrpath()] unless the +#' files are present already at `destdir`. Note that `ExperimentHub` and +#' `BiocFileCache` will cache the data and automatically detect if you have +#' previously downloaded it, thus making it the preferred way to interact with +#' the data. #' #' @param type A `character(1)` specifying which file you want to download. It #' can either be: `sce` for the @@ -19,10 +21,14 @@ #' or `modeling_results` for the list of tables with the `enrichment`, #' `pairwise`, and `anova` model results from the layer-level data. It can also #' be `sce_example` which is a reduced version of `sce` just for example -#' purposes. As of BioC version 3.13 `spe` downloads a +#' purposes. The initial version of `spatialLIBD` downloaded data only from +#' . As of BioC version 3.13 +#' `spe` downloads a #' [SpatialExperiment-class][SpatialExperiment::SpatialExperiment-class] object. -#' As of version 1.11.6 this function also allows downloading data from the -#' project. +#' As of version 1.11.6, this function also allows downloading data from the +#' project. As of version 1.11.12, +#' data from can be +#' downloaded. #' #' @param destdir The destination directory to where files will be downloaded #' to in case the `ExperimentHub` resource is not available. If you already @@ -89,7 +95,11 @@ fetch_data <- "spatialDLPFC_Visium_pseudobulk", "spatialDLPFC_Visium_modeling_results", "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq" + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" ), destdir = tempdir(), eh = ExperimentHub::ExperimentHub(), @@ -183,7 +193,7 @@ fetch_data <- "https://www.dropbox.com/s/pbti4strsfk1m55/sce_pseudo_BayesSpace_k09.rds?dl=1" } else if (type == "spatialDLPFC_Visium_modeling_results") { tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" - hub_title <- "spatialDLPFC_Visium_modeling_results" + hub_title <- type ## While EH is not set-up file_name <- @@ -201,13 +211,45 @@ fetch_data <- "https://www.dropbox.com/s/nbf13dna9ibqfaa/spe.rds?dl=1" } else if (type == "spatialDLPFC_snRNAseq") { tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" - hub_title <- "spatialDLPFC_snRNAseq" + hub_title <- type ## While EH is not set-up file_name <- "sce_DLPFC_annotated.zip" url <- "https://www.dropbox.com/s/5919zt00vm1ht8e/sce_DLPFC_annotated.zip?dl=1" + } else if (type == "Visium_SPG_AD_Visium_wholegenome_spe") { + tag <- "Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" + hub_title <- type + + ## While EH is not set-up + file_name <- "Visium_SPG_AD_spe_wholegenome.Rdata" + url <- + "https://www.dropbox.com/s/ng036m63grykdm6/Visium_SPG_AD_spe_wholegenome.Rdata?dl=1" + } else if (type == "Visium_SPG_AD_Visium_targeted_spe") { + tag <- "Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" + hub_title <- type + + ## While EH is not set-up + file_name <- "Visium_SPG_AD_spe_targeted.Rdata" + url <- + "https://www.dropbox.com/s/kda9160awc2h8jq/Visium_SPG_AD_spe_targeted.Rdata?dl=1" + } else if (type == "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe") { + tag <- "Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" + hub_title <- type + + ## While EH is not set-up + file_name <- "sce_pseudo_pathology_wholegenome.rds" + url <- + "https://www.dropbox.com/s/p8foxj6t6inb8uf/sce_pseudo_pathology_wholegenome.rds?dl=1" + } else if (type == "Visium_SPG_AD_Visium_wholegenome_modeling_results") { + tag <- "Visium_SPG_AD_Alzheimer_Disease_ITC_spatialLIBD" + hub_title <- type + + ## While EH is not set-up + file_name <- "Visium_IF_AD_modeling_results.Rdata" + url <- + "https://www.dropbox.com/s/5plupu8bj5m0kfh/Visium_IF_AD_modeling_results.Rdata?dl=1" } file_path <- file.path(destdir, file_name) diff --git a/man/fetch_data.Rd b/man/fetch_data.Rd index 3f755c0d..eebb2d2b 100644 --- a/man/fetch_data.Rd +++ b/man/fetch_data.Rd @@ -8,7 +8,10 @@ fetch_data( type = c("sce", "sce_layer", "modeling_results", "sce_example", "spe", "spatialDLPFC_Visium", "spatialDLPFC_Visium_pseudobulk", "spatialDLPFC_Visium_modeling_results", "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq"), + "spatialDLPFC_snRNAseq", "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results"), destdir = tempdir(), eh = ExperimentHub::ExperimentHub(), bfc = BiocFileCache::BiocFileCache() @@ -26,10 +29,14 @@ object containing the layer-level data (pseudo-bulked from the spot-level), or \code{modeling_results} for the list of tables with the \code{enrichment}, \code{pairwise}, and \code{anova} model results from the layer-level data. It can also be \code{sce_example} which is a reduced version of \code{sce} just for example -purposes. As of BioC version 3.13 \code{spe} downloads a +purposes. The initial version of \code{spatialLIBD} downloaded data only from +\url{https://github.com/LieberInstitute/HumanPilot}. As of BioC version 3.13 +\code{spe} downloads a \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} object. -As of version 1.11.6 this function also allows downloading data from the -\url{http://research.libd.org/spatialDLPFC/} project.} +As of version 1.11.6, this function also allows downloading data from the +\url{http://research.libd.org/spatialDLPFC/} project. As of version 1.11.12, +data from \url{https://github.com/LieberInstitute/Visium_SPG_AD} can be +downloaded.} \item{destdir}{The destination directory to where files will be downloaded to in case the \code{ExperimentHub} resource is not available. If you already @@ -49,13 +56,15 @@ you have to assign to an object. If you didn't you can still avoid re-loading the object by using \code{.Last.value}. } \description{ -This function downloads from \code{ExperimentHub} the dorsolateral prefrontal -cortex (DLPFC) human Visium data and results analyzed by LIBD. If -\code{ExperimentHub} is not available, it will download the files from Dropbox -using \code{\link[utils:download.file]{utils::download.file()}} unless the files are present already at -\code{destdir}. Note that \code{ExperimentHub} will cache the data and automatically -detect if you have previously downloaded it, thus making it the preferred -way to interact with the data. +This function downloads from \code{ExperimentHub} Visium, Visium Spatial +Proteogenomics (Visium-SPG), or single nucleus RNA-seq (snRNA-seq) data +and results analyzed by LIBD from multiple projects. +If \code{ExperimentHub} is not available, this function will +download the files from Dropbox using \code{\link[BiocFileCache:BiocFileCache-class]{BiocFileCache::bfcrpath()}} unless the +files are present already at \code{destdir}. Note that \code{ExperimentHub} and +\code{BiocFileCache} will cache the data and automatically detect if you have +previously downloaded it, thus making it the preferred way to interact with +the data. } \details{ The data was initially prepared by scripts at From 09d142741d629e444890d2bf255d4efc58b7c9b7 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 17:00:30 -0400 Subject: [PATCH 016/259] v1.11.12 -- update the NEWS and bump version --- DESCRIPTION | 2 +- NEWS.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 6f457809..16d7a786 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.11 +Version: 1.11.12 Date: 2023-03-17 Authors@R: c( diff --git a/NEWS.md b/NEWS.md index c0636674..76a7067b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,14 @@ +# spatialLIBD 1.11.12 + +SIGNIFICANT USER-VISIBLE CHANGES + +* `fetch_data("Visium_SPG_AD_Visium_wholegenome_spe"")`, +`fetch_data("Visium_SPG_AD_Visium_targeted_spe")`, +`fetch_data("Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe")`, and + `fetch_data("Visium_SPG_AD_Visium_wholegenome_modeling_results")` have been + added. Use this to access data from the + project. + # spatialLIBD 1.11.11 SIGNIFICANT USER-VISIBLE CHANGES From 4b5d6e5de4ccd7c283767d4408372b22f31dd67c Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 17 Mar 2023 17:08:10 -0400 Subject: [PATCH 017/259] Fix a few parts of fetch_data() for the new data from Visium_SPG_AD Related to https://github.com/LieberInstitute/Visium_SPG_AD/issues/53 --- R/fetch_data.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index d9db9f63..dead44ec 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -283,10 +283,12 @@ fetch_data <- return(.update_sce(sce)) } else if (type == "sce_layer") { return(.update_sce_layer(sce_layer)) - } else if (type == "modeling_results" || type == "spatialDLPFC_Visium_modeling_results") { + } else if (type == "modeling_results" || type == "spatialDLPFC_Visium_modeling_results" || type == "Visium_SPG_AD_Visium_wholegenome_modeling_results") { return(modeling_results) } else if (type == "sce_example") { return(.update_sce(sce_sub)) + } else if (type == "Visium_SPG_AD_Visium_wholegenome_spe" || type == "Visium_SPG_AD_Visium_targeted_spe") { + return(spe) } } else if (grepl(".rds", file_path)) { return(readRDS(file_path)) From 93bbd91f945a3c1f7a3d572e04ce2a7a43bf6b7b Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 7 Apr 2023 23:08:03 -0400 Subject: [PATCH 018/259] Use an oxford comma --- inst/app/www/documentation_sce_layer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/app/www/documentation_sce_layer.md b/inst/app/www/documentation_sce_layer.md index d2b31881..3912d871 100644 --- a/inst/app/www/documentation_sce_layer.md +++ b/inst/app/www/documentation_sce_layer.md @@ -1,7 +1,7 @@ Layer-level `spatialLIBD` documentation ======================================= -This document describes the layer-level portion of the shiny web application made by the [`spatialLIBD`](https://bioconductor.org/packages/spatialLIBD) Bioconductor package. You can either find the documentation about this package through [Bioconductor](https://bioconductor.org/packages/spatialLIBD) or at the [`spatialLIBD` documentation website](http://lieberinstitute.github.io/spatialLIBD). Below we explain the options common across tabs and each of the tabs at the layer-level data. As explained in the documentation, the layer-level data is the result of pseudo-bulking the spot-level data to compress it, reduce sparsity and power more analyses. +This document describes the layer-level portion of the shiny web application made by the [`spatialLIBD`](https://bioconductor.org/packages/spatialLIBD) Bioconductor package. You can either find the documentation about this package through [Bioconductor](https://bioconductor.org/packages/spatialLIBD) or at the [`spatialLIBD` documentation website](http://lieberinstitute.github.io/spatialLIBD). Below we explain the options common across tabs and each of the tabs at the layer-level data. As explained in the documentation, the layer-level data is the result of pseudo-bulking the spot-level data to compress it, reduce sparsity, and power more analyses. ## Slides and videos From 17be05e3ec8196c0ee00b58259a1b5ca40f65ae8 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sat, 8 Apr 2023 13:18:04 -0400 Subject: [PATCH 019/259] Add citation info for the spatialDLPFC and Visium_SPG_AD projects since the data from those projects is available through spatialLIBD::fetch_data(). This will make the citations (aka links to papers) also show up on the Bioconductor landing page. It's what we did also with recount2. --- inst/CITATION | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/inst/CITATION b/inst/CITATION index 1351d786..839baee9 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -43,5 +43,65 @@ c( journal = "Nature Neuroscience", doi = "10.1038/s41593-020-00787-0", url = "https://www.nature.com/articles/s41593-020-00787-0" + ), + bibentry(bibtype="article", + title = "Integrated single cell and unsupervised spatial transcriptomic analysis defines molecular anatomy of the human dorsolateral prefrontal cortex", + author = personList( + as.person("Louise A. Huuki-Myers"), + as.person("Abby Spangler"), + as.person("Nicholas J. Eagles"), + as.person("Kelsey D. Montgomergy"), + as.person("Sang Ho Kwon"), + as.person("Boyi Guo"), + as.person("Melissa Grant-Peters"), + as.person("Heena R. Divecha"), + as.person("Madhavi Tippani"), + as.person("Chaichontat Sriworarat"), + as.person("Annie B. Nguyen"), + as.person("Prashanthi Ravichandran"), + as.person("Matthew N. Tran"), + as.person("Arta Seyedian"), + as.person("PsychENCODE Consortium"), + as.person("Thomas M. Hyde"), + as.person("Joel E. Kleinman"), + as.person("Alexis Battle"), + as.person("Stephanie C. Page"), + as.person("Mina Ryten"), + as.person("Stephanie C. Hicks"), + as.person("Keri Martinowich"), + as.person("Leonardo Collado-Torres"), + as.person("Kristen R. Maynard") + ), + year = 2023, + journal = "bioRxiv", + doi = "10.1101/2023.02.15.528722", + url = "https://www.biorxiv.org/content/10.1101/2023.02.15.528722v1" + ), + bibentry(bibtype="article", + title = "Influence of Alzheimer’s disease related neuropathology on local microenvironment gene expression in the human inferior temporal cortex", + author = personList( + as.person("Sang Ho Kwon"), + as.person("Sowmya Parthiban"), + as.person("Madhavi Tippani"), + as.person("Heena R. Divecha"), + as.person("Nicholas J. Eagles"), + as.person("Jashandeep S. Lobana"), + as.person("Stephen Williams"), + as.person("Michelle Mak"), + as.person("Guixia Yu"), + as.person("Julianna Avalos-Gracia"), + as.person("Rahul A. Bharadwaj"), + as.person("Joel E. Kleinman"), + as.person("Thomas M. Hyde"), + as.person("Stephanie C. Page"), + as.person("Stephanie C. Hicks"), + as.person("Keri Martinowich"), + as.person("Kristen R. Maynard") + as.person("Leonardo Collado-Torres") + ), + year = 2023, + journal = "bioRxiv", + doi = "10.1101/2023.04.TODO", + url = "https://www.biorxiv.org/content/10.1101/2023.04.TODO" ) ) From 0ae784442e324461206a5e61f90ca4cb90d85e5d Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sat, 8 Apr 2023 13:18:44 -0400 Subject: [PATCH 020/259] Document the spatialDLPFC and Visium_SPG_AD projects. Also document locus-c and link to the external WeberDivechaLCdata R/Bioconductor package. --- vignettes/spatialLIBD.Rmd | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vignettes/spatialLIBD.Rmd b/vignettes/spatialLIBD.Rmd index 4e86fa60..fa258567 100644 --- a/vignettes/spatialLIBD.Rmd +++ b/vignettes/spatialLIBD.Rmd @@ -77,6 +77,8 @@ bib <- c( SpatialExperiment = citation("SpatialExperiment")[1], spatialLIBD = citation("spatialLIBD")[1], spatialLIBDpaper = citation("spatialLIBD")[2], + spatialDLPFC = citation("spatialLIBD")[3], + VisiumSPGAD = citation("spatialLIBD")[4], statmod = citation("statmod")[1], SummarizedExperiment = citation("SummarizedExperiment")[1], testthat = citation("testthat")[1], @@ -571,6 +573,37 @@ If you are interested in reshaping your data to fit our structure, we do not pro You don't necessarily need to do all of this to use the functions provided by `r Biocpkg('spatialLIBD')`. Note that external to the R objects, for the `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')` you will need to have the `tissue_lowres_image.png` image files in a directory structure by sample as shown [here](https://github.com/LieberInstitute/spatialLIBD/tree/master/inst/app/www/data) in order for the interactive visualizations made with `r CRANpkg('plotly')` to work. +# More spatially-resolved LIBD datasets + +Over time `spatialLIBD::fetch_data()` has been expanded to provide access to other datasets generated by our teams at the Lieber Institute for Brain Development ([LIBD](libd.org)) that have also been analyzed with `spatialLIBD`. + +## spatialDLPFC + +Through `spatialLIBD::fetch_data()` you can also download the data from the [_Integrated single cell and unsupervised spatial transcriptomic analysis defines molecular anatomy of the human dorsolateral prefrontal cortex_](https://www.biorxiv.org/content/10.1101/2023.02.15.528722v1) project, also known as `spatialDLPFC` `r Citep(bib[['spatialDLPFC']])`. See http://research.libd.org/spatialDLPFC/ for more information about this project. + +See the Twitter thread 🧵 below for a brief overview of the [`#spatialDLPFC`](https://twitter.com/search?q=%23spatialDLPFC&src=typed_query) project. + + + +## Visium_SPG_AD + +Through `spatialLIBD::fetch_data()` you can also download the data from the [_Influence of Alzheimer’s disease related neuropathology on local microenvironment gene expression in the human inferior temporal cortex _](https://www.biorxiv.org/content/10.1101/2023.04.TODO) project, also known as `Visium_SPG_AD` `r Citep(bib[['VisiumSPGAD']])`. See http://research.libd.org/Visium_SPG_AD/ for more information about this project. + +See the Twitter thread 🧵 below for a brief overview of the [`#Visium_SPG_AD`](https://twitter.com/search?q=%23Visium_SPG_AD&src=typed_query) project. + +TODO + +## LIBD data outside `spatialLIBD` + +Sometimes our collaborators have shared data through other venues. So not all LIBD spatially-resolved transcriptomics data from the [Keri Martinowich](https://www.libd.org/team/keri-martinowich-phd/), [Kristen Maynard](https://www.libd.org/team/kristen-maynard-phd/), and [Leonardo Collado-Torres](http://lcolladotor.github.io/) teams has been released through `spatialLIBD`. However, it is very much compatible with `spatialLIBD` and can be analyzed or visualized with `spatialLIBD` functions. + +### locus-c + +[_The gene expression landscape of the human locus coeruleus revealed by single-nucleus and spatially-resolved transcriptomics_](https://www.biorxiv.org/content/10.1101/2022.10.28.514241v1), also known as `locus-c`, is not available through `spatialLIBD`, but you might be interested in checking out the excellent `r Biocpkg("WeberDivechaLCdata")` package for more details. See https://github.com/lmweber/locus-c for more details about the `locus-c` project. + +See the Twitter thread 🧵 below for a brief overview of the `locus-c` project. + + # Reproducibility From f5ff0e77abb5fab9946918fe31050e573f542fc2 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sat, 8 Apr 2023 13:20:43 -0400 Subject: [PATCH 021/259] Document on the NEWS the edits to the vignette --- NEWS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS.md b/NEWS.md index 76a7067b..b8cb77f2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.11.13 + +SIGNIFICANT USER-VISIBLE CHANGES + +* The vignette now has a section describing the data from the `spatialDLFPC`, +`Visium_SPG_AD`, and `locus-c` projects that were done by members of the +Keri Martinowich, Kristen R. Maynard, and Leonardo Collado-Torres LIBD teams as +well as our collaborators. + # spatialLIBD 1.11.12 SIGNIFICANT USER-VISIBLE CHANGES From 7b2a9891428967744ab4adf152188d4b591903da Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sat, 8 Apr 2023 13:20:53 -0400 Subject: [PATCH 022/259] v1.11.13 --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 16d7a786..5c61b973 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.12 -Date: 2023-03-17 +Version: 1.11.13 +Date: 2023-04-08 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From 5e25e4b0fa12516cfda6fc34bc7b46ee1b6f5863 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sat, 8 Apr 2023 13:34:24 -0400 Subject: [PATCH 023/259] Add missing comma --- inst/CITATION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/CITATION b/inst/CITATION index 839baee9..e64e4e7b 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -96,7 +96,7 @@ c( as.person("Stephanie C. Page"), as.person("Stephanie C. Hicks"), as.person("Keri Martinowich"), - as.person("Kristen R. Maynard") + as.person("Kristen R. Maynard"), as.person("Leonardo Collado-Torres") ), year = 2023, From 52c9caf5f79ff341c6ee5984fadc7769d0925e9d Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sat, 8 Apr 2023 14:41:26 -0400 Subject: [PATCH 024/259] Fix speackerdeck syntax. Drop link to BioTuring since they no longer have our webinar listed --- inst/app/www/documentation_sce_layer.md | 4 ++-- inst/app/www/documentation_spe.md | 4 ++-- inst/spe_wrapper_app/www/documentation_spe.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/inst/app/www/documentation_sce_layer.md b/inst/app/www/documentation_sce_layer.md index 3912d871..12105287 100644 --- a/inst/app/www/documentation_sce_layer.md +++ b/inst/app/www/documentation_sce_layer.md @@ -7,9 +7,9 @@ This document describes the layer-level portion of the shiny web application mad You might find the following slides useful for understanding the features from this part of the web application. Particularly slides 10-12 and 15-22. - + -These slides were part of our 2021-04-27 webinar for BioTuring that you can watch from [their website](https://bioturing.com/sources/webinar/60752954a433e26dd8affcbd) or YouTube: +These slides were part of our 2021-04-27 webinar for BioTuring that you can watch on YouTube: diff --git a/inst/app/www/documentation_spe.md b/inst/app/www/documentation_spe.md index 0daae913..68e374ae 100644 --- a/inst/app/www/documentation_spe.md +++ b/inst/app/www/documentation_spe.md @@ -7,9 +7,9 @@ This document describes the spot-level portion of the shiny web application made You might find the following slides useful for understanding the features from this part of the web application. - + -These slides were part of our 2021-04-27 webinar for BioTuring that you can watch from [their website](https://bioturing.com/sources/webinar/60752954a433e26dd8affcbd) or YouTube: +These slides were part of our 2021-04-27 webinar for BioTuring that you can watch on YouTube: diff --git a/inst/spe_wrapper_app/www/documentation_spe.md b/inst/spe_wrapper_app/www/documentation_spe.md index fea08d52..45df9d1c 100644 --- a/inst/spe_wrapper_app/www/documentation_spe.md +++ b/inst/spe_wrapper_app/www/documentation_spe.md @@ -7,9 +7,9 @@ This document describes the spot-level portion of the shiny web application made You might find the following slides useful for understanding the features from this part of the web application. - + -These slides were part of our 2021-04-27 webinar for BioTuring that you can watch from [their website](https://bioturing.com/sources/webinar/60752954a433e26dd8affcbd) or YouTube: +These slides were part of our 2021-04-27 webinar for BioTuring that you can watch on YouTube: From 7bbea8c52e0b104f0526c31abd9c867f89f7941b Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Mon, 24 Apr 2023 11:21:43 -0400 Subject: [PATCH 025/259] v1.11.14 -- update Visium SPG AD's citation info --- DESCRIPTION | 4 ++-- inst/CITATION | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5c61b973..3dd5df84 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.13 -Date: 2023-04-08 +Version: 1.11.14 +Date: 2023-04-24 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/inst/CITATION b/inst/CITATION index e64e4e7b..36731c8c 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -86,10 +86,8 @@ c( as.person("Heena R. Divecha"), as.person("Nicholas J. Eagles"), as.person("Jashandeep S. Lobana"), - as.person("Stephen Williams"), - as.person("Michelle Mak"), - as.person("Guixia Yu"), - as.person("Julianna Avalos-Gracia"), + as.person("Stephen R. Williams"), + as.person("Michelle Mark"), as.person("Rahul A. Bharadwaj"), as.person("Joel E. Kleinman"), as.person("Thomas M. Hyde"), @@ -101,7 +99,7 @@ c( ), year = 2023, journal = "bioRxiv", - doi = "10.1101/2023.04.TODO", - url = "https://www.biorxiv.org/content/10.1101/2023.04.TODO" + doi = "10.1101/2023.04.20.537710", + url = "https://www.biorxiv.org/content/10.1101/2023.04.20.537710v1" ) ) From 5eacc616050bcad415755ea337cd7d67de1dbb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Pag=C3=A8s?= Date: Tue, 25 Apr 2023 10:48:31 -0400 Subject: [PATCH 026/259] bump x.y.z version to even y prior to creation of RELEASE_3_17 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3dd5df84..03b1bc6e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.14 +Version: 1.12.0 Date: 2023-04-24 Authors@R: c( From 0f27d32323b05ee776b49728fc406711ab22faa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Pag=C3=A8s?= Date: Tue, 25 Apr 2023 10:48:31 -0400 Subject: [PATCH 027/259] bump x.y.z version to odd y following creation of RELEASE_3_17 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 03b1bc6e..5ec4418c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.12.0 +Version: 1.13.0 Date: 2023-04-24 Authors@R: c( From 16ebd70e88db204e61225afc0f22b5d587630cdc Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 26 Apr 2023 15:06:39 -0400 Subject: [PATCH 028/259] Create vignette with biocthis::use_bioc_vignette --- vignettes/guide_to_spatial_registration.Rmd | 165 ++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 vignettes/guide_to_spatial_registration.Rmd diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd new file mode 100644 index 00000000..3d7a7dea --- /dev/null +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -0,0 +1,165 @@ +--- +title: "Guide to Spatial Registration" +author: + - name: Your name + affiliation: + - Your institution + email: your.email@somewhere.com +output: + BiocStyle::html_document: + self_contained: yes + toc: true + toc_float: true + toc_depth: 2 + code_folding: show +date: "`r doc_date()`" +package: "`r pkg_ver('spatialLIBD')`" +vignette: > + %\VignetteIndexEntry{Guide to Spatial Registration} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + crop = NULL ## Related to https://stat.ethz.ch/pipermail/bioc-devel/2020-April/016656.html +) +``` + + +```{r vignetteSetup, echo=FALSE, message=FALSE, warning = FALSE} +## Track time spent on making the vignette +startTime <- Sys.time() + +## Bib setup +library("RefManageR") + +## Write bibliography information +bib <- c( + R = citation(), + BiocStyle = citation("BiocStyle")[1], + knitr = citation("knitr")[1], + RefManageR = citation("RefManageR")[1], + rmarkdown = citation("rmarkdown")[1], + sessioninfo = citation("sessioninfo")[1], + testthat = citation("testthat")[1], + spatialLIBD = citation("spatialLIBD")[1] +) +``` + +# Basics + +## Install `spatialLIBD` + +`R` is an open-source statistical environment which can be easily modified to enhance its functionality via packages. `r Biocpkg("spatialLIBD")` is a `R` package available via the [Bioconductor](http://bioconductor.org) repository for packages. `R` can be installed on any operating system from [CRAN](https://cran.r-project.org/) after which you can install `r Biocpkg("spatialLIBD")` by using the following commands in your `R` session: + +```{r "install", eval = FALSE} +if (!requireNamespace("BiocManager", quietly = TRUE)) { + install.packages("BiocManager") + } + +BiocManager::install("spatialLIBD") + +## Check that you have a valid Bioconductor installation +BiocManager::valid() +``` + +## Required knowledge + +`r Biocpkg("spatialLIBD")` is based on many other packages and in particular in those that have implemented the infrastructure needed for dealing with RNA-seq data (EDIT!). That is, packages like `r Biocpkg("SummarizedExperiment")` (EDIT!). + +If you are asking yourself the question "Where do I start using Bioconductor?" you might be interested in [this blog post](http://lcolladotor.github.io/2014/10/16/startbioc/#.VkOKbq6rRuU). + +## Asking for help + +As package developers, we try to explain clearly how to use our packages and in which order to use the functions. But `R` and `Bioconductor` have a steep learning curve so it is critical to learn where to ask for help. The blog post quoted above mentions some but we would like to highlight the [Bioconductor support site](https://support.bioconductor.org/) as the main resource for getting help: remember to use the `spatialLIBD` tag and check [the older posts](https://support.bioconductor.org/tag/spatialLIBD/). Other alternatives are available such as creating GitHub issues and tweeting. However, please note that if you want to receive help you should adhere to the [posting guidelines](http://www.bioconductor.org/help/support/posting-guide/). It is particularly critical that you provide a small reproducible example and your session information so package developers can track down the source of the error. + +## Citing `spatialLIBD` + +We hope that `r Biocpkg("spatialLIBD")` will be useful for your research. Please use the following information to cite the package and the overall approach. Thank you! + +```{r "citation"} +## Citation info +citation("spatialLIBD") +``` + +# Quick start to using `spatialLIBD` + +```{r "start", message=FALSE} +library("spatialLIBD") +``` + +Edit this as you see fit =) + +Here is an example of you can cite your package inside the vignette: + +* `r Biocpkg("spatialLIBD")` `r Citep(bib[["spatialLIBD"]])` + + + +# Reproducibility + +The `r Biocpkg("spatialLIBD")` package `r Citep(bib[["spatialLIBD"]])` was made possible thanks to: + +* R `r Citep(bib[["R"]])` +* `r Biocpkg("BiocStyle")` `r Citep(bib[["BiocStyle"]])` +* `r CRANpkg("knitr")` `r Citep(bib[["knitr"]])` +* `r CRANpkg("RefManageR")` `r Citep(bib[["RefManageR"]])` +* `r CRANpkg("rmarkdown")` `r Citep(bib[["rmarkdown"]])` +* `r CRANpkg("sessioninfo")` `r Citep(bib[["sessioninfo"]])` +* `r CRANpkg("testthat")` `r Citep(bib[["testthat"]])` + +This package was developed using `r BiocStyle::Biocpkg("biocthis")`. + + +Code for creating the vignette + +```{r createVignette, eval=FALSE} +## Create the vignette +library("rmarkdown") +system.time(render("guide_to_spatial_registration.Rmd", "BiocStyle::html_document")) + +## Extract the R code +library("knitr") +knit("guide_to_spatial_registration.Rmd", tangle = TRUE) +``` + +Date the vignette was generated. + +```{r reproduce1, echo=FALSE} +## Date the vignette was generated +Sys.time() +``` + +Wallclock time spent generating the vignette. + +```{r reproduce2, echo=FALSE} +## Processing time in seconds +totalTime <- diff(c(startTime, Sys.time())) +round(totalTime, digits = 3) +``` + +`R` session information. + +```{r reproduce3, echo=FALSE} +## Session info +library("sessioninfo") +options(width = 120) +session_info() +``` + + + +# Bibliography + +This vignette was generated using `r Biocpkg("BiocStyle")` `r Citep(bib[["BiocStyle"]])` +with `r CRANpkg("knitr")` `r Citep(bib[["knitr"]])` and `r CRANpkg("rmarkdown")` `r Citep(bib[["rmarkdown"]])` running behind the scenes. + +Citations made with `r CRANpkg("RefManageR")` `r Citep(bib[["RefManageR"]])`. + +```{r vignetteBiblio, results = "asis", echo = FALSE, warning = FALSE, message = FALSE} +## Print bibliography +PrintBibliography(bib, .opts = list(hyperlink = "to.doc", style = "html")) +``` From 7cec80650e41bcadddb68ddeb2109c0a58d92596 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 26 Apr 2023 15:23:21 -0400 Subject: [PATCH 029/259] Start re-working intro section --- vignettes/guide_to_spatial_registration.Rmd | 28 ++++++++------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index 3d7a7dea..6fd7eaee 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -1,10 +1,10 @@ --- title: "Guide to Spatial Registration" author: - - name: Your name + - name: Louise Huuki-Myers affiliation: - - Your institution - email: your.email@somewhere.com + - Lieber Institute for Brain Development + email: lahuuki@gmail.com output: BiocStyle::html_document: self_contained: yes @@ -49,7 +49,10 @@ bib <- c( ) ``` -# Basics + +# What is Spatial Registration? + +# How to run Spatial Registration with `spatialLIBD` tools ## Install `spatialLIBD` @@ -66,17 +69,14 @@ BiocManager::install("spatialLIBD") BiocManager::valid() ``` -## Required knowledge - -`r Biocpkg("spatialLIBD")` is based on many other packages and in particular in those that have implemented the infrastructure needed for dealing with RNA-seq data (EDIT!). That is, packages like `r Biocpkg("SummarizedExperiment")` (EDIT!). +## Important Notes -If you are asking yourself the question "Where do I start using Bioconductor?" you might be interested in [this blog post](http://lcolladotor.github.io/2014/10/16/startbioc/#.VkOKbq6rRuU). +### Required knowledge -## Asking for help +It may be helpful to review _Introduction to spatialLIBD_ vignette available through [GitHub](http://research.libd.org/spatialLIBD/articles/spatialLIBD.html) or [Bioconductor](https://bioconductor.org/packages/spatialLIBD). -As package developers, we try to explain clearly how to use our packages and in which order to use the functions. But `R` and `Bioconductor` have a steep learning curve so it is critical to learn where to ask for help. The blog post quoted above mentions some but we would like to highlight the [Bioconductor support site](https://support.bioconductor.org/) as the main resource for getting help: remember to use the `spatialLIBD` tag and check [the older posts](https://support.bioconductor.org/tag/spatialLIBD/). Other alternatives are available such as creating GitHub issues and tweeting. However, please note that if you want to receive help you should adhere to the [posting guidelines](http://www.bioconductor.org/help/support/posting-guide/). It is particularly critical that you provide a small reproducible example and your session information so package developers can track down the source of the error. -## Citing `spatialLIBD` +### Citing `spatialLIBD` We hope that `r Biocpkg("spatialLIBD")` will be useful for your research. Please use the following information to cite the package and the overall approach. Thank you! @@ -85,17 +85,11 @@ We hope that `r Biocpkg("spatialLIBD")` will be useful for your research. Please citation("spatialLIBD") ``` -# Quick start to using `spatialLIBD` ```{r "start", message=FALSE} library("spatialLIBD") ``` -Edit this as you see fit =) - -Here is an example of you can cite your package inside the vignette: - -* `r Biocpkg("spatialLIBD")` `r Citep(bib[["spatialLIBD"]])` From a62a5bb0d420ccad87b0639e1a4c505316a5e04f Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 27 Apr 2023 12:10:41 -0400 Subject: [PATCH 030/259] Add spatial registration overview figure --- man/figures/spatial_registration.png | Bin 0 -> 1359614 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 man/figures/spatial_registration.png diff --git a/man/figures/spatial_registration.png b/man/figures/spatial_registration.png new file mode 100755 index 0000000000000000000000000000000000000000..4982574e65dd0cf5d2f305105066141e61b086e0 GIT binary patch literal 1359614 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

MN5Un%$Ouk-Ty6Un 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\NQ{5i4hlz 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

(M74|uZjMrgDTApB^7T~6N&tr8s#W;U|b5+ha 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

eC#Y^s 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�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 MVnWr~51>pFiV7m}LTnD@P^ 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

1-F=Y> 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%0Dt)$}wFJP&@cE1;W8etWa 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 literal 0 HcmV?d00001 From 122b6fcd432621bd48ec2079e7ac149ab524fe0c Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Thu, 27 Apr 2023 14:30:17 -0400 Subject: [PATCH 031/259] v1.11.15 -- provide better error messages. Related to a request by @madhavitippani --- DESCRIPTION | 4 ++-- R/read10xVisiumWrapper.R | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3dd5df84..97614c2c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.11.14 -Date: 2023-04-24 +Version: 1.11.15 +Date: 2023-04-27 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 2b9d862e..501a744d 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -62,8 +62,12 @@ read10xVisiumWrapper <- function(samples = "", reference_path <- gsub('.*"', "", regmatches(web, regexpr('\\["Reference Path", *"[/|A-z|0-9|-]+', web))) reference_gtf <- file.path(reference_path, "genes", "genes.gtf") } - stopifnot(length(reference_gtf) == 1) - stopifnot(file.exists(reference_gtf)) + reference_gtf <- reference_gtf[file.exists(reference_gtf)] + if (length(reference_gtf) > 1) { + stop("More than one 'reference_gtf' was provided or detected. Manually specify the path to just one 'reference_gtf'. If different GTF files were used, then different genes will have been quantified and thus cannot be merged naively into a single SpatialExperiment object. If that's the case, we recommend you build separate SPE objects based on the different 'reference_gtf' files used.", call. = FALSE) + } else if (length(reference_gtf) == 0) { + stop("No 'reference_gtf' files were detected. Please check that the files are available.", call. = FALSE) + } if (verbose) message(Sys.time(), " SpatialExperiment::read10xVisium: reading basic data from SpaceRanger") spe <- SpatialExperiment::read10xVisium( From 08c487fb47f743393ff508564851e3caf03531b0 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 27 Apr 2023 18:29:30 -0400 Subject: [PATCH 032/259] Write draft for spatial registration guide --- .Rbuildignore | 2 + .gitignore | 2 + vignettes/guide_to_spatial_registration.Rmd | 241 +++++++++++++++++++- 3 files changed, 233 insertions(+), 12 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 4ee9d1c6..41e4608e 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -15,3 +15,5 @@ $run_dev.* ^codecov\.yml$ ^\.github$ ^spatialLIBD\.Rproj$ +^doc$ +^Meta$ diff --git a/.gitignore b/.gitignore index c70047e0..2064dd51 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ data-raw/spatialLIBD_files docs/ rsconnect *.Rproj +/doc/ +/Meta/ diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index 6fd7eaee..90d2f4da 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -45,35 +45,84 @@ bib <- c( rmarkdown = citation("rmarkdown")[1], sessioninfo = citation("sessioninfo")[1], testthat = citation("testthat")[1], - spatialLIBD = citation("spatialLIBD")[1] + spatialLIBD = citation("spatialLIBD")[1], + spatialLIBDpaper = citation("spatialLIBD")[2], + tran2021 = RefManageR::BibEntry( + bibtype = "Article", + key = "tran2021", + author = "Tran, Matthew N. and Maynard, Kristen R. and Spangler, Abby and Huuki, Louise A. and Montgomery, Kelsey D. and Sadashivaiah, Vijay and Tippani, Madhavi and Barry, Brianna K. and Hancock, Dana B. and Hicks, Stephanie C. and Kleinman, Joel E. and Hyde, Thomas M. and Collado-Torres, Leonardo and Jaffe, Andrew E. and Martinowich, Keri", + title = "Single-nucleus transcriptome analysis reveals cell-type-specific molecular signatures across reward circuitry in the human brain", + year = 2021, doi = "10.1016/j.neuron.2021.09.001", + journal = "Neuron" + ) ) ``` # What is Spatial Registration? +Spatial Registration is an analysis that compares the gene expression of groups +in a query RNA-seq data set (typically spatially resolved RNA-seq or single cell RNA-seq) to +groups in a reference spatially resolved RNA-seq data set (such annotated anatomical features). + +For spatial data, this can be helpful to compare manual annotations, +or annotating clusters. For scRNA-seq data it can check if +a cell type might be more concentrated in one area or anatomical feature of the +tissue. + +The spatial annotation process correlates the t-statistics from the gene enrichment +analysis between spatial features from the reference data set, with the t-statistics +from the gene enrichment of features in the query data set. Pairs with high +positive correlation show where similar patterns of gene expression are occurring +and what anatomical feature the new spatial feature or cell population may map to. + +## Overview of the Spatial Registration method + +1. Perform gene set enrichment analysis between spatial features (ex. anatomical +features, histological layers) on reference spatial data set. Or access existing statistics. + +2. Perform gene set enrichment analysis between features (ex. new +annotations, data-driven clusters) on new query data set. + +3. Correlate the t-statistics between the reference and query features. + +4. Annotate new spatial features with the most strongly associated reference feature. + +5. Plot correlation heat map to observe patterns between the two data sets. + +

+![Spatial Registration Overview](http://research.libd.org/spatialLIBD/reference/figures/spatial_registration.png){width=100%} +

+ + # How to run Spatial Registration with `spatialLIBD` tools -## Install `spatialLIBD` +## Introduction. -`R` is an open-source statistical environment which can be easily modified to enhance its functionality via packages. `r Biocpkg("spatialLIBD")` is a `R` package available via the [Bioconductor](http://bioconductor.org) repository for packages. `R` can be installed on any operating system from [CRAN](https://cran.r-project.org/) after which you can install `r Biocpkg("spatialLIBD")` by using the following commands in your `R` session: +In this example we will utilize the human DLPFC 10x Genomics Visium dataset +from Maynard, Collado-Torres et al. `r Citep(bib[['spatialLIBDpaper']])` as the **reference**. +This data contains manually annotated features: the **six cortical layers + white matter** +present in the DLPFC. We will use the pre-calculated enrichment statistics for the +layers, which are available from `r Biocpkg("spatialLIBD")`. -```{r "install", eval = FALSE} -if (!requireNamespace("BiocManager", quietly = TRUE)) { - install.packages("BiocManager") - } +

+ +![Dotplot of sample from refernce DLPFC data, colored by annotated layers](http://research.libd.org/spatialLIBD/reference/figures/README-access_data-1.png){width=100%} +

+ + +The **querey** dataset will be the DLPFC single nucleus RNA-seq (snRNA-seq) data from `r Citep(bib[['tran2021']])`. + +We will compare the gene expression in the cell type populations of the **querey** +dataset to the annotated **layers** in the **reference**. -BiocManager::install("spatialLIBD") -## Check that you have a valid Bioconductor installation -BiocManager::valid() -``` ## Important Notes ### Required knowledge -It may be helpful to review _Introduction to spatialLIBD_ vignette available through [GitHub](http://research.libd.org/spatialLIBD/articles/spatialLIBD.html) or [Bioconductor](https://bioconductor.org/packages/spatialLIBD). +It may be helpful to review _Introduction to spatialLIBD_ vignette available through [GitHub](http://research.libd.org/spatialLIBD/articles/spatialLIBD.html) or [Bioconductor](https://bioconductor.org/packages/spatialLIBD) for more information about this data set and R package. ### Citing `spatialLIBD` @@ -85,12 +134,180 @@ We hope that `r Biocpkg("spatialLIBD")` will be useful for your research. Please citation("spatialLIBD") ``` +## Setup + +### Install `spatialLIBD` + +```{r "install", eval = FALSE} +if (!requireNamespace("BiocManager", quietly = TRUE)) { + install.packages("BiocManager") + } + +BiocManager::install("spatialLIBD") + +## Check that you have a valid Bioconductor installation +BiocManager::valid() +``` + +### Load required packages ```{r "start", message=FALSE} library("spatialLIBD") +library("SingleCellExperiment") ``` +## Download Data + +### Spatial Reference + +The reference data is easily accessed through `r Biocpkg("spatialLIBD")`. The modeling results +for the annotated layers is already calculated and can be accessed with the `fetch_data()` function. +This data contains the results form three models (anova, enrichment, and pairwise), +we will use the **enrichment** results for spatial registration. The tables contain the +t-statistics, p-values, and gene ensembl ID and symbol. + +```{r "fetch_refrence"} + +## get reference layer enrichment statistics +layer_modeling_results <- fetch_data(type = "modeling_results") + +layer_modeling_results$enrichment[1:5,1:5] + +``` + + +### Querery Data: snRNA-seq + +For the query data set, we will use the public single nucleus RNA-seq (snRNA-seq) +data from `r Citep(bib[['tran2021']])` can be accessed on [github](https://github.com/LieberInstitute/10xPilot_snRNAseq-human#processed-data). + +This data is also from postmortem human brain DLPFC, and contains gene +expression data for 11k nuclei and 19 cell types. + +We will use `BiocFileCache()` to cache this data. It is stored as a `SingleCellExperiment` +object named `sce.dlpfc.tran`, and takes 1.01 GB of RAM memory to load. + +```{r "download_sce_data"} +# Download and save a local cache of the data available at: +# https://github.com/LieberInstitute/10xPilot_snRNAseq-human#processed-data +bfc <- BiocFileCache::BiocFileCache() +url <- paste0( + "https://libd-snrnaseq-pilot.s3.us-east-2.amazonaws.com/", + "SCE_DLPFC-n3_tran-etal.rda" +) +local_data <- BiocFileCache::bfcrpath(url, x = bfc) + +load(local_data, verbose = TRUE) +``` + + +DLPFC tissue consists of many cell types, some are quite rare and will not have enough data to complete the analysis + +```{r "check_cell_types"} +table(sce.dlpfc.tran$cellType) +``` + +The data will be pseudo-bulked over `donor` x `cellType`, it is recommended to drop +groups with < 10 nuclei (this is done automatically in the pseudobulk step). + +```{r "donor_x_cellType"} + +table(sce.dlpfc.tran$donor, sce.dlpfc.tran$cellType) + +``` + + +## Get Enrichment statistics for snRNA-seq data + +`spatialLIBD` contains many functions to compute `modeling_results` for the query sc/snRAN-seq or spatial data. + +**The process includes the following steps** + +1. `registration_pseudobulk()`: Pseudo-bulks data, filter low expressed genes, and normalize counts +2. `registration_mod()`: Defines the statistical model that will be used for computing the block correlation +3. `registration_block_cor()` : Computes the block correlation using the sample ID as the blocking factor, used as correlation in eBayes call +2. `registration_stats_enrichment()` : Computes the gene enrichment t-statistics (one group vs. All other groups) + +The function `registration_wrapper()` makes life easy by wrapping these functions together in to one step! + +```{r "run_registration_wrapper"} + +sce.dlpfc.tran$cellType2 <- as.character(sce.dlpfc.tran$cellType) + +rownames(sce.dlpfc.tran) <- rowData(sce.dlpfc.tran)$gene_id + +## if empty levels after min_ncells +sce_modeling_results <- registration_wrapper(sce = sce.dlpfc.tran, + var_registration = "cellType2", + var_sample_id = "donor", + gene_ensembl = "gene_id", + gene_name = "gene_name" + ) + +``` + +## Extract Enrichment t-statistics +```{r "extract_t_stats"} +## extract t-statics and rename +registration_t_stats <- sce_modeling_results$enrichment[, grep("^t_stat", colnames(sce_modeling_results$enrichment))] +colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) + +## cell types x gene +dim(registration_t_stats) + +## check out table +registration_t_stats[1:5,1:5] +``` + + +## Correlate statsics with Layer Reference +```{r "layer_stat_cor"} + +cor_layer <- layer_stat_cor( + stats = registration_t_stats, + modeling_results = layer_modeling_results, + model_type = "enrichment", + top_n = 100 +) + + +cor_layer +``` + +# Explore Results + +Now we can use these correlation values to learn about the cell types. + +## Create Heatmap of Corelations + +We can see from this heatmap what layers the different cell types are associated with. +* Oligo with WM +* Astro with Layer 1 +* Excitatory neurons to different layers of the cotrex +* Weak associate with Inbihitory Neurons + + +```{r layer_cor_plot} + +layer_stat_cor_plot(cor_layer, max = max(cor_layer)) + +``` + +## Annotate Cell Types by Top Correlation + +We can use `annotate_registered_clusters` to create annotation labels for the +cell types based on the correlation values. + +```{r "annotate"} +anno <- annotate_registered_clusters( + cor_stats_layer = cor_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25 +) + +anno +``` # Reproducibility From 75ae4a2260537897eb0c008cb91699747fb60eef Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 27 Apr 2023 18:37:13 -0400 Subject: [PATCH 033/259] Fix bullet points, add some code comments --- vignettes/guide_to_spatial_registration.Rmd | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index 90d2f4da..0da63cf3 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -232,9 +232,10 @@ table(sce.dlpfc.tran$donor, sce.dlpfc.tran$cellType) The function `registration_wrapper()` makes life easy by wrapping these functions together in to one step! ```{r "run_registration_wrapper"} - +## cellType is a factor - use character vector to avoid empty level bug sce.dlpfc.tran$cellType2 <- as.character(sce.dlpfc.tran$cellType) +## need ensemblID as rownames rownames(sce.dlpfc.tran) <- rowData(sce.dlpfc.tran)$gene_id ## if empty levels after min_ncells @@ -282,9 +283,13 @@ Now we can use these correlation values to learn about the cell types. ## Create Heatmap of Corelations We can see from this heatmap what layers the different cell types are associated with. -* Oligo with WM + +* Oligo with WM + * Astro with Layer 1 + * Excitatory neurons to different layers of the cotrex + * Weak associate with Inbihitory Neurons From 44e3b895800210818baeb7bc201eac8b2f0e2b65 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 09:09:11 -0400 Subject: [PATCH 034/259] v1.13.2 -- bump version after Louise's PR --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8244407d..fa32ae6a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.13.1 -Date: 2023-04-27 +Version: 1.13.2 +Date: 2023-04-28 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From c761bc2f6ea543db7b37c47f50d74ebe1e1e6c4a Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 09:14:51 -0400 Subject: [PATCH 035/259] Auto-style code --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 +-- R/annotate_registered_clusters.R | 16 ++-- R/check_sce.R | 69 +++++++-------- R/check_spe.R | 15 ++-- R/fetch_data.R | 40 +++++---- R/frame_limits.R | 21 ++--- R/gene_set_enrichment.R | 11 +-- R/gene_set_enrichment_plot.R | 23 ++--- R/geom_spatial.R | 17 ++-- R/img_edit.R | 37 ++++---- R/img_update.R | 13 +-- R/img_update_all.R | 11 +-- R/layer_boxplot.R | 27 +++--- R/layer_matrix_plot.R | 27 +++--- R/layer_stat_cor.R | 11 +-- R/layer_stat_cor_plot.R | 11 +-- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 ++--- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 +-- R/registration_stats_anova.R | 17 ++-- R/registration_stats_enrichment.R | 15 ++-- R/registration_stats_pairwise.R | 15 ++-- R/registration_wrapper.R | 19 +++-- R/run_app.R | 95 +++++++++++---------- R/sig_genes_extract.R | 11 ++- R/sig_genes_extract_all.R | 7 +- R/vis_clus.R | 47 +++++----- R/vis_clus_p.R | 23 ++--- R/vis_gene.R | 29 ++++--- R/vis_gene_p.R | 35 ++++---- R/vis_grid_clus.R | 31 +++---- R/vis_grid_gene.R | 37 ++++---- inst/scripts/make-metadata_Visium_SPG_AD.R | 1 - vignettes/guide_to_spatial_registration.Rmd | 39 ++++----- 36 files changed, 424 insertions(+), 410 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index de4f5fee..dbe49f86 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,8 +29,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function(spe, - visium_analysis) { +add10xVisiumAnalysis <- function( + spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index bfdddbe5..e7b09e5c 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,12 +43,13 @@ #' )) #' } add_images <- - function(spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function( + spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index c2a9ec43..13e1d5ab 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,9 +48,10 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function(cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function( + cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -86,10 +87,11 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function(remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function( + remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 0d17423b..1d625342 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,40 +24,41 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function(sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function( + sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index 47de3c0a..d0344daa 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,13 +25,14 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function(spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function( + spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index dead44ec..d64897cd 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,26 +84,25 @@ #' #> 172.28 MB #' } fetch_data <- - function( - type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function(type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL @@ -295,7 +294,6 @@ fetch_data <- } else { file_path } - } diff --git a/R/frame_limits.R b/R/frame_limits.R index b22b5c8a..320cc643 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,16 +37,17 @@ #' } #' frame_limits <- - function(spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function( + spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index 1accea28..e6b6a63d 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,11 +58,12 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function(gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function( + gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index 4ccbfcbc..c155e672 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,17 +84,18 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function(enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function( + enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 64f00cc3..965db758 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,14 +58,15 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function(mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function( + mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index ec6fae90..93aceee3 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,24 +58,25 @@ #' plot(x) #' } img_edit <- - function(spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function( + spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index db6dfcb1..fdfe5b83 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,12 +41,13 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function(spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 31c368c9..314b9b0d 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,11 +22,12 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function(spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 345d5499..6a671a5e 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,19 +114,20 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function(i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function( + i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index f1530fb1..4a44fd18 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,19 +55,20 @@ #' cex = 2 #' ) layer_matrix_plot <- - function(matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function( + matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index 0ccf0bf2..f484c912 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,11 +49,12 @@ #' top_n = 10 #' )) layer_stat_cor <- - function(stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function( + stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index c0f4e924..0d2653b8 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,11 +72,12 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function(cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function( + cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index ef76f1d0..70bc49ac 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,9 +24,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 501a744d..d9f31fc2 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,16 +44,17 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 3f36260c..6921dbb9 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,9 +24,10 @@ #' head(registration_mod) #' registration_model <- - function(sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function( + sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 2e4a0e96..1e115847 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,12 +51,13 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index c899459d..d1d0b135 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,14 +50,15 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index d186547e..cd3ee182 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,14 +34,13 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index afb9771a..09bb3ff9 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,14 +32,13 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function( - sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 5c8cb982..19cc3097 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,15 +50,16 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { sce_pseudo <- registration_pseudobulk(sce, var_registration = var_registration, diff --git a/R/run_app.R b/R/run_app.R index dd6820f3..21fb0ebc 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -182,53 +182,54 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function(spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - ...) { +run_app <- function( + spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index b21902c1..fac5f65b 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,12 +59,11 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index d2c3c01f..0d68b880 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,10 +27,9 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index a4b006c8..58ee8289 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -75,29 +75,30 @@ #' ) #' print(p3) #' } -vis_clus <- function(spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - ...) { +vis_clus <- function( + spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index 34aecaef..cd8b720a 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,17 +42,18 @@ #' rm(spe_sub) #' } vis_clus_p <- - function(spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE) { + function( + spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE) { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 712800de..708e4f53 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -113,20 +113,21 @@ #' print(p5) #' } vis_gene <- - function(spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index e659d477..9bc3dc0a 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,23 +48,24 @@ #' rm(spe_sub) #' } vis_gene_p <- - function(spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function( + spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 6c90221c..40ec7aee 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,21 +47,22 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function(spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - ...) { + function( + spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index e21b5bf1..2504cce5 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,24 +35,25 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function(spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/inst/scripts/make-metadata_Visium_SPG_AD.R b/inst/scripts/make-metadata_Visium_SPG_AD.R index 2c14dc1f..913c0d7c 100644 --- a/inst/scripts/make-metadata_Visium_SPG_AD.R +++ b/inst/scripts/make-metadata_Visium_SPG_AD.R @@ -68,4 +68,3 @@ Sys.time() proc.time() options(width = 120) session_info() - diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index 0da63cf3..d3207c62 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -140,8 +140,8 @@ citation("spatialLIBD") ```{r "install", eval = FALSE} if (!requireNamespace("BiocManager", quietly = TRUE)) { - install.packages("BiocManager") - } + install.packages("BiocManager") +} BiocManager::install("spatialLIBD") @@ -168,12 +168,10 @@ we will use the **enrichment** results for spatial registration. The tables cont t-statistics, p-values, and gene ensembl ID and symbol. ```{r "fetch_refrence"} - -## get reference layer enrichment statistics +## get reference layer enrichment statistics layer_modeling_results <- fetch_data(type = "modeling_results") -layer_modeling_results$enrichment[1:5,1:5] - +layer_modeling_results$enrichment[1:5, 1:5] ``` @@ -212,9 +210,7 @@ The data will be pseudo-bulked over `donor` x `cellType`, it is recommended to d groups with < 10 nuclei (this is done automatically in the pseudobulk step). ```{r "donor_x_cellType"} - table(sce.dlpfc.tran$donor, sce.dlpfc.tran$cellType) - ``` @@ -232,20 +228,20 @@ table(sce.dlpfc.tran$donor, sce.dlpfc.tran$cellType) The function `registration_wrapper()` makes life easy by wrapping these functions together in to one step! ```{r "run_registration_wrapper"} -## cellType is a factor - use character vector to avoid empty level bug +## cellType is a factor - use character vector to avoid empty level bug sce.dlpfc.tran$cellType2 <- as.character(sce.dlpfc.tran$cellType) ## need ensemblID as rownames rownames(sce.dlpfc.tran) <- rowData(sce.dlpfc.tran)$gene_id ## if empty levels after min_ncells -sce_modeling_results <- registration_wrapper(sce = sce.dlpfc.tran, - var_registration = "cellType2", - var_sample_id = "donor", - gene_ensembl = "gene_id", - gene_name = "gene_name" - ) - +sce_modeling_results <- registration_wrapper( + sce = sce.dlpfc.tran, + var_registration = "cellType2", + var_sample_id = "donor", + gene_ensembl = "gene_id", + gene_name = "gene_name" +) ``` ## Extract Enrichment t-statistics @@ -258,13 +254,12 @@ colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_s dim(registration_t_stats) ## check out table -registration_t_stats[1:5,1:5] +registration_t_stats[1:5, 1:5] ``` ## Correlate statsics with Layer Reference ```{r "layer_stat_cor"} - cor_layer <- layer_stat_cor( stats = registration_t_stats, modeling_results = layer_modeling_results, @@ -294,9 +289,7 @@ We can see from this heatmap what layers the different cell types are associated ```{r layer_cor_plot} - layer_stat_cor_plot(cor_layer, max = max(cor_layer)) - ``` ## Annotate Cell Types by Top Correlation @@ -306,9 +299,9 @@ cell types based on the correlation values. ```{r "annotate"} anno <- annotate_registered_clusters( - cor_stats_layer = cor_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25 + cor_stats_layer = cor_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25 ) anno From 69df271a0408edf318588377d3685a4f865b67e0 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 09:16:32 -0400 Subject: [PATCH 036/259] Document on the news https://github.com/LieberInstitute/spatialLIBD/pull/46 by @lahuuki --- NEWS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS.md b/NEWS.md index b8cb77f2..eea71f58 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.13.2 + +NEW FEATURES + +* Louise A. Huuki-Myers @lahuuki added a vignette explaining the spatial +registration process and all related functions. See + for the full pull +request. + # spatialLIBD 1.11.13 SIGNIFICANT USER-VISIBLE CHANGES From 427769f1d5cd4e77e97438ae4efe3ac6b3519579 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 09:22:02 -0400 Subject: [PATCH 037/259] Fix a few typos, use italics for the t in t-statistics --- vignettes/guide_to_spatial_registration.Rmd | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index d3207c62..c5168c81 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -70,8 +70,8 @@ or annotating clusters. For scRNA-seq data it can check if a cell type might be more concentrated in one area or anatomical feature of the tissue. -The spatial annotation process correlates the t-statistics from the gene enrichment -analysis between spatial features from the reference data set, with the t-statistics +The spatial annotation process correlates the $t$-statistics from the gene enrichment +analysis between spatial features from the reference data set, with the $t$-statistics from the gene enrichment of features in the query data set. Pairs with high positive correlation show where similar patterns of gene expression are occurring and what anatomical feature the new spatial feature or cell population may map to. @@ -84,7 +84,7 @@ features, histological layers) on reference spatial data set. Or access existing 2. Perform gene set enrichment analysis between features (ex. new annotations, data-driven clusters) on new query data set. -3. Correlate the t-statistics between the reference and query features. +3. Correlate the $t$-statistics between the reference and query features. 4. Annotate new spatial features with the most strongly associated reference feature. @@ -111,9 +111,9 @@ layers, which are available from `r Biocpkg("spatialLIBD")`.

-The **querey** dataset will be the DLPFC single nucleus RNA-seq (snRNA-seq) data from `r Citep(bib[['tran2021']])`. +The **query** dataset will be the DLPFC single nucleus RNA-seq (snRNA-seq) data from `r Citep(bib[['tran2021']])`. -We will compare the gene expression in the cell type populations of the **querey** +We will compare the gene expression in the cell type populations of the **query** dataset to the annotated **layers** in the **reference**. @@ -165,7 +165,7 @@ for the annotated layers is already calculated and can be accessed with the `fet This data contains the results form three models (anova, enrichment, and pairwise), we will use the **enrichment** results for spatial registration. The tables contain the -t-statistics, p-values, and gene ensembl ID and symbol. +$t$-statistics, p-values, and gene ensembl ID and symbol. ```{r "fetch_refrence"} ## get reference layer enrichment statistics @@ -175,7 +175,7 @@ layer_modeling_results$enrichment[1:5, 1:5] ``` -### Querery Data: snRNA-seq +### Query Data: snRNA-seq For the query data set, we will use the public single nucleus RNA-seq (snRNA-seq) data from `r Citep(bib[['tran2021']])` can be accessed on [github](https://github.com/LieberInstitute/10xPilot_snRNAseq-human#processed-data). @@ -216,19 +216,20 @@ table(sce.dlpfc.tran$donor, sce.dlpfc.tran$cellType) ## Get Enrichment statistics for snRNA-seq data -`spatialLIBD` contains many functions to compute `modeling_results` for the query sc/snRAN-seq or spatial data. +`spatialLIBD` contains many functions to compute `modeling_results` for the query sc/snRNA-seq or spatial data. **The process includes the following steps** 1. `registration_pseudobulk()`: Pseudo-bulks data, filter low expressed genes, and normalize counts 2. `registration_mod()`: Defines the statistical model that will be used for computing the block correlation 3. `registration_block_cor()` : Computes the block correlation using the sample ID as the blocking factor, used as correlation in eBayes call -2. `registration_stats_enrichment()` : Computes the gene enrichment t-statistics (one group vs. All other groups) +2. `registration_stats_enrichment()` : Computes the gene enrichment $t$-statistics (one group vs. All other groups) The function `registration_wrapper()` makes life easy by wrapping these functions together in to one step! ```{r "run_registration_wrapper"} ## cellType is a factor - use character vector to avoid empty level bug +## or use droplevels() sce.dlpfc.tran$cellType2 <- as.character(sce.dlpfc.tran$cellType) ## need ensemblID as rownames @@ -259,6 +260,7 @@ registration_t_stats[1:5, 1:5] ## Correlate statsics with Layer Reference + ```{r "layer_stat_cor"} cor_layer <- layer_stat_cor( stats = registration_t_stats, @@ -267,7 +269,6 @@ cor_layer <- layer_stat_cor( top_n = 100 ) - cor_layer ``` From d013d96db2c147a9bd0cbfc7824085e9a29a6dbf Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 09:54:20 -0400 Subject: [PATCH 038/259] Fix some bugs noted by Louise @lahuuki Co-authored-by: Louise Huuki --- R/registration_pseudobulk.R | 19 ++++++++++------- R/registration_wrapper.R | 23 ++++++++++++--------- vignettes/guide_to_spatial_registration.Rmd | 11 ++-------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 1e115847..2d859e4e 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,13 +51,12 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) @@ -126,6 +125,12 @@ registration_pseudobulk <- sce_pseudo <- sce_pseudo[, sce_pseudo$ncells >= min_ncells] } + if (is.factor(sce_pseudo$registration_variable)) { + ## Drop unused var_registration levels if we had to drop some due + ## to min_ncells + sce_pseudo$registration_variable <- droplevels(sce_pseudo$registration_variable) + } + ## Drop lowly-expressed genes message(Sys.time(), " drop lowly expressed genes") keep_expr <- diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 19cc3097..38a1c297 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,16 +50,19 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { + ## Change the rownames to ENSEMBL IDs + rownames(sce) <- rowData(sce)[, gene_ensembl] + + ## Pseudobulk sce_pseudo <- registration_pseudobulk(sce, var_registration = var_registration, diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index c5168c81..fe769504 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -228,17 +228,10 @@ table(sce.dlpfc.tran$donor, sce.dlpfc.tran$cellType) The function `registration_wrapper()` makes life easy by wrapping these functions together in to one step! ```{r "run_registration_wrapper"} -## cellType is a factor - use character vector to avoid empty level bug -## or use droplevels() -sce.dlpfc.tran$cellType2 <- as.character(sce.dlpfc.tran$cellType) - -## need ensemblID as rownames -rownames(sce.dlpfc.tran) <- rowData(sce.dlpfc.tran)$gene_id - -## if empty levels after min_ncells +## Perform the spatial registration sce_modeling_results <- registration_wrapper( sce = sce.dlpfc.tran, - var_registration = "cellType2", + var_registration = "cellType", var_sample_id = "donor", gene_ensembl = "gene_id", gene_name = "gene_name" From 132817a303f0375ae3e782aa8120a3878c400f90 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 09:54:37 -0400 Subject: [PATCH 039/259] v1.13.3 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index fa32ae6a..d78b5814 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.13.2 +Version: 1.13.3 Date: 2023-04-28 Authors@R: c( From ecf0fbbe78656c0915b6c63bb257e300f5b7007e Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 10:01:45 -0400 Subject: [PATCH 040/259] Fix a typo --- vignettes/guide_to_spatial_registration.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index fe769504..19208bef 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -269,7 +269,7 @@ cor_layer Now we can use these correlation values to learn about the cell types. -## Create Heatmap of Corelations +## Create Heatmap of Correlations We can see from this heatmap what layers the different cell types are associated with. From 9f1edd219dfb3e7540235e5f47fd13f2671544e7 Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 10:05:18 -0400 Subject: [PATCH 041/259] Fix another one --- vignettes/guide_to_spatial_registration.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index 19208bef..c3732c6f 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -279,7 +279,7 @@ We can see from this heatmap what layers the different cell types are associated * Excitatory neurons to different layers of the cotrex -* Weak associate with Inbihitory Neurons +* Weak associate with Inhibitory Neurons ```{r layer_cor_plot} From c02cd5684ba4f3d2195bb918b1f3cda45f7f2b3e Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Fri, 28 Apr 2023 10:05:42 -0400 Subject: [PATCH 042/259] Missed another one --- vignettes/guide_to_spatial_registration.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index c3732c6f..cefdf0fa 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -277,7 +277,7 @@ We can see from this heatmap what layers the different cell types are associated * Astro with Layer 1 -* Excitatory neurons to different layers of the cotrex +* Excitatory neurons to different layers of the cortex * Weak associate with Inhibitory Neurons From 5d4ebb62df7adafc71734ef6b67cd5d063dc6f4d Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sat, 6 May 2023 20:57:44 -0400 Subject: [PATCH 043/259] Update GHA to bioc 3.17 --- .github/workflows/check-bioc.yml | 36 +++++++++----------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index c0f04dd5..82b58998 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -52,9 +52,9 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-latest, r: '4.2', bioc: '3.16', cont: "bioconductor/bioconductor_docker:RELEASE_3_16", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } - # - { os: macOS-latest, r: '4.2', bioc: '3.16'} - - { os: windows-latest, r: '4.2', bioc: '3.16'} + - { os: ubuntu-latest, r: '4.3', bioc: '3.17', cont: "bioconductor/bioconductor_docker:RELEASE_3_17", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } + - { os: macOS-latest, r: '4.3', bioc: '3.17'} + - { os: windows-latest, r: '4.3', bioc: '3.17'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent env: @@ -105,16 +105,16 @@ jobs: uses: actions/cache@v3 with: path: ${{ env.R_LIBS_USER }} - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_16-r-4.2-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_16-r-4.2- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3- - name: Cache R packages on Linux if: "!contains(github.event.head_commit.message, '/nocache') && runner.os == 'Linux' " uses: actions/cache@v3 with: path: /home/runner/work/_temp/Library - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_16-r-4.2-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_16-r-4.2- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3- - name: Install Linux system dependencies if: runner.os == 'Linux' @@ -169,35 +169,19 @@ jobs: ## https://github.com/r-lib/remotes/issues/296 ## Ideally, all dependencies should get installed in the first pass. - ## Set the repos source depending on the OS - ## Alternatively use https://storage.googleapis.com/bioconductor_docker/packages/ - ## though based on https://bit.ly/bioc2021-package-binaries - ## the Azure link will be the main one going forward. - gha_repos <- if( - .Platform$OS.type == "unix" && Sys.info()["sysname"] != "Darwin" - ) c( - "AnVIL" = "https://bioconductordocker.blob.core.windows.net/packages/3.16/bioc", - BiocManager::repositories() - ) else BiocManager::repositories() - ## For running the checks message(paste('****', Sys.time(), 'installing rcmdcheck and BiocCheck ****')) - install.packages(c("rcmdcheck", "BiocCheck"), repos = gha_repos) + install.packages(c("rcmdcheck", "BiocCheck"), repos = BiocManager::repositories()) ## Pass #1 at installing dependencies - ## This pass uses AnVIL-powered fast binaries - ## details at https://github.com/nturaga/bioc2021-bioconductor-binaries - ## The speed gains only apply to the docker builds. message(paste('****', Sys.time(), 'pass number 1 at installing dependencies: local dependencies ****')) - remotes::install_local(dependencies = TRUE, repos = gha_repos, build_vignettes = FALSE, upgrade = TRUE) + remotes::install_local(dependencies = TRUE, repos = BiocManager::repositories(), build_vignettes = FALSE, upgrade = TRUE) continue-on-error: true shell: Rscript {0} - name: Install dependencies pass 2 run: | ## Pass #2 at installing dependencies - ## This pass does not use AnVIL and will thus update any packages - ## that have seen been updated in Bioconductor message(paste('****', Sys.time(), 'pass number 2 at installing dependencies: any remaining dependencies ****')) remotes::install_local(dependencies = TRUE, repos = BiocManager::repositories(), build_vignettes = TRUE, upgrade = TRUE, force = TRUE) shell: Rscript {0} @@ -302,7 +286,7 @@ jobs: if: failure() uses: actions/upload-artifact@master with: - name: ${{ runner.os }}-biocversion-RELEASE_3_16-r-4.2-results + name: ${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3-results path: check From 7a3d71d2182d78a1f67e710614d2ad581d90d83e Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Sun, 7 May 2023 02:07:29 -0400 Subject: [PATCH 044/259] master --> devel, added the PR badge, ran dev/04_update.R --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 ++-- R/annotate_registered_clusters.R | 16 ++--- R/check_sce.R | 69 +++++++++--------- R/check_spe.R | 15 ++-- R/fetch_data.R | 39 +++++----- R/frame_limits.R | 21 +++--- R/gene_set_enrichment.R | 11 ++- R/gene_set_enrichment_plot.R | 23 +++--- R/geom_spatial.R | 17 +++-- R/img_edit.R | 37 +++++----- R/img_update.R | 13 ++-- R/img_update_all.R | 11 ++- R/layer_boxplot.R | 27 ++++--- R/layer_matrix_plot.R | 27 ++++--- R/layer_stat_cor.R | 11 ++- R/layer_stat_cor_plot.R | 11 ++- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 +++--- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 ++-- R/registration_stats_anova.R | 17 +++-- R/registration_stats_enrichment.R | 15 ++-- R/registration_stats_pairwise.R | 15 ++-- R/registration_wrapper.R | 19 ++--- R/run_app.R | 95 ++++++++++++------------- R/sig_genes_extract.R | 11 +-- R/sig_genes_extract_all.R | 7 +- R/vis_clus.R | 47 ++++++------ R/vis_clus_p.R | 23 +++--- R/vis_gene.R | 29 ++++---- R/vis_gene_p.R | 35 +++++---- R/vis_grid_clus.R | 31 ++++---- R/vis_grid_gene.R | 37 +++++----- README.Rmd | 3 +- README.md | 51 +++++++++++-- inst/app/www/README.md | 2 +- inst/app/www/documentation_sce_layer.md | 4 +- vignettes/spatialLIBD.Rmd | 8 +-- 39 files changed, 443 insertions(+), 418 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index dbe49f86..de4f5fee 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,9 +29,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function( - spe, - visium_analysis) { +add10xVisiumAnalysis <- function(spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index e7b09e5c..bfdddbe5 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,13 +43,12 @@ #' )) #' } add_images <- - function( - spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function(spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index 13e1d5ab..c2a9ec43 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,10 +48,9 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function( - cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function(cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -87,11 +86,10 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function( - remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function(remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 1d625342..0d17423b 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,41 +24,40 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function( - sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function(sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index d0344daa..47de3c0a 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,14 +25,13 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function( - spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function(spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index d64897cd..33954baf 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,25 +84,26 @@ #' #> 172.28 MB #' } fetch_data <- - function(type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function( + type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index 320cc643..b22b5c8a 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,17 +37,16 @@ #' } #' frame_limits <- - function( - spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function(spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index e6b6a63d..1accea28 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,12 +58,11 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function( - gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function(gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index c155e672..4ccbfcbc 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,18 +84,17 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function( - enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function(enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 965db758..64f00cc3 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,15 +58,14 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function( - mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function(mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index 93aceee3..ec6fae90 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,25 +58,24 @@ #' plot(x) #' } img_edit <- - function( - spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function(spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index fdfe5b83..db6dfcb1 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,13 +41,12 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function( - spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 314b9b0d..31c368c9 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,12 +22,11 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function( - spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 6a671a5e..345d5499 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,20 +114,19 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function( - i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function(i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index 4a44fd18..f1530fb1 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,20 +55,19 @@ #' cex = 2 #' ) layer_matrix_plot <- - function( - matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function(matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index f484c912..0ccf0bf2 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,12 +49,11 @@ #' top_n = 10 #' )) layer_stat_cor <- - function( - stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function(stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 0d2653b8..c0f4e924 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,12 +72,11 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function( - cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function(cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 70bc49ac..ef76f1d0 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,8 +24,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index d9f31fc2..501a744d 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,17 +44,16 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 6921dbb9..3f36260c 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,10 +24,9 @@ #' head(registration_mod) #' registration_model <- - function( - sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function(sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 2d859e4e..5f3c5dd2 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,12 +51,13 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index d1d0b135..c899459d 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,15 +50,14 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index cd3ee182..d186547e 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,13 +34,14 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index 09bb3ff9..afb9771a 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,13 +32,14 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function(sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 38a1c297..49896d78 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,15 +50,16 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index 21fb0ebc..dd6820f3 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -182,54 +182,53 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function( - spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - ...) { +run_app <- function(spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index fac5f65b..b21902c1 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,11 +59,12 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index 0d68b880..d2c3c01f 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,9 +27,10 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index 58ee8289..a4b006c8 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -75,30 +75,29 @@ #' ) #' print(p3) #' } -vis_clus <- function( - spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - ...) { +vis_clus <- function(spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index cd8b720a..34aecaef 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,18 +42,17 @@ #' rm(spe_sub) #' } vis_clus_p <- - function( - spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE) { + function(spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE) { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 708e4f53..712800de 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -113,21 +113,20 @@ #' print(p5) #' } vis_gene <- - function( - spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 9bc3dc0a..e659d477 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,24 +48,23 @@ #' rm(spe_sub) #' } vis_gene_p <- - function( - spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function(spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 40ec7aee..6c90221c 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,22 +47,21 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function( - spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - ...) { + function(spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index 2504cce5..e21b5bf1 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,25 +35,24 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function( - spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/README.Rmd b/README.Rmd index ef568571..27248ae7 100644 --- a/README.Rmd +++ b/README.Rmd @@ -23,9 +23,10 @@ knitr::opts_chunk$set( [![Bioc support](https://bioconductor.org/shields/posts/spatialLIBD.svg)](https://support.bioconductor.org/tag/spatialLIBD) [![Bioc last commit](https://bioconductor.org/shields/lastcommit/devel/data-experiment/spatialLIBD.svg)](http://bioconductor.org/checkResults/devel/data-experiment-LATEST/spatialLIBD/) [![Bioc dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD.svg)](https://bioconductor.org/packages/release/data-experiment/html/spatialLIBD.html#since) -[![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/master/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=master) +[![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) [![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) +[![GitHub pulls](https://img.shields.io/github/issues-pr/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/pulls) [![DOI](https://zenodo.org/badge/225913568.svg)](https://zenodo.org/badge/latestdoi/225913568) diff --git a/README.md b/README.md index 97d15e8b..b15cfbdc 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,13 @@ commit](https://bioconductor.org/shields/lastcommit/devel/data-experiment/spatia [![Bioc dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD.svg)](https://bioconductor.org/packages/release/data-experiment/html/spatialLIBD.html#since) [![Codecov test -coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/master/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=master) +coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) [![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) +[![GitHub +pulls](https://img.shields.io/github/issues-pr/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/pulls) [![DOI](https://zenodo.org/badge/225913568.svg)](https://zenodo.org/badge/latestdoi/225913568) @@ -243,7 +245,6 @@ Please run this yourself to check for any updates on how to cite ``` r print(citation("spatialLIBD"), bibtex = TRUE) -#> #> To cite package 'spatialLIBD' in publications use: #> #> Pardo B, Spangler A, Weber LM, Hicks SC, Jaffe AE, Martinowich K, @@ -283,6 +284,48 @@ print(citation("spatialLIBD"), bibtex = TRUE) #> doi = {10.1038/s41593-020-00787-0}, #> url = {https://www.nature.com/articles/s41593-020-00787-0}, #> } +#> +#> Huuki-Myers LA, Spangler A, Eagles NJ, Montgomergy KD, Kwon SH, Guo +#> B, Grant-Peters M, Divecha HR, Tippani M, Sriworarat C, Nguyen AB, +#> Ravichandran P, Tran MN, Seyedian A, Consortium P, Hyde TM, Kleinman +#> JE, Battle A, Page SC, Ryten M, Hicks SC, Martinowich K, +#> Collado-Torres L, Maynard KR (2023). "Integrated single cell and +#> unsupervised spatial transcriptomic analysis defines molecular +#> anatomy of the human dorsolateral prefrontal cortex." _bioRxiv_. +#> doi:10.1101/2023.02.15.528722 +#> , +#> . +#> +#> A BibTeX entry for LaTeX users is +#> +#> @Article{, +#> title = {Integrated single cell and unsupervised spatial transcriptomic analysis defines molecular anatomy of the human dorsolateral prefrontal cortex}, +#> author = {Louise A. Huuki-Myers and Abby Spangler and Nicholas J. Eagles and Kelsey D. Montgomergy and Sang Ho Kwon and Boyi Guo and Melissa Grant-Peters and Heena R. Divecha and Madhavi Tippani and Chaichontat Sriworarat and Annie B. Nguyen and Prashanthi Ravichandran and Matthew N. Tran and Arta Seyedian and PsychENCODE Consortium and Thomas M. Hyde and Joel E. Kleinman and Alexis Battle and Stephanie C. Page and Mina Ryten and Stephanie C. Hicks and Keri Martinowich and Leonardo Collado-Torres and Kristen R. Maynard}, +#> year = {2023}, +#> journal = {bioRxiv}, +#> doi = {10.1101/2023.02.15.528722}, +#> url = {https://www.biorxiv.org/content/10.1101/2023.02.15.528722v1}, +#> } +#> +#> Kwon SH, Parthiban S, Tippani M, Divecha HR, Eagles NJ, Lobana JS, +#> Williams SR, Mark M, Bharadwaj RA, Kleinman JE, Hyde TM, Page SC, +#> Hicks SC, Martinowich K, Maynard KR, Collado-Torres L (2023). +#> "Influence of Alzheimer’s disease related neuropathology on local +#> microenvironment gene expression in the human inferior temporal +#> cortex." _bioRxiv_. doi:10.1101/2023.04.20.537710 +#> , +#> . +#> +#> A BibTeX entry for LaTeX users is +#> +#> @Article{, +#> title = {Influence of Alzheimer’s disease related neuropathology on local microenvironment gene expression in the human inferior temporal cortex}, +#> author = {Sang Ho Kwon and Sowmya Parthiban and Madhavi Tippani and Heena R. Divecha and Nicholas J. Eagles and Jashandeep S. Lobana and Stephen R. Williams and Michelle Mark and Rahul A. Bharadwaj and Joel E. Kleinman and Thomas M. Hyde and Stephanie C. Page and Stephanie C. Hicks and Keri Martinowich and Kristen R. Maynard and Leonardo Collado-Torres}, +#> year = {2023}, +#> journal = {bioRxiv}, +#> doi = {10.1101/2023.04.20.537710}, +#> url = {https://www.biorxiv.org/content/10.1101/2023.04.20.537710v1}, +#> } ``` Please note that the `spatialLIBD` was only made possible thanks to many @@ -306,7 +349,7 @@ By contributing to this project, you agree to abide by its terms. *[rcmdcheck](https://CRAN.R-project.org/package=rcmdcheck)* customized to use [Bioconductor’s docker containers](https://www.bioconductor.org/help/docker/) and - *[BiocCheck](https://bioconductor.org/packages/3.16/BiocCheck)*. + *[BiocCheck](https://bioconductor.org/packages/3.17/BiocCheck)*. - Code coverage assessment is possible thanks to [codecov](https://codecov.io/gh) and *[covr](https://CRAN.R-project.org/package=covr)*. @@ -323,7 +366,7 @@ By contributing to this project, you agree to abide by its terms. For more details, check the `dev` directory. This package was developed using -*[biocthis](https://bioconductor.org/packages/3.16/biocthis)*. +*[biocthis](https://bioconductor.org/packages/3.17/biocthis)*.
diff --git a/inst/app/www/README.md b/inst/app/www/README.md index 71853ef8..5a4d943a 100644 --- a/inst/app/www/README.md +++ b/inst/app/www/README.md @@ -20,7 +20,7 @@ commit](https://bioconductor.org/shields/lastcommit/devel/data-experiment/spatia [![Bioc dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD.svg)](https://bioconductor.org/packages/release/data-experiment/html/spatialLIBD.html#since) [![Codecov test -coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/master/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=master) +coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) [![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub diff --git a/inst/app/www/documentation_sce_layer.md b/inst/app/www/documentation_sce_layer.md index 12105287..5b6660c7 100644 --- a/inst/app/www/documentation_sce_layer.md +++ b/inst/app/www/documentation_sce_layer.md @@ -79,7 +79,7 @@ spatialLIBD::layer_boxplot() ## Gene Set Enrichment -This tab allows you to upload a CSV file that has a particular format as illustrated [in this example file](https://github.com/LieberInstitute/spatialLIBD/blob/master/data-raw/asd_sfari_geneList.csv). This CSV file should contain: +This tab allows you to upload a CSV file that has a particular format as illustrated [in this example file](https://github.com/LieberInstitute/spatialLIBD/blob/devel/data-raw/asd_sfari_geneList.csv). This CSV file should contain: * one column per gene set of interest labeled as column names on the first row, * no row names, @@ -97,7 +97,7 @@ spatialLIBD::gene_set_enrichment_plot() ## Spatial registration -If you have a single nucleus or single cell RNA-sequencing (snRNA-seq) (scRNA-seq) dataset, you might group your cells into clusters. Once you do, you could compress the data by pseudo-bulking (like we did to go from `spe` to `sce_layer`). You could then compute `enrichment` (`pairwise`, `anova`) statistics for your cell clusters. If you do so, you can then upload a specially formatted CSV file just like the one in [this example file](https://github.com/LieberInstitute/spatialLIBD/blob/master/data-raw/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.csv). This file has: +If you have a single nucleus or single cell RNA-sequencing (snRNA-seq) (scRNA-seq) dataset, you might group your cells into clusters. Once you do, you could compress the data by pseudo-bulking (like we did to go from `spe` to `sce_layer`). You could then compute `enrichment` (`pairwise`, `anova`) statistics for your cell clusters. If you do so, you can then upload a specially formatted CSV file just like the one in [this example file](https://github.com/LieberInstitute/spatialLIBD/blob/devel/data-raw/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.csv). This file has: * column names, * human Ensembl gene IDs as the row names (first column, no name for the column), diff --git a/vignettes/spatialLIBD.Rmd b/vignettes/spatialLIBD.Rmd index fa258567..00189010 100644 --- a/vignettes/spatialLIBD.Rmd +++ b/vignettes/spatialLIBD.Rmd @@ -480,7 +480,7 @@ In order to fully interpret the resulting heatmap you need to know what each of You can find the version with the full names [here](https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/pdf/snRNAseq_overlap_heatmap.pdf) if you are interested in it. -The `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')` `r Citep(bib[['spatialLIBD']])` allows users to upload CSV file with these t-statistics, view the correlation heatmaps, download them, and download the correlation matrix. An example CSV file is provided [here](https://github.com/LieberInstitute/spatialLIBD/blob/master/data-raw/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.csv). +The `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')` `r Citep(bib[['spatialLIBD']])` allows users to upload CSV file with these t-statistics, view the correlation heatmaps, download them, and download the correlation matrix. An example CSV file is provided [here](https://github.com/LieberInstitute/spatialLIBD/blob/devel/data-raw/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.csv). ## Gene set enrichment @@ -531,7 +531,7 @@ gene_set_enrichment_plot( ) ``` -The `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')` `r Citep(bib[['spatialLIBD']])` allows users to upload CSV file their gene lists, compute the enrichment statistics, visualize them, download the PDF, and download the enrichment table. An example CSV file is provided [here](https://github.com/LieberInstitute/spatialLIBD/blob/master/data-raw/asd_sfari_geneList.csv). +The `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')` `r Citep(bib[['spatialLIBD']])` allows users to upload CSV file their gene lists, compute the enrichment statistics, visualize them, download the PDF, and download the enrichment table. An example CSV file is provided [here](https://github.com/LieberInstitute/spatialLIBD/blob/devel/data-raw/asd_sfari_geneList.csv). # Re-shaping your data to our structure @@ -569,9 +569,9 @@ If you are interested in reshaping your data to fit our structure, we do not pro * `Layer_Notebook.R` available [here](https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Notebook.R) reads in the Visium data and builds a list of `RangeSummarizedExperiment()` objects from `r Biocpkg('SummarizedExperiment')`, one per sample (image) that is eventually saved as `Human_DLPFC_Visium_processedData_rseList.rda`. * `convert_sce.R` available [here](https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/convert_sce.R) reads in `Human_DLPFC_Visium_processedData_rseList.rda` and builds an initial `sce` object with image data under `metadata(sce)$image` which is a single data.frame. Subsetting doesn't automatically subset the image, so you have to do it yourself when plotting as is done by `vis_clus_p()` and `vis_gene_p()`. Having the data from all images in a single object allows you to use the spot-level data from all images to compute clusters and do other similar analyses to the ones you would do with sc/snRNA-seq data. The script creates the `Human_DLPFC_Visium_processedData_sce.Rdata` file. * `sce_scran.R` available [here](https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/sce_scran.R) then uses `r Biocpkg('scran')` to read in `Human_DLPFC_Visium_processedData_sce.Rdata`, compute the highly variable genes (stored in our final `sce` object at `rowData(sce)$is_top_hvg`), perform dimensionality reduction (PCA, TSNE, UMAP) and identify clusters using the data from all images. The resulting data is then stored as `Human_DLPFC_Visium_processedData_sce_scran.Rdata` and is the main object used throughout our analysis code `r Citep(bib[['spatialLIBDpaper']])`. -* `make-data_spatialLIBD.R` available in the source version of `spatialLIBD` and [online here](https://github.com/LieberInstitute/spatialLIBD/blob/master/inst/scripts/make-data_spatialLIBD.R) is the script that reads in `Human_DLPFC_Visium_processedData_sce_scran.Rdata` as well as some other outputs from our analysis and combines them into the final `sce` and `sce_layer` objects provided by `r Biocpkg('spatialLIBD')` `r Citep(bib[['spatialLIBD']])`. This script simplifies some operations in order to simplify the code behind the `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')`. +* `make-data_spatialLIBD.R` available in the source version of `spatialLIBD` and [online here](https://github.com/LieberInstitute/spatialLIBD/blob/devel/inst/scripts/make-data_spatialLIBD.R) is the script that reads in `Human_DLPFC_Visium_processedData_sce_scran.Rdata` as well as some other outputs from our analysis and combines them into the final `sce` and `sce_layer` objects provided by `r Biocpkg('spatialLIBD')` `r Citep(bib[['spatialLIBD']])`. This script simplifies some operations in order to simplify the code behind the `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')`. -You don't necessarily need to do all of this to use the functions provided by `r Biocpkg('spatialLIBD')`. Note that external to the R objects, for the `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')` you will need to have the `tissue_lowres_image.png` image files in a directory structure by sample as shown [here](https://github.com/LieberInstitute/spatialLIBD/tree/master/inst/app/www/data) in order for the interactive visualizations made with `r CRANpkg('plotly')` to work. +You don't necessarily need to do all of this to use the functions provided by `r Biocpkg('spatialLIBD')`. Note that external to the R objects, for the `r CRANpkg('shiny')` application provided by `r Biocpkg('spatialLIBD')` you will need to have the `tissue_lowres_image.png` image files in a directory structure by sample as shown [here](https://github.com/LieberInstitute/spatialLIBD/tree/devel/inst/app/www/data) in order for the interactive visualizations made with `r CRANpkg('plotly')` to work. # More spatially-resolved LIBD datasets From 2f0c30b4de25b1096a6e9d57c31fd626a7bde5aa Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Tue, 23 May 2023 23:52:11 +0100 Subject: [PATCH 045/259] v1.13.4 -- add fetch_data("spatialDLPFC_Visium_example_subset") for example / tutorial purposes ```R > hola <- fetch_data("spatialDLPFC_Visium_example_subset") snapshotDate(): 2023-04-24 adding rname 'https://www.dropbox.com/s/3jm3kjab9lzaemo/spatialDLPFC_spe_subset_example.rds?dl=1' |=====================================================| 100% 2023-05-23 23:50:07.779924 loading file /Users/leocollado/Library/Caches/org.R-project.R/R/BiocFileCache/b40a58edd49c_spatialDLPFC_spe_subset_example.rds%3Fdl%3D1 devel* > hola class: SpatialExperiment dim: 28916 12107 metadata(1): BayesSpace.data assays(2): counts logcounts rownames(28916): ENSG00000243485 ENSG00000238009 ... ENSG00000278817 ENSG00000277196 rowData names(7): source type ... gene_type gene_search colnames(12107): AAACAAGTATCTCCCA-1 AAACACCAATAACTGC-1 ... TTGTTTGTATTACACG-1 TTGTTTGTGTAAATTC-1 colData names(155): age array_col ... VistoSeg_proportion wrinkle_type reducedDimNames(8): 10x_pca 10x_tsne ... HARMONY UMAP.HARMONY mainExpName: NULL altExpNames(0): spatialCoords names(2) : pxl_col_in_fullres pxl_row_in_fullres imgData names(4): sample_id image_id data scaleFactor devel* > table(hola$sample_id) Br6432_ant Br6522_ant Br8667_mid 3905 4263 3939 ``` --- DESCRIPTION | 4 +- NEWS.md | 8 + R/fetch_data.R | 9 + data-raw/.gitignore | 1 + data-raw/create_spatialDLPFC_spe_subset.R | 244 ++++++++++++++++++++++ inst/extdata/metadata_spatialDLPFC.csv | 1 + inst/scripts/make-metadata_spatialDLPFC.R | 6 +- man/fetch_data.Rd | 8 +- 8 files changed, 274 insertions(+), 7 deletions(-) create mode 100644 data-raw/create_spatialDLPFC_spe_subset.R diff --git a/DESCRIPTION b/DESCRIPTION index d78b5814..c8ae742f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.13.3 -Date: 2023-04-28 +Version: 1.13.4 +Date: 2023-05-23 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index eea71f58..2b945752 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# spatialLIBD 1.13.4 + +NEW FEATURES + +* Added `fetch_data("spatialDLPFC_Visium_example_subset")` which is a subset +of 3 samples with only the `lowres` images that can be used for example / +tutorial purposes. + # spatialLIBD 1.13.2 NEW FEATURES diff --git a/R/fetch_data.R b/R/fetch_data.R index 33954baf..cc715e4a 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -92,6 +92,7 @@ fetch_data <- "sce_example", "spe", "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", "spatialDLPFC_Visium_pseudobulk", "spatialDLPFC_Visium_modeling_results", "spatialDLPFC_Visium_SPG", @@ -182,6 +183,14 @@ fetch_data <- "spe_filtered_final_with_clusters_and_deconvolution_results.rds" url <- "https://www.dropbox.com/s/y2ifv5v8g68papf/spe_filtered_final_with_clusters_and_deconvolution_results.rds?dl=1" + } else if (type == "spatialDLPFC_Visium_example_subset") { + tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD_example_subset" + hub_title <- "spatialDLPFC_Visium_spe_example_subset" + + ## While EH is not set-up + file_name <- "spatialDLPFC_spe_subset_example.rds" + url <- + "https://www.dropbox.com/s/3jm3kjab9lzaemo/spatialDLPFC_spe_subset_example.rds?dl=1" } else if (type == "spatialDLPFC_Visium_pseudobulk") { tag <- "spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" hub_title <- "spatialDLPFC_Visium_pseudobulk_spe" diff --git a/data-raw/.gitignore b/data-raw/.gitignore index d839103c..32d882b2 100644 --- a/data-raw/.gitignore +++ b/data-raw/.gitignore @@ -1,3 +1,4 @@ *.Rdata logo.ai logo.pdf +spatialDLPFC_spe_subset_example.rds diff --git a/data-raw/create_spatialDLPFC_spe_subset.R b/data-raw/create_spatialDLPFC_spe_subset.R new file mode 100644 index 00000000..ca5e83ab --- /dev/null +++ b/data-raw/create_spatialDLPFC_spe_subset.R @@ -0,0 +1,244 @@ +library("spatialLIBD") +library("sessioninfo") + +spe <- fetch_data("spatialDLPFC_Visium") + +lobstr::obj_size(spe) +# 6.97 GB + +## Subset to just 3 samples used in Figure 2A +spe <- spe[, spe$sample_id %in% c("Br8667_mid", "Br6522_ant", "Br6432_ant")] + +lobstr::obj_size(spe) +# 777.93 MB + +imgData(spe) +# DataFrame with 12 rows and 4 columns +# sample_id image_id data scaleFactor +# +# 1 Br6432_ant lowres #### 0.0148894 +# 2 Br6432_ant hires #### 0.0496315 +# 3 Br6432_ant detected #### 0.0496315 +# 4 Br6432_ant aligned #### 0.0496315 +# 5 Br6522_ant lowres #### 0.0192517 +# ... ... ... ... ... +# 8 Br6522_ant aligned #### 0.0641725 +# 9 Br8667_mid lowres #### 0.0169181 +# 10 Br8667_mid hires #### 0.0563936 +# 11 Br8667_mid detected #### 0.0563936 +# 12 Br8667_mid aligned #### 0.0563936 + +## Subset to just the lowres images +imgData(spe) <- imgData(spe)[imgData(spe)$image_id == "lowres", ] + +lobstr::obj_size(spe) +# 540.88 MB + +saveRDS(spe, file = here::here("data-raw", "spatialDLPFC_spe_subset_example.rds")) +system2("ls", paste("-lh", here::here("data-raw", "spatialDLPFC_spe_subset_example.rds"))) +# -rw-r--r--@ 1 leocollado staff 107M May 23 23:42 /Users/leocollado/Dropbox/Code/spatialLIBD/data-raw/spatialDLPFC_spe_subset_example.rds + +## Reproducibility information +print("Reproducibility information:") +Sys.time() +proc.time() +options(width = 120) +session_info() +# ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── +# setting value +# version R version 4.3.0 (2023-04-21) +# os macOS Ventura 13.3.1 +# system aarch64, darwin20 +# ui RStudio +# language (EN) +# collate en_US.UTF-8 +# ctype en_US.UTF-8 +# tz Europe/London +# date 2023-05-23 +# rstudio 2023.03.1+446 Cherry Blossom (desktop) +# pandoc 2.17.1.1 @ /opt/homebrew/bin/pandoc +# +# ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── +# package * version date (UTC) lib source +# AnnotationDbi 1.62.1 2023-05-02 [1] Bioconductor +# AnnotationHub 3.8.0 2023-04-25 [1] Bioconductor +# attempt 0.3.1 2020-05-03 [1] CRAN (R 4.3.0) +# beachmat 2.16.0 2023-04-25 [1] Bioconductor +# beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) +# benchmarkme 1.0.8 2022-06-12 [1] CRAN (R 4.3.0) +# benchmarkmeData 1.0.4 2020-04-23 [1] CRAN (R 4.3.0) +# Biobase * 2.60.0 2023-04-25 [1] Bioconductor +# BiocFileCache 2.8.0 2023-04-25 [1] Bioconductor +# BiocGenerics * 0.46.0 2023-04-25 [1] Bioconductor +# BiocIO 1.10.0 2023-04-25 [1] Bioconductor +# BiocManager 1.30.20 2023-02-24 [1] CRAN (R 4.3.0) +# BiocNeighbors 1.18.0 2023-04-25 [1] Bioconductor +# BiocParallel 1.34.1 2023-05-08 [1] Bioconductor +# BiocSingular 1.16.0 2023-04-25 [1] Bioconductor +# biocthis 1.11.1 2023-05-06 [1] Github (lcolladotor/biocthis@42dc8df) +# BiocVersion 3.17.1 2022-12-20 [1] Bioconductor +# Biostrings 2.68.1 2023-05-16 [1] Bioconductor +# bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) +# bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) +# bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) +# blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) +# brio 1.1.3 2021-11-30 [1] CRAN (R 4.3.0) +# bslib 0.4.2 2022-12-16 [1] CRAN (R 4.3.0) +# cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) +# callr 3.7.3 2022-11-02 [1] CRAN (R 4.3.0) +# cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) +# codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.0) +# colorout 1.2-2 2023-05-06 [1] Github (jalvesaq/colorout@79931fd) +# colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) +# config 0.3.1 2020-12-17 [1] CRAN (R 4.3.0) +# cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) +# crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) +# curl 5.0.0 2023-01-12 [1] CRAN (R 4.3.0) +# data.table 1.14.8 2023-02-17 [1] CRAN (R 4.3.0) +# DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) +# dbplyr 2.3.2 2023-03-21 [1] CRAN (R 4.3.0) +# DelayedArray 0.26.2 2023-05-05 [1] Bioconductor +# DelayedMatrixStats 1.22.0 2023-04-25 [1] Bioconductor +# devtools * 2.4.5 2022-10-11 [1] CRAN (R 4.3.0) +# digest 0.6.31 2022-12-11 [1] CRAN (R 4.3.0) +# doParallel 1.0.17 2022-02-07 [1] CRAN (R 4.3.0) +# dotCall64 1.0-2 2022-10-03 [1] CRAN (R 4.3.0) +# dplyr 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) +# dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) +# DropletUtils 1.20.0 2023-05-08 [1] Bioconductor +# DT 0.28 2023-05-18 [1] CRAN (R 4.3.0) +# edgeR 3.42.2 2023-05-08 [1] Bioconductor +# ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) +# ExperimentHub 2.8.0 2023-04-25 [1] Bioconductor +# fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) +# fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) +# fields 14.1 2022-08-12 [1] CRAN (R 4.3.0) +# filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) +# foreach 1.5.2 2022-02-02 [1] CRAN (R 4.3.0) +# fs 1.6.2 2023-04-25 [1] CRAN (R 4.3.0) +# generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) +# GenomeInfoDb * 1.36.0 2023-04-25 [1] Bioconductor +# GenomeInfoDbData 1.2.10 2023-05-06 [1] Bioconductor +# GenomicAlignments 1.36.0 2023-04-25 [1] Bioconductor +# GenomicRanges * 1.52.0 2023-04-25 [1] Bioconductor +# ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) +# ggplot2 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) +# ggrepel 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) +# glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) +# golem 0.4.0 2023-03-12 [1] CRAN (R 4.3.0) +# gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) +# gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) +# HDF5Array 1.28.1 2023-05-01 [1] Bioconductor +# here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) +# hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) +# htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) +# htmlwidgets 1.6.2 2023-03-17 [1] CRAN (R 4.3.0) +# httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) +# httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) +# interactiveDisplayBase 1.38.0 2023-04-25 [1] Bioconductor +# IRanges * 2.34.0 2023-04-25 [1] Bioconductor +# irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) +# iterators 1.0.14 2022-02-05 [1] CRAN (R 4.3.0) +# jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) +# jsonlite 1.8.4 2022-12-06 [1] CRAN (R 4.3.0) +# KEGGREST 1.40.0 2023-04-25 [1] Bioconductor +# later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) +# lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.0) +# lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) +# lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) +# limma 3.56.1 2023-05-08 [1] Bioconductor +# lobstr 1.1.2 2022-06-22 [1] CRAN (R 4.3.0) +# locfit 1.5-9.7 2023-01-02 [1] CRAN (R 4.3.0) +# lubridate 1.9.2 2023-02-10 [1] CRAN (R 4.3.0) +# magick 2.7.4 2023-03-09 [1] CRAN (R 4.3.0) +# magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) +# maps 3.4.1 2022-10-30 [1] CRAN (R 4.3.0) +# Matrix 1.5-4.1 2023-05-18 [1] CRAN (R 4.3.0) +# MatrixGenerics * 1.12.0 2023-04-25 [1] Bioconductor +# matrixStats * 0.63.0 2022-11-18 [1] CRAN (R 4.3.0) +# memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) +# mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) +# miniUI 0.1.1.1 2018-05-18 [1] CRAN (R 4.3.0) +# munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) +# paletteer 1.5.0 2022-10-19 [1] CRAN (R 4.3.0) +# pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) +# pkgbuild 1.4.0 2022-11-27 [1] CRAN (R 4.3.0) +# pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) +# pkgload 1.3.2 2022-11-16 [1] CRAN (R 4.3.0) +# plotly 4.10.1 2022-11-07 [1] CRAN (R 4.3.0) +# png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) +# prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) +# processx 3.8.1 2023-04-18 [1] CRAN (R 4.3.0) +# profvis 0.3.8 2023-05-02 [1] CRAN (R 4.3.0) +# promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) +# prompt 1.0.1 2023-05-06 [1] Github (gaborcsardi/prompt@7ef0f2e) +# ps 1.7.5 2023-04-18 [1] CRAN (R 4.3.0) +# purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) +# R.cache 0.16.0 2022-07-21 [1] CRAN (R 4.3.0) +# R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) +# R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) +# R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) +# R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) +# rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) +# RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) +# Rcpp 1.0.10 2023-01-22 [1] CRAN (R 4.3.0) +# RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) +# rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.3.0) +# remotes 2.4.2 2021-11-30 [1] CRAN (R 4.3.0) +# restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) +# rhdf5 2.44.0 2023-04-25 [1] Bioconductor +# rhdf5filters 1.12.1 2023-04-30 [1] Bioconductor +# Rhdf5lib 1.22.0 2023-04-25 [1] Bioconductor +# rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) +# rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) +# rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) +# Rsamtools 2.16.0 2023-04-25 [1] Bioconductor +# RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) +# rsthemes 0.4.0 2023-05-06 [1] Github (gadenbuie/rsthemes@34a55a4) +# rstudioapi 0.14 2022-08-22 [1] CRAN (R 4.3.0) +# rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) +# rtracklayer 1.60.0 2023-04-25 [1] Bioconductor +# S4Arrays 1.0.4 2023-05-14 [1] Bioconductor +# S4Vectors * 0.38.1 2023-05-02 [1] Bioconductor +# sass 0.4.6.9000 2023-05-06 [1] Github (rstudio/sass@f248fe5) +# ScaledMatrix 1.8.1 2023-05-03 [1] Bioconductor +# scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) +# scater 1.28.0 2023-04-25 [1] Bioconductor +# scuttle 1.10.1 2023-05-02 [1] Bioconductor +# sessioninfo * 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) +# shiny 1.7.4 2022-12-15 [1] CRAN (R 4.3.0) +# shinyWidgets 0.7.6 2023-01-08 [1] CRAN (R 4.3.0) +# SingleCellExperiment * 1.22.0 2023-04-25 [1] Bioconductor +# spam 2.9-1 2022-08-07 [1] CRAN (R 4.3.0) +# sparseMatrixStats 1.12.0 2023-04-25 [1] Bioconductor +# SpatialExperiment * 1.10.0 2023-04-25 [1] Bioconductor +# spatialLIBD * 1.12.0 2023-04-27 [1] Bioconductor +# statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) +# stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) +# stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) +# styler 1.9.1 2023-03-04 [1] CRAN (R 4.3.0) +# SummarizedExperiment * 1.30.1 2023-05-01 [1] Bioconductor +# suncalc 0.5.1 2022-09-29 [1] CRAN (R 4.3.0) +# testthat * 3.1.8 2023-05-04 [1] CRAN (R 4.3.0) +# tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) +# tidyr 1.3.0 2023-01-24 [1] CRAN (R 4.3.0) +# tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) +# timechange 0.2.0 2023-01-11 [1] CRAN (R 4.3.0) +# urlchecker 1.0.1 2021-11-30 [1] CRAN (R 4.3.0) +# usethis * 2.1.6 2022-05-25 [1] CRAN (R 4.3.0) +# utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) +# vctrs 0.6.2 2023-04-19 [1] CRAN (R 4.3.0) +# vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) +# viridis 0.6.3 2023-05-03 [1] CRAN (R 4.3.0) +# viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) +# withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) +# XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) +# xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) +# XVector 0.40.0 2023-04-25 [1] Bioconductor +# yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) +# zlibbioc 1.46.0 2023-04-25 [1] Bioconductor +# +# [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library +# +# ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + diff --git a/inst/extdata/metadata_spatialDLPFC.csv b/inst/extdata/metadata_spatialDLPFC.csv index eed6daaa..bcb2b822 100644 --- a/inst/extdata/metadata_spatialDLPFC.csv +++ b/inst/extdata/metadata_spatialDLPFC.csv @@ -1,5 +1,6 @@ "Title","Description","BiocVersion","Genome","SourceType","SourceUrl","SourceVersion","Species","TaxonomyId","Coordinate_1_based","DataProvider","Maintainer","RDataClass","DispatchClass","RDataPath","Tags" "spatialDLPFC_Visium_spe","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spe_filtered_final_with_clusters_and_deconvolution_results.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" +"spatialDLPFC_Visium_example_subset","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Subsetted to just 3 samples with only the lowres images for example purposes.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spatialDLPFC_spe_subset_example.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" "spatialDLPFC_Visium_pseudobulk_spe","Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/sce_pseudo_BayesSpace_k09.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" "spatialDLPFC_Visium_modeling_results","List of modeling results at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","list","Rda","spatialLIBD/spatialLIBD_files/modeling_results_BayesSpace_k09.Rdata","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" "spatialDLPFC_Visium_SPG","SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 4) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.","3.17","GRCh38","GTF","https://bioconductor.org/packages/spatialLIBD","Mar 17 2023","Homo sapiens",9606,TRUE,"LIBD","Leonardo Collado-Torres ","SpatialExperiment","Rds","spatialLIBD/spatialLIBD_files/spe.rds","spatialDLPFC_Visium_VisiumSPG_snRNAseq_spatialLIBD" diff --git a/inst/scripts/make-metadata_spatialDLPFC.R b/inst/scripts/make-metadata_spatialDLPFC.R index 7e250d79..b728b856 100644 --- a/inst/scripts/make-metadata_spatialDLPFC.R +++ b/inst/scripts/make-metadata_spatialDLPFC.R @@ -9,6 +9,7 @@ pkgname <- "spatialLIBD" meta <- data.frame( Title = c( "spatialDLPFC_Visium_spe", + "spatialDLPFC_Visium_example_subset", "spatialDLPFC_Visium_pseudobulk_spe", "spatialDLPFC_Visium_modeling_results", "spatialDLPFC_Visium_SPG", @@ -16,6 +17,7 @@ meta <- data.frame( ), Description = c( "SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Subsetted to just 3 samples with only the lowres images for example purposes.", "Pseudo-bulked SingleCellExperiment object (SpatialExperiment object without spatial data) at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", "List of modeling results at the Sp09D spatial domain resolution for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 30) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", "SpatialExperiment object at the spot-level for the spatialDLPFC human brain (DLPFC) spatial transcriptomics data (n = 4) from the Visium Spatial Proteogenomics (Visium-SPG) platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", @@ -32,18 +34,20 @@ meta <- data.frame( DataProvider = "LIBD", Maintainer = "Leonardo Collado-Torres ", RDataClass = c( + "SpatialExperiment", "SpatialExperiment", "SpatialExperiment", "list", "SpatialExperiment", "SingleCellExperiment" ), - DispatchClass = c("Rds", "Rds", "Rda", "Rds", "FilePath"), + DispatchClass = c("Rds", "Rds", "Rds", "Rda", "Rds", "FilePath"), RDataPath = file.path( pkgname, outdir, c( "spe_filtered_final_with_clusters_and_deconvolution_results.rds", + "spatialDLPFC_spe_subset_example.rds", "sce_pseudo_BayesSpace_k09.rds", "modeling_results_BayesSpace_k09.Rdata", "spe.rds", diff --git a/man/fetch_data.Rd b/man/fetch_data.Rd index eebb2d2b..b77f5aa9 100644 --- a/man/fetch_data.Rd +++ b/man/fetch_data.Rd @@ -6,10 +6,10 @@ \usage{ fetch_data( type = c("sce", "sce_layer", "modeling_results", "sce_example", "spe", - "spatialDLPFC_Visium", "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", + "spatialDLPFC_Visium", "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", "Visium_SPG_AD_Visium_targeted_spe", "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", "Visium_SPG_AD_Visium_wholegenome_modeling_results"), destdir = tempdir(), From edc8b72505af097895dcbf35887df28da8122e3c Mon Sep 17 00:00:00 2001 From: Leonardo Collado Torres Date: Wed, 24 May 2023 07:25:09 +0100 Subject: [PATCH 046/259] Ignore the linux system dependencies step for now https://github.com/LieberInstitute/spatialLIBD/actions/runs/5062773024/jobs/9093822984#step:10:1 --- .github/workflows/check-bioc.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index 82b58998..86907f3b 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -116,12 +116,12 @@ jobs: key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3-${{ hashFiles('.github/depends.Rds') }} restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3- - - name: Install Linux system dependencies - if: runner.os == 'Linux' - run: | - sysreqs=$(Rscript -e 'cat("apt-get update -y && apt-get install -y", paste(gsub("apt-get install -y ", "", remotes::system_requirements("ubuntu", "20.04")), collapse = " "))') - echo $sysreqs - sudo -s eval "$sysreqs" + # - name: Install Linux system dependencies + # if: runner.os == 'Linux' + # run: | + # sysreqs=$(Rscript -e 'cat("apt-get update -y && apt-get install -y", paste(gsub("apt-get install -y ", "", remotes::system_requirements("ubuntu", "20.04")), collapse = " "))') + # echo $sysreqs + # sudo -s eval "$sysreqs" - name: Install macOS system dependencies if: matrix.config.os == 'macOS-latest' From 66f7b7ba72be86ed65ed70bb1251f314bcdc332e Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Mon, 3 Jul 2023 22:19:03 -0400 Subject: [PATCH 047/259] Trigger a GHA new run --- _pkgdown.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/_pkgdown.yml b/_pkgdown.yml index 6ef5f5a6..e047e6e6 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1 +1,2 @@ destination: docs + From aeaba31b13f19d6739f31bd1c26a5d5f07ea3f3d Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 5 Sep 2023 15:45:41 -0400 Subject: [PATCH 048/259] v1.13.5 -- allow disabling auto_crop on the shiny apps for cases where your images do not follow the expected dimensions for Visium grids, such as when you manually stitched images together --- DESCRIPTION | 4 ++-- NEWS.md | 9 +++++++++ R/app_ui.R | 3 ++- R/run_app.R | 6 ++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c8ae742f..5bf620bf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.13.4 -Date: 2023-05-23 +Version: 1.13.5 +Date: 2023-09-05 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 2b945752..1b89419e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.13.5 + +NEW FEATURES + +* `run_app()` now has a `auto_crop_default` argument set to `TRUE` by default. +It can be turned off in cases where you are displaying images that do not +follow the expected Visium grid dimensions, such as manually stitched images +that you don't want to automatically crop. + # spatialLIBD 1.13.4 NEW FEATURES diff --git a/R/app_ui.R b/R/app_ui.R index 88455b14..410bb374 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -14,6 +14,7 @@ app_ui <- function() { sce_layer <- golem::get_golem_options("sce_layer") modeling_results <- golem::get_golem_options("modeling_results") sig_genes <- golem::get_golem_options("sig_genes") + auto_crop_default <- golem::get_golem_options("auto_crop_default") red_dim_names <- reducedDimNames(spe) if (length(red_dim_names) > 0) { @@ -169,7 +170,7 @@ app_ui <- function() { checkboxInput( "auto_crop", "Should the image be automatically cropped?", - value = TRUE + value = auto_crop_default ), hr(), selectInput( diff --git a/R/run_app.R b/R/run_app.R index dd6820f3..b7beae48 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -36,6 +36,10 @@ #' @param default_cluster A `character(1)` with the name of the main cluster #' (discrete) variable to use. It will have to be present in both `colData(spe)` #' and `colData(sce_layer)`. +#' @param auto_crop_default A `logical(1)` specifying the default value for +#' automatically cropping the images. Set this to `FALSE` if your images do not +#' follow the Visium grid size expectations, which are key for enabling +#' auto-cropping. #' @param ... Other arguments passed to the list of golem options for running #' the application. #' @@ -228,6 +232,7 @@ run_app <- function(spe = fetch_data(type = "spe"), "expr_chrM_ratio" ), default_cluster = "spatialLIBD", + auto_crop_default = TRUE, ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) @@ -275,6 +280,7 @@ run_app <- function(spe = fetch_data(type = "spe"), spe_discrete_vars = spe_discrete_vars, spe_continuous_vars = spe_continuous_vars, default_cluster = default_cluster, + auto_crop_default = auto_crop_default, ... ) ) From be5be0e0354f02c5e3c349822fc466f625fc382b Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 15 Sep 2023 13:26:09 -0400 Subject: [PATCH 049/259] v1.13.6 -- resolve #43 --- DESCRIPTION | 4 ++-- NEWS.md | 8 ++++++++ R/vis_clus.R | 23 ++++++++++++++++++++++- R/vis_clus_p.R | 5 +++-- R/vis_gene.R | 5 ----- R/vis_grid_clus.R | 2 ++ man/run_app.Rd | 6 ++++++ man/vis_clus.Rd | 21 +++++++++++++++++++++ man/vis_clus_p.Rd | 9 ++++++++- man/vis_grid_clus.Rd | 7 +++++++ 10 files changed, 79 insertions(+), 11 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5bf620bf..74e74b51 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.13.5 -Date: 2023-09-05 +Version: 1.13.6 +Date: 2023-09-15 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 1b89419e..72d76cb4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# spatialLIBD 1.13.6 + +NEW FEATURES + +* `vis_clus_p()`, `vis_clus()`, and `vis_grid_clus()` now all use implement the +`na_color` argument that was present in the `vis_gene()` functions. This +resolves https://github.com/LieberInstitute/spatialLIBD/issues/43 by @boyiguo1. + # spatialLIBD 1.13.5 NEW FEATURES diff --git a/R/vis_clus.R b/R/vis_clus.R index a4b006c8..d3f00dc1 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -24,6 +24,11 @@ #' @param auto_crop A `logical(1)` indicating whether to automatically crop #' the image / plotting area, which is useful if the Visium capture area is #' not centered on the image and if the image is not a square. +#' @param na_color A `character(1)` specifying a color for the NA values. +#' If you set `alpha = NA` then it's best to set `na_color` to a color that has +#' alpha blending already, which will make non-NA values pop up more and the NA +#' values will show with a lighter color. This behavior is lost when `alpha` is +#' set to a non-`NA` value. #' @param ... Passed to [paste0()][base::paste] for making the title of the #' plot following the `sampleid`. #' @@ -74,6 +79,20 @@ #' spatial = FALSE #' ) #' print(p3) +#' +#' ## With some NA values +#' spe$tmp <- spe$layer_guess_reordered +#' spe$tmp[spe$sample_id == "151673"][seq_len(500)] <- NA +#' p4 <- vis_clus( +#' spe = spe, +#' clustervar = "tmp", +#' sampleid = "151673", +#' colors = libd_layer_colors, +#' na_color = "white", +#' ... = " LIBD Layers" +#' ) +#' print(p4) +#' #' } vis_clus <- function(spe, sampleid = unique(spe$sample_id)[1], @@ -97,6 +116,7 @@ vis_clus <- function(spe, alpha = NA, point_size = 2, auto_crop = TRUE, + na_color = "#CCCCCC40", ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) @@ -112,6 +132,7 @@ vis_clus <- function(spe, image_id = image_id, alpha = alpha, point_size = point_size, - auto_crop = auto_crop + auto_crop = auto_crop, + na_color = na_color ) } diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index 34aecaef..a91ce369 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -52,7 +52,8 @@ vis_clus_p <- image_id = "lowres", alpha = NA, point_size = 2, - auto_crop = TRUE) { + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) @@ -112,7 +113,7 @@ vis_clus_p <- alpha = alpha ) + coord_fixed(expand = FALSE) + - scale_fill_manual(values = colors) + + scale_fill_manual(values = colors, na.value = na_color) + xlim(0, ncol(img)) + ylim(nrow(img), 0) + xlab("") + ylab("") + diff --git a/R/vis_gene.R b/R/vis_gene.R index 712800de..673bb453 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -23,11 +23,6 @@ #' dependent on cell density. #' @param cont_colors A `character()` vector of colors that supersedes the #' `viridis` argument. -#' @param na_color A `character(1)` specifying a color for the NA values. -#' If you set `alpha = NA` then it's best to set `na_color` to a color that has -#' alpha blending already, which will make non-NA values pop up more and the NA -#' values will show with a lighter color. This behavior is lost when `alpha` is -#' set to a non-`NA` value. #' #' @return A [ggplot2][ggplot2::ggplot] object. #' @export diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 6c90221c..40ead6b3 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -61,6 +61,7 @@ vis_grid_clus <- sample_order = unique(spe$sample_id), point_size = 2, auto_crop = TRUE, + na_color = "#CCCCCC40", ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) @@ -79,6 +80,7 @@ vis_grid_clus <- alpha = alpha, point_size = point_size, auto_crop = auto_crop, + na_color = na_color, ... ) }) diff --git a/man/run_app.Rd b/man/run_app.Rd index ec7f0cb3..5b1d6c6a 100644 --- a/man/run_app.Rd +++ b/man/run_app.Rd @@ -23,6 +23,7 @@ run_app( spe_continuous_vars = c("cell_count", "sum_umi", "sum_gene", "expr_chrM", "expr_chrM_ratio"), default_cluster = "spatialLIBD", + auto_crop_default = TRUE, ... ) } @@ -69,6 +70,11 @@ as genes. They will have to be present in \code{colData(sce)}.} (discrete) variable to use. It will have to be present in both \code{colData(spe)} and \code{colData(sce_layer)}.} +\item{auto_crop_default}{A \code{logical(1)} specifying the default value for +automatically cropping the images. Set this to \code{FALSE} if your images do not +follow the Visium grid size expectations, which are key for enabling +auto-cropping.} + \item{...}{Other arguments passed to the list of golem options for running the application.} } diff --git a/man/vis_clus.Rd b/man/vis_clus.Rd index 4bb0c369..ebb948c2 100644 --- a/man/vis_clus.Rd +++ b/man/vis_clus.Rd @@ -15,6 +15,7 @@ vis_clus( alpha = NA, point_size = 2, auto_crop = TRUE, + na_color = "#CCCCCC40", ... ) } @@ -52,6 +53,12 @@ to \code{1.25}. Some colors look better if you use \code{2} for instance.} the image / plotting area, which is useful if the Visium capture area is not centered on the image and if the image is not a square.} +\item{na_color}{A \code{character(1)} specifying a color for the NA values. +If you set \code{alpha = NA} then it's best to set \code{na_color} to a color that has +alpha blending already, which will make non-NA values pop up more and the NA +values will show with a lighter color. This behavior is lost when \code{alpha} is +set to a non-\code{NA} value.} + \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} } @@ -107,6 +114,20 @@ if (enough_ram()) { spatial = FALSE ) print(p3) + + ## With some NA values + spe$tmp <- spe$layer_guess_reordered + spe$tmp[spe$sample_id == "151673"][seq_len(500)] <- NA + p4 <- vis_clus( + spe = spe, + clustervar = "tmp", + sampleid = "151673", + colors = libd_layer_colors, + na_color = "white", + ... = " LIBD Layers" + ) + print(p4) + } } \seealso{ diff --git a/man/vis_clus_p.Rd b/man/vis_clus_p.Rd index ba154839..3706e6a2 100644 --- a/man/vis_clus_p.Rd +++ b/man/vis_clus_p.Rd @@ -15,7 +15,8 @@ vis_clus_p( image_id = "lowres", alpha = NA, point_size = 2, - auto_crop = TRUE + auto_crop = TRUE, + na_color = "#CCCCCC40" ) } \arguments{ @@ -56,6 +57,12 @@ to \code{1.25}. Some colors look better if you use \code{2} for instance.} \item{auto_crop}{A \code{logical(1)} indicating whether to automatically crop the image / plotting area, which is useful if the Visium capture area is not centered on the image and if the image is not a square.} + +\item{na_color}{A \code{character(1)} specifying a color for the NA values. +If you set \code{alpha = NA} then it's best to set \code{na_color} to a color that has +alpha blending already, which will make non-NA values pop up more and the NA +values will show with a lighter color. This behavior is lost when \code{alpha} is +set to a non-\code{NA} value.} } \value{ A \link[ggplot2:ggplot]{ggplot2} object. diff --git a/man/vis_grid_clus.Rd b/man/vis_grid_clus.Rd index 52fd0be5..6d9a3690 100644 --- a/man/vis_grid_clus.Rd +++ b/man/vis_grid_clus.Rd @@ -19,6 +19,7 @@ vis_grid_clus( sample_order = unique(spe$sample_id), point_size = 2, auto_crop = TRUE, + na_color = "#CCCCCC40", ... ) } @@ -69,6 +70,12 @@ to \code{1.25}. Some colors look better if you use \code{2} for instance.} the image / plotting area, which is useful if the Visium capture area is not centered on the image and if the image is not a square.} +\item{na_color}{A \code{character(1)} specifying a color for the NA values. +If you set \code{alpha = NA} then it's best to set \code{na_color} to a color that has +alpha blending already, which will make non-NA values pop up more and the NA +values will show with a lighter color. This behavior is lost when \code{alpha} is +set to a non-\code{NA} value.} + \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} } From 211922009c4b5968b6bc33cd9f8aea6a7231b6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Pag=C3=A8s?= Date: Tue, 24 Oct 2023 09:20:54 -0400 Subject: [PATCH 050/259] bump x.y.z version to even y prior to creation of RELEASE_3_18 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 74e74b51..93e18452 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.13.6 +Version: 1.14.0 Date: 2023-09-15 Authors@R: c( From 5ed2dd3bc0bfbf714cbb8d36eb7683ec37595341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Pag=C3=A8s?= Date: Tue, 24 Oct 2023 09:20:54 -0400 Subject: [PATCH 051/259] bump x.y.z version to odd y following creation of RELEASE_3_18 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 93e18452..b9a57a0e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.14.0 +Version: 1.15.0 Date: 2023-09-15 Authors@R: c( From 94048657dd0cf134b8e2347933e4302f75cec415 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 29 Nov 2023 14:50:17 -0600 Subject: [PATCH 052/259] v1.15.1 -- Add DropletUtils to Suggests as recommended by Jennifer Wokaty --- DESCRIPTION | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b9a57a0e..c853019c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.15.0 -Date: 2023-09-15 +Version: 1.15.1 +Date: 2023-11-29 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), @@ -90,7 +90,8 @@ Suggests: covr, here, BiocManager, - lobstr + lobstr, + DropletUtils VignetteBuilder: knitr biocViews: Homo_sapiens_Data, ExperimentHub, SequencingData, SingleCellData, ExpressionData, Tissue, PackageTypeData, SpatialData From ef76198a98c73b713de4b6a8795604b6b7d593ed Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 29 Nov 2023 14:51:34 -0600 Subject: [PATCH 053/259] Fix spacing --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index c853019c..d80b87ca 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -91,7 +91,7 @@ Suggests: here, BiocManager, lobstr, - DropletUtils + DropletUtils VignetteBuilder: knitr biocViews: Homo_sapiens_Data, ExperimentHub, SequencingData, SingleCellData, ExpressionData, Tissue, PackageTypeData, SpatialData From ca1eb3f6fa7cfa3c04b4a1f55cec7430f9f50593 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 15 Feb 2024 14:33:43 -0500 Subject: [PATCH 054/259] Update GHA workflow to use Bioc 3.18 using biocthis::use_bioc_github_action(), but preserve settings otherwise --- .github/workflows/check-bioc.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index 86907f3b..2b37d332 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -52,9 +52,9 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-latest, r: '4.3', bioc: '3.17', cont: "bioconductor/bioconductor_docker:RELEASE_3_17", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } - - { os: macOS-latest, r: '4.3', bioc: '3.17'} - - { os: windows-latest, r: '4.3', bioc: '3.17'} + - { os: ubuntu-latest, r: '4.3', bioc: '3.18', cont: "bioconductor/bioconductor_docker:RELEASE_3_18", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } + - { os: macOS-latest, r: '4.3', bioc: '3.18'} + - { os: windows-latest, r: '4.3', bioc: '3.18'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent env: @@ -105,16 +105,16 @@ jobs: uses: actions/cache@v3 with: path: ${{ env.R_LIBS_USER }} - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3- - name: Cache R packages on Linux if: "!contains(github.event.head_commit.message, '/nocache') && runner.os == 'Linux' " uses: actions/cache@v3 with: path: /home/runner/work/_temp/Library - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3- # - name: Install Linux system dependencies # if: runner.os == 'Linux' @@ -286,7 +286,7 @@ jobs: if: failure() uses: actions/upload-artifact@master with: - name: ${{ runner.os }}-biocversion-RELEASE_3_17-r-4.3-results + name: ${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3-results path: check From 97531b28238fede7b9026ccc732de7561f7e02dc Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 13:13:51 -0500 Subject: [PATCH 055/259] Overhaul how 'geneid' is validated and used to extract continuous variables-- allow for vectors of any length, and allow mixing and matching of continuous variables (from colData) with genes. Behavior remains identical for vectors of length 1 --- R/vis_gene.R | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index 673bb453..708f2891 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -125,15 +125,47 @@ vis_gene <- spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) - if (geneid %in% colnames(colData(spe_sub))) { - d$COUNT <- colData(spe_sub)[[geneid]] - } else if (geneid %in% rowData(spe_sub)$gene_search) { - d$COUNT <- - assays(spe_sub)[[assayname]][which(rowData(spe_sub)$gene_search == geneid), ] - } else if (geneid %in% rownames(spe_sub)) { - d$COUNT <- assays(spe_sub)[[assayname]][which(rownames(spe_sub) == geneid), ] - } else { - stop("Could not find the 'geneid' ", geneid, call. = FALSE) + # Verify legitimacy of names in geneid + geneid_is_valid = (geneid %in% rowData(spe_sub)$gene_search) | + (geneid %in% rownames(spe_sub)) | + (geneid %in% colnames(colData(spe_sub))) + if (any(!geneid_is_valid)) { + stop( + "Could not find the 'geneid'(s) ", + paste(geneid[!geneid_is_valid], collapse = ', '), + call. = FALSE + ) + } + + # Grab any continuous colData columns + cont_cols = as.matrix( + colData(spe_sub)[ + , geneid[geneid %in% colnames(colData(spe_sub))], drop = FALSE + ] + ) + + # Get the integer indices of each gene in the SpatialExperiment, since we + # aren't guaranteed that rownames are gene names + remaining_geneid = geneid[!(geneid %in% colnames(colData(spe_sub)))] + valid_gene_indices = unique( + c( + match(remaining_geneid, rowData(spe_sub)$gene_search), + match(remaining_geneid, rownames(spe_sub)) + ) + ) + valid_gene_indices = valid_gene_indices[!is.na(valid_gene_indices)] + + # Grab any genes + gene_cols = t( + as.matrix(assays(spe_sub[valid_gene_indices, ])[[assayname]]) + ) + + # Combine into one matrix where rows are genes and columns are continuous + # features + cont_matrix = cbind(cont_cols, gene_cols) + + if (ncol(cont_matrix) == 1) { + d$COUNT = cont_matrix[,1] } d$COUNT[d$COUNT <= minCount] <- NA p <- vis_gene_p( From ebeb89b355e2b49916c55e0f05ecee15340d95c5 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 13:23:10 -0500 Subject: [PATCH 056/259] Add a 'multi_gene_method' parameter to 'vis_gene', and clarify that 'geneid' is allowed to be a length > 1 vector --- DESCRIPTION | 2 +- R/vis_gene.R | 13 +++++++++---- man/annotate_registered_clusters.Rd | 4 ++-- man/check_modeling_results.Rd | 2 +- man/check_spe.Rd | 4 ++-- man/frame_limits.Rd | 2 +- man/img_edit.Rd | 4 ++-- man/layer_boxplot.Rd | 4 ++-- man/vis_gene.Rd | 14 ++++++++++---- man/vis_grid_clus.Rd | 4 ++-- man/vis_grid_gene.Rd | 14 ++++++++------ 11 files changed, 40 insertions(+), 27 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d80b87ca..e8ae3f82 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -77,7 +77,7 @@ Imports: edgeR, limma, statmod -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Roxygen: list(markdown = TRUE) URL: https://github.com/LieberInstitute/spatialLIBD BugReports: https://support.bioconductor.org/tag/spatialLIBD diff --git a/R/vis_gene.R b/R/vis_gene.R index 708f2891..74cef189 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -6,10 +6,12 @@ #' To visualize clusters (or any discrete variable) use [vis_clus()]. #' #' @inheritParams vis_clus -#' @param geneid A `character(1)` specifying the gene ID stored in -#' `rowData(spe)$gene_search` or a continuous variable stored in `colData(spe)` -#' to visualize. If `rowData(spe)$gene_search` is missing, then `rownames(spe)` -#' is used to search for the gene ID. +#' @param geneid A `character()` specifying the gene ID(s) stored in +#' `rowData(spe)$gene_search` or a continuous variable(s) stored in `colData(spe)` +#' to visualize. For each ID, if `rowData(spe)$gene_search` is missing, then +#' `rownames(spe)` is used to search for the gene ID. When a vector of length > 1 +#' is supplied, the continuous variables are combined according to \code{multi_gene_method}, +#' producing a single value for each spot. #' @param assayname The name of the `assays(spe)` to use for extracting the #' gene expression data. Defaults to `logcounts`. #' @param minCount A `numeric(1)` specifying the minimum gene expression (or @@ -23,6 +25,9 @@ #' dependent on cell density. #' @param cont_colors A `character()` vector of colors that supersedes the #' `viridis` argument. +#' @param multi_gene_method A \code{character(1)}: either "pca", "sparsity", or +#' "z_score". This parameter controls how multiple continuous variables are +#' combined for visualization, and only applies when \code{geneid} has length > 1. #' #' @return A [ggplot2][ggplot2::ggplot] object. #' @export diff --git a/man/annotate_registered_clusters.Rd b/man/annotate_registered_clusters.Rd index a8305229..41d6245a 100644 --- a/man/annotate_registered_clusters.Rd +++ b/man/annotate_registered_clusters.Rd @@ -64,7 +64,7 @@ annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) } \seealso{ Other Layer correlation functions: -\code{\link{layer_stat_cor_plot}()}, -\code{\link{layer_stat_cor}()} +\code{\link{layer_stat_cor}()}, +\code{\link{layer_stat_cor_plot}()} } \concept{Layer correlation functions} diff --git a/man/check_modeling_results.Rd b/man/check_modeling_results.Rd index 38aa3b8b..48cf5f6a 100644 --- a/man/check_modeling_results.Rd +++ b/man/check_modeling_results.Rd @@ -32,8 +32,8 @@ xx <- check_modeling_results(modeling_results) } \seealso{ Other Check input functions: -\code{\link{check_sce_layer}()}, \code{\link{check_sce}()}, +\code{\link{check_sce_layer}()}, \code{\link{check_spe}()} } \concept{Check input functions} diff --git a/man/check_spe.Rd b/man/check_spe.Rd index ec0a6a5a..ecaa9867 100644 --- a/man/check_spe.Rd +++ b/man/check_spe.Rd @@ -39,8 +39,8 @@ if (enough_ram()) { \seealso{ Other Check input functions: \code{\link{check_modeling_results}()}, -\code{\link{check_sce_layer}()}, -\code{\link{check_sce}()} +\code{\link{check_sce}()}, +\code{\link{check_sce_layer}()} } \author{ Brenda Pardo, Leonardo Collado-Torres diff --git a/man/frame_limits.Rd b/man/frame_limits.Rd index e7ee4089..8b5cbe77 100644 --- a/man/frame_limits.Rd +++ b/man/frame_limits.Rd @@ -57,8 +57,8 @@ if (enough_ram()) { } \seealso{ Other Spatial cluster visualization functions: -\code{\link{vis_clus_p}()}, \code{\link{vis_clus}()}, +\code{\link{vis_clus_p}()}, \code{\link{vis_grid_clus}()} } \author{ diff --git a/man/img_edit.Rd b/man/img_edit.Rd index bec5908e..699bea07 100644 --- a/man/img_edit.Rd +++ b/man/img_edit.Rd @@ -108,7 +108,7 @@ if (enough_ram()) { } \seealso{ Other Image editing functions: -\code{\link{img_update_all}()}, -\code{\link{img_update}()} +\code{\link{img_update}()}, +\code{\link{img_update_all}()} } \concept{Image editing functions} diff --git a/man/layer_boxplot.Rd b/man/layer_boxplot.Rd index ea3a0cc2..6b09350b 100644 --- a/man/layer_boxplot.Rd +++ b/man/layer_boxplot.Rd @@ -153,7 +153,7 @@ https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses } \seealso{ Other Layer modeling functions: -\code{\link{sig_genes_extract_all}()}, -\code{\link{sig_genes_extract}()} +\code{\link{sig_genes_extract}()}, +\code{\link{sig_genes_extract_all}()} } \concept{Layer modeling functions} diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index 339c5296..9624ce19 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -32,10 +32,12 @@ visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more \item{sampleid}{A \code{character(1)} specifying which sample to plot from \code{colData(spe)$sample_id} (formerly \code{colData(spe)$sample_name}).} -\item{geneid}{A \code{character(1)} specifying the gene ID stored in -\code{rowData(spe)$gene_search} or a continuous variable stored in \code{colData(spe)} -to visualize. If \code{rowData(spe)$gene_search} is missing, then \code{rownames(spe)} -is used to search for the gene ID.} +\item{geneid}{A \code{character()} specifying the gene ID(s) stored in +\code{rowData(spe)$gene_search} or a continuous variable(s) stored in \code{colData(spe)} +to visualize. For each ID, if \code{rowData(spe)$gene_search} is missing, then +\code{rownames(spe)} is used to search for the gene ID. When a vector of length > 1 +is supplied, the continuous variables are combined according to \code{multi_gene_method}, +producing a single value for each spot.} \item{spatial}{A \code{logical(1)} indicating whether to include the histology layer from \code{\link[=geom_spatial]{geom_spatial()}}. If you plan to use @@ -79,6 +81,10 @@ set to a non-\code{NA} value.} \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} + +\item{multi_gene_method}{A \code{character(1)}: either "pca", "sparsity", or +"z_score". This parameter controls how multiple continuous variables are +combined for visualization, and only applies when \code{geneid} has length > 1.} } \value{ A \link[ggplot2:ggplot]{ggplot2} object. diff --git a/man/vis_grid_clus.Rd b/man/vis_grid_clus.Rd index 6d9a3690..c9410866 100644 --- a/man/vis_grid_clus.Rd +++ b/man/vis_grid_clus.Rd @@ -117,7 +117,7 @@ if (enough_ram()) { \seealso{ Other Spatial cluster visualization functions: \code{\link{frame_limits}()}, -\code{\link{vis_clus_p}()}, -\code{\link{vis_clus}()} +\code{\link{vis_clus}()}, +\code{\link{vis_clus_p}()} } \concept{Spatial cluster visualization functions} diff --git a/man/vis_grid_gene.Rd b/man/vis_grid_gene.Rd index 257c0d05..0ed8c520 100644 --- a/man/vis_grid_gene.Rd +++ b/man/vis_grid_gene.Rd @@ -33,10 +33,12 @@ vis_grid_gene( object with the spot-level Visium data and information required for visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} -\item{geneid}{A \code{character(1)} specifying the gene ID stored in -\code{rowData(spe)$gene_search} or a continuous variable stored in \code{colData(spe)} -to visualize. If \code{rowData(spe)$gene_search} is missing, then \code{rownames(spe)} -is used to search for the gene ID.} +\item{geneid}{A \code{character()} specifying the gene ID(s) stored in +\code{rowData(spe)$gene_search} or a continuous variable(s) stored in \code{colData(spe)} +to visualize. For each ID, if \code{rowData(spe)$gene_search} is missing, then +\code{rownames(spe)} is used to search for the gene ID. When a vector of length > 1 +is supplied, the continuous variables are combined according to \code{multi_gene_method}, +producing a single value for each spot.} \item{pdf_file}{A \code{character(1)} specifying the path for the resulting PDF.} @@ -129,7 +131,7 @@ if (enough_ram()) { } \seealso{ Other Spatial gene visualization functions: -\code{\link{vis_gene_p}()}, -\code{\link{vis_gene}()} +\code{\link{vis_gene}()}, +\code{\link{vis_gene_p}()} } \concept{Spatial gene visualization functions} From 0c5a19b6b0dd0694ebd6e56eefe969fa59a70106 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 14:08:33 -0500 Subject: [PATCH 057/259] Add a 'multi_gene_method' parameter, and a 'multi_gene_z_score' function corresponding to multi_gene_method='z_score' --- NAMESPACE | 2 ++ R/multi_gene_z_score.R | 21 +++++++++++++++++++++ R/vis_gene.R | 8 ++++++++ man/multi_gene_z_score.Rd | 24 ++++++++++++++++++++++++ man/vis_gene.Rd | 7 ++++--- 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 R/multi_gene_z_score.R create mode 100644 man/multi_gene_z_score.Rd diff --git a/NAMESPACE b/NAMESPACE index d60670e7..2504724c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -46,6 +46,7 @@ export(vis_gene_p) export(vis_grid_clus) export(vis_grid_gene) import(ExperimentHub) +import(MatrixGenerics) import(SingleCellExperiment) import(ggplot2) import(grid) @@ -121,6 +122,7 @@ importFrom(magick,image_transparent) importFrom(methods,is) importFrom(methods,new) importFrom(png,readPNG) +importFrom(rlang,arg_match) importFrom(rtracklayer,import) importFrom(scater,plotReducedDim) importFrom(scuttle,aggregateAcrossCells) diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R new file mode 100644 index 00000000..d0b5aef1 --- /dev/null +++ b/R/multi_gene_z_score.R @@ -0,0 +1,21 @@ +#' Combine multiple continuous variables by averaging Z scores +#' +#' To summarize multiple features, each is normalized to represent a Z-score. +#' Scores are averaged to return a single vector. +#' +#' @param cont_mat A \code{matrix()} with spots as rows and 2 or more continuous +#' variables as columns. +#' +#' @return A \code{numeric()} vector with one element per spot, summarizing the +#' multiple continuous variables. +#' +#' @author Nicholas J. Eagles +#' @import MatrixGenerics +#' @family functions for summarizing expression of multiple continuous variables simultaneously +multi_gene_z_score <- function(cont_mat) { + # For each spot, average Z-scores across all features + cont_z <- (cont_mat - rowMeans(cont_mat)) / rowSds(cont_mat) + z_vec <- colMeans(cont_z, na.rm = TRUE) + + return(z_vec) +} diff --git a/R/vis_gene.R b/R/vis_gene.R index 74cef189..bababaa4 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -33,6 +33,7 @@ #' @export #' @importFrom SummarizedExperiment assays #' @importFrom SpatialExperiment spatialCoords +#' @importFrom rlang arg_match #' @family Spatial gene visualization functions #' @details This function subsets `spe` to the given sample and prepares the #' data and title for [vis_gene_p()]. It also adds a caption to the plot. @@ -126,10 +127,13 @@ vis_gene <- point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) + multi_gene_method = rlang::arg_match(multi_gene_method) + # Verify legitimacy of names in geneid geneid_is_valid = (geneid %in% rowData(spe_sub)$gene_search) | (geneid %in% rownames(spe_sub)) | @@ -171,6 +175,10 @@ vis_gene <- if (ncol(cont_matrix) == 1) { d$COUNT = cont_matrix[,1] + } else { + if (multi_gene_method == 'z_score') { + d$COUNT = multi_gene_z_score(cont_matrix) + } } d$COUNT[d$COUNT <= minCount] <- NA p <- vis_gene_p( diff --git a/man/multi_gene_z_score.Rd b/man/multi_gene_z_score.Rd new file mode 100644 index 00000000..b52f98b7 --- /dev/null +++ b/man/multi_gene_z_score.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/multi_gene_z_score.R +\name{multi_gene_z_score} +\alias{multi_gene_z_score} +\title{Combine multiple continuous variables by averaging Z scores} +\usage{ +multi_gene_z_score(cont_mat) +} +\arguments{ +\item{cont_mat}{A \code{matrix()} with spots as rows and 2 or more continuous +variables as columns.} +} +\value{ +A \code{numeric()} vector with one element per spot, summarizing the +multiple continuous variables. +} +\description{ +To summarize multiple features, each is normalized to represent a Z-score. +Scores are averaged to return a single vector. +} +\author{ +Nicholas J. Eagles +} +\concept{functions for summarizing expression of multiple continuous variables simultaneously} diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index 9624ce19..dd07b7fb 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -19,6 +19,7 @@ vis_gene( point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), ... ) } @@ -79,12 +80,12 @@ alpha blending already, which will make non-NA values pop up more and the NA values will show with a lighter color. This behavior is lost when \code{alpha} is set to a non-\code{NA} value.} -\item{...}{Passed to \link[base:paste]{paste0()} for making the title of the -plot following the \code{sampleid}.} - \item{multi_gene_method}{A \code{character(1)}: either "pca", "sparsity", or "z_score". This parameter controls how multiple continuous variables are combined for visualization, and only applies when \code{geneid} has length > 1.} + +\item{...}{Passed to \link[base:paste]{paste0()} for making the title of the +plot following the \code{sampleid}.} } \value{ A \link[ggplot2:ggplot]{ggplot2} object. From 9fafe26a07323a4d65b8ed2099d179316c295e20 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 14:17:43 -0500 Subject: [PATCH 058/259] Add a 'multi_gene_sparsity' function, corresponding to the 'sparsity' argument to the 'multi_gene_method' parameter --- R/multi_gene_sparsity.R | 17 +++++++++++++++++ R/vis_gene.R | 2 ++ man/multi_gene_z_score.Rd | 12 ++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 R/multi_gene_sparsity.R diff --git a/R/multi_gene_sparsity.R b/R/multi_gene_sparsity.R new file mode 100644 index 00000000..037254c0 --- /dev/null +++ b/R/multi_gene_sparsity.R @@ -0,0 +1,17 @@ +#' Combine multiple continuous variables by proportion of positive values +#' +#' To summarize multiple features, the proportion of features with positive +#' values for each spot is computed. +#' +#' @param cont_mat A \code{matrix()} with spots as rows and 2 or more continuous +#' variables as columns. +#' +#' @return A \code{numeric()} vector with one element per spot, summarizing the +#' multiple continuous variables. +#' +#' @author Nicholas J. Eagles +#' @import MatrixGenerics +#' @family functions for summarizing expression of multiple continuous variables simultaneously +multi_gene_z_score <- function(cont_mat) { + return(rowMeans(cont_mat > 0)) +} diff --git a/R/vis_gene.R b/R/vis_gene.R index bababaa4..24b1aacd 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -178,6 +178,8 @@ vis_gene <- } else { if (multi_gene_method == 'z_score') { d$COUNT = multi_gene_z_score(cont_matrix) + } else if (multi_gene_method == 'sparsity') { + d$COUNT = multi_gene_sparsity(cont_matrix) } } d$COUNT[d$COUNT <= minCount] <- NA diff --git a/man/multi_gene_z_score.Rd b/man/multi_gene_z_score.Rd index b52f98b7..211ade51 100644 --- a/man/multi_gene_z_score.Rd +++ b/man/multi_gene_z_score.Rd @@ -1,9 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/multi_gene_z_score.R +% Please edit documentation in R/multi_gene_sparsity.R, R/multi_gene_z_score.R \name{multi_gene_z_score} \alias{multi_gene_z_score} -\title{Combine multiple continuous variables by averaging Z scores} +\title{Combine multiple continuous variables by proportion of positive values} \usage{ +multi_gene_z_score(cont_mat) + multi_gene_z_score(cont_mat) } \arguments{ @@ -11,10 +13,16 @@ multi_gene_z_score(cont_mat) variables as columns.} } \value{ +A \code{numeric()} vector with one element per spot, summarizing the +multiple continuous variables. + A \code{numeric()} vector with one element per spot, summarizing the multiple continuous variables. } \description{ +To summarize multiple features, the proportion of features with positive +values for each spot is computed. + To summarize multiple features, each is normalized to represent a Z-score. Scores are averaged to return a single vector. } From 7e04a8411137e4eae2ecbf5e1988a751a7436f63 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 14:38:17 -0500 Subject: [PATCH 059/259] Add a 'multi_gene_pca' function, corresponding to the 'pca' argument to the 'multi_gene_method' parameter --- NAMESPACE | 1 + R/multi_gene_pca.R | 40 +++++++++++++++++++++++++++++++++++++++ R/vis_gene.R | 2 ++ man/multi_gene_z_score.Rd | 17 +++++++++++++++-- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 R/multi_gene_pca.R diff --git a/NAMESPACE b/NAMESPACE index 2504724c..d18236fa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -139,6 +139,7 @@ importFrom(stats,hclust) importFrom(stats,median) importFrom(stats,model.matrix) importFrom(stats,p.adjust) +importFrom(stats,prcomp) importFrom(stats,reshape) importFrom(stats,setNames) importFrom(tibble,tibble) diff --git a/R/multi_gene_pca.R b/R/multi_gene_pca.R new file mode 100644 index 00000000..403ff2b3 --- /dev/null +++ b/R/multi_gene_pca.R @@ -0,0 +1,40 @@ +#' Combine multiple continuous variables through PCA +#' +#' PCA is performed on \code{cont_mat}, the matrix of multiple continuous +#' features. The first PC is returned, representing the dominant spatial +#' signature of the feature set. Its direction is negated if necessary so that +#' the majority of coefficients across features are positive (when the features +#' are highly correlated, this encourages spots with higher values to +#' represent areas of higher expression of the features). +#' +#' @param cont_mat A \code{matrix()} with spots as rows and 2 or more continuous +#' variables as columns. +#' +#' @return A \code{numeric()} vector with one element per spot, summarizing the +#' multiple continuous variables. +#' +#' @author Nicholas J. Eagles +#' @importFrom stats prcomp +#' @family functions for summarizing expression of multiple continuous variables simultaneously +multi_gene_z_score <- function(cont_mat) { + pc_exp <- stats::prcomp(cont_mat, center = TRUE, scale = TRUE) + pc_vec <- pc_exp$x[, "PC1"] + + # Reverse the direction of PC1 if needed to improve visual interpretation + # + # Often, this function will be called with multiple genes as continuous + # variables, and in particular for genes with similar spatial patterns of + # expression. In this case, it's likely that each gene's coefficients to + # the first PC should tend to have the same sign. Next, the sign of each + # PC is arbitary, and we'd like plots to have positive values where + # expression is greater. If most genes have negative coefficients to the + # first PC, we reverse the sign of the coefficients to make visual + # intrepretation consistent. Note this step is neither beneficial nor + # harmful in other cases, where continuous features are not expected to be + # positively correlated + if (mean(pc_exp$rotation[, 1] > 0) < 0.5) { + pc_vec <- -1 * pc_vec + } + + return(pc_vec) +} diff --git a/R/vis_gene.R b/R/vis_gene.R index 24b1aacd..f38388b7 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -180,6 +180,8 @@ vis_gene <- d$COUNT = multi_gene_z_score(cont_matrix) } else if (multi_gene_method == 'sparsity') { d$COUNT = multi_gene_sparsity(cont_matrix) + } else { # must be 'pca' + d$COUNT = multi_gene_pca(cont_matrix) } } d$COUNT[d$COUNT <= minCount] <- NA diff --git a/man/multi_gene_z_score.Rd b/man/multi_gene_z_score.Rd index 211ade51..8c94a369 100644 --- a/man/multi_gene_z_score.Rd +++ b/man/multi_gene_z_score.Rd @@ -1,11 +1,14 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/multi_gene_sparsity.R, R/multi_gene_z_score.R +% Please edit documentation in R/multi_gene_pca.R, R/multi_gene_sparsity.R, +% R/multi_gene_z_score.R \name{multi_gene_z_score} \alias{multi_gene_z_score} -\title{Combine multiple continuous variables by proportion of positive values} +\title{Combine multiple continuous variables through PCA} \usage{ multi_gene_z_score(cont_mat) +multi_gene_z_score(cont_mat) + multi_gene_z_score(cont_mat) } \arguments{ @@ -16,10 +19,20 @@ variables as columns.} A \code{numeric()} vector with one element per spot, summarizing the multiple continuous variables. +A \code{numeric()} vector with one element per spot, summarizing the +multiple continuous variables. + A \code{numeric()} vector with one element per spot, summarizing the multiple continuous variables. } \description{ +PCA is performed on \code{cont_mat}, the matrix of multiple continuous +features. The first PC is returned, representing the dominant spatial +signature of the feature set. Its direction is negated if necessary so that +the majority of coefficients across features are positive (when the features +are highly correlated, this encourages spots with higher values to +represent areas of higher expression of the features). + To summarize multiple features, the proportion of features with positive values for each spot is computed. From 68cb97567341823d264f4bc014a712f5753fc0d9 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 14:50:45 -0500 Subject: [PATCH 060/259] Swap rows and columns, since the matrix is transposed relative to the original code --- R/multi_gene_z_score.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R index d0b5aef1..67ee4614 100644 --- a/R/multi_gene_z_score.R +++ b/R/multi_gene_z_score.R @@ -14,8 +14,8 @@ #' @family functions for summarizing expression of multiple continuous variables simultaneously multi_gene_z_score <- function(cont_mat) { # For each spot, average Z-scores across all features - cont_z <- (cont_mat - rowMeans(cont_mat)) / rowSds(cont_mat) - z_vec <- colMeans(cont_z, na.rm = TRUE) + cont_z <- (cont_mat - colMeans(cont_mat)) / colSds(cont_mat) + z_vec <- rowMeans(cont_z, na.rm = TRUE) return(z_vec) } From 4db9d32d28200f45a961b2a09ba741e8ab1040df Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 14:51:20 -0500 Subject: [PATCH 061/259] Fix plot and legend titles to work for single or multiple features --- R/vis_gene.R | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index f38388b7..09923ad6 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -174,8 +174,10 @@ vis_gene <- cont_matrix = cbind(cont_cols, gene_cols) if (ncol(cont_matrix) == 1) { + plot_title = paste(sampleid, geneid, ...) d$COUNT = cont_matrix[,1] } else { + plot_title = paste(sampleid, ...) if (multi_gene_method == 'z_score') { d$COUNT = multi_gene_z_score(cont_matrix) } else if (multi_gene_method == 'sparsity') { @@ -185,16 +187,13 @@ vis_gene <- } } d$COUNT[d$COUNT <= minCount] <- NA + p <- vis_gene_p( spe = spe_sub, d = d, sampleid = sampleid, spatial = spatial, - title = paste( - sampleid, - geneid, - ... - ), + title = plot_title, viridis = viridis, image_id = image_id, alpha = alpha, @@ -203,7 +202,7 @@ vis_gene <- auto_crop = auto_crop, na_color = na_color, legend_title = paste0( - if (!geneid %in% colnames(colData(spe_sub))) { + if (!any(geneid %in% colnames(colData(spe_sub)))) { paste0(assayname, "\n") } else { NULL From a0341da10b08d2db6d6224ccb4b55cda913a9c1c Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 15:04:15 -0500 Subject: [PATCH 062/259] Add an example for plotting multiple genes --- R/vis_gene.R | 11 +++++++++++ man/vis_gene.Rd | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/R/vis_gene.R b/R/vis_gene.R index 09923ad6..05336eb2 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -112,6 +112,17 @@ #' auto_crop = FALSE #' ) #' print(p5) +#' +#' ## Plot two genes at once using the Z-score combination method +#' p6 <- vis_gene( +#' spe = spe, +#' sampleid = "151507", +#' geneid = rownames(spe)[ +#' which(rowData(spe)$gene_name %in% c("MBP", "GFAP")) +#' ], +#' multi_gene_method = "z_score" +#' ) +#' print(p6) #' } vis_gene <- function(spe, diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index dd07b7fb..95cd7b03 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -174,6 +174,17 @@ if (enough_ram()) { auto_crop = FALSE ) print(p5) + + ## Plot two genes at once using the Z-score combination method + p6 <- vis_gene( + spe = spe, + sampleid = "151507", + geneid = rownames(spe)[ + which(rowData(spe)$gene_name \%in\% c("MBP", "GFAP")) + ], + multi_gene_method = "z_score" + ) + print(p6) } } \seealso{ From b7b0f02e356dfadcdc56776edc329159eb46e420 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 19 Feb 2024 15:11:27 -0500 Subject: [PATCH 063/259] Fix function names to not be duplicated --- R/multi_gene_pca.R | 2 +- R/multi_gene_sparsity.R | 2 +- man/multi_gene_pca.Rd | 33 +++++++++++++++++++++++++++++++++ man/multi_gene_sparsity.Rd | 29 +++++++++++++++++++++++++++++ man/multi_gene_z_score.Rd | 30 +++++++----------------------- 5 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 man/multi_gene_pca.Rd create mode 100644 man/multi_gene_sparsity.Rd diff --git a/R/multi_gene_pca.R b/R/multi_gene_pca.R index 403ff2b3..6a4521ba 100644 --- a/R/multi_gene_pca.R +++ b/R/multi_gene_pca.R @@ -16,7 +16,7 @@ #' @author Nicholas J. Eagles #' @importFrom stats prcomp #' @family functions for summarizing expression of multiple continuous variables simultaneously -multi_gene_z_score <- function(cont_mat) { +multi_gene_pca <- function(cont_mat) { pc_exp <- stats::prcomp(cont_mat, center = TRUE, scale = TRUE) pc_vec <- pc_exp$x[, "PC1"] diff --git a/R/multi_gene_sparsity.R b/R/multi_gene_sparsity.R index 037254c0..0ae47e19 100644 --- a/R/multi_gene_sparsity.R +++ b/R/multi_gene_sparsity.R @@ -12,6 +12,6 @@ #' @author Nicholas J. Eagles #' @import MatrixGenerics #' @family functions for summarizing expression of multiple continuous variables simultaneously -multi_gene_z_score <- function(cont_mat) { +multi_gene_sparsity <- function(cont_mat) { return(rowMeans(cont_mat > 0)) } diff --git a/man/multi_gene_pca.Rd b/man/multi_gene_pca.Rd new file mode 100644 index 00000000..364394c6 --- /dev/null +++ b/man/multi_gene_pca.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/multi_gene_pca.R +\name{multi_gene_pca} +\alias{multi_gene_pca} +\title{Combine multiple continuous variables through PCA} +\usage{ +multi_gene_pca(cont_mat) +} +\arguments{ +\item{cont_mat}{A \code{matrix()} with spots as rows and 2 or more continuous +variables as columns.} +} +\value{ +A \code{numeric()} vector with one element per spot, summarizing the +multiple continuous variables. +} +\description{ +PCA is performed on \code{cont_mat}, the matrix of multiple continuous +features. The first PC is returned, representing the dominant spatial +signature of the feature set. Its direction is negated if necessary so that +the majority of coefficients across features are positive (when the features +are highly correlated, this encourages spots with higher values to +represent areas of higher expression of the features). +} +\seealso{ +Other functions for summarizing expression of multiple continuous variables simultaneously: +\code{\link{multi_gene_sparsity}()}, +\code{\link{multi_gene_z_score}()} +} +\author{ +Nicholas J. Eagles +} +\concept{functions for summarizing expression of multiple continuous variables simultaneously} diff --git a/man/multi_gene_sparsity.Rd b/man/multi_gene_sparsity.Rd new file mode 100644 index 00000000..31ca2a0b --- /dev/null +++ b/man/multi_gene_sparsity.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/multi_gene_sparsity.R +\name{multi_gene_sparsity} +\alias{multi_gene_sparsity} +\title{Combine multiple continuous variables by proportion of positive values} +\usage{ +multi_gene_sparsity(cont_mat) +} +\arguments{ +\item{cont_mat}{A \code{matrix()} with spots as rows and 2 or more continuous +variables as columns.} +} +\value{ +A \code{numeric()} vector with one element per spot, summarizing the +multiple continuous variables. +} +\description{ +To summarize multiple features, the proportion of features with positive +values for each spot is computed. +} +\seealso{ +Other functions for summarizing expression of multiple continuous variables simultaneously: +\code{\link{multi_gene_pca}()}, +\code{\link{multi_gene_z_score}()} +} +\author{ +Nicholas J. Eagles +} +\concept{functions for summarizing expression of multiple continuous variables simultaneously} diff --git a/man/multi_gene_z_score.Rd b/man/multi_gene_z_score.Rd index 8c94a369..6869e53d 100644 --- a/man/multi_gene_z_score.Rd +++ b/man/multi_gene_z_score.Rd @@ -1,14 +1,9 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/multi_gene_pca.R, R/multi_gene_sparsity.R, -% R/multi_gene_z_score.R +% Please edit documentation in R/multi_gene_z_score.R \name{multi_gene_z_score} \alias{multi_gene_z_score} -\title{Combine multiple continuous variables through PCA} +\title{Combine multiple continuous variables by averaging Z scores} \usage{ -multi_gene_z_score(cont_mat) - -multi_gene_z_score(cont_mat) - multi_gene_z_score(cont_mat) } \arguments{ @@ -16,29 +11,18 @@ multi_gene_z_score(cont_mat) variables as columns.} } \value{ -A \code{numeric()} vector with one element per spot, summarizing the -multiple continuous variables. - -A \code{numeric()} vector with one element per spot, summarizing the -multiple continuous variables. - A \code{numeric()} vector with one element per spot, summarizing the multiple continuous variables. } \description{ -PCA is performed on \code{cont_mat}, the matrix of multiple continuous -features. The first PC is returned, representing the dominant spatial -signature of the feature set. Its direction is negated if necessary so that -the majority of coefficients across features are positive (when the features -are highly correlated, this encourages spots with higher values to -represent areas of higher expression of the features). - -To summarize multiple features, the proportion of features with positive -values for each spot is computed. - To summarize multiple features, each is normalized to represent a Z-score. Scores are averaged to return a single vector. } +\seealso{ +Other functions for summarizing expression of multiple continuous variables simultaneously: +\code{\link{multi_gene_pca}()}, +\code{\link{multi_gene_sparsity}()} +} \author{ Nicholas J. Eagles } From f3b5c65addb6a377f0a9c823c3a4f996f479a69d Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 20 Feb 2024 10:20:27 -0500 Subject: [PATCH 064/259] Add missing dependencies --- DESCRIPTION | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index e8ae3f82..c9572a82 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -76,7 +76,9 @@ Imports: scuttle, edgeR, limma, - statmod + statmod, + MatrixGenerics, + rlang RoxygenNote: 7.3.1 Roxygen: list(markdown = TRUE) URL: https://github.com/LieberInstitute/spatialLIBD From 5b523a2a27a54d6f39c1838e44c4a2ab5979eee3 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 21 Feb 2024 12:09:16 -0500 Subject: [PATCH 065/259] Add a vignette for plotting multiple continuous features simultaneously --- vignettes/multi_gene_plots.Rmd | 173 +++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 vignettes/multi_gene_plots.Rmd diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd new file mode 100644 index 00000000..15abaec6 --- /dev/null +++ b/vignettes/multi_gene_plots.Rmd @@ -0,0 +1,173 @@ +--- +title: "Guide to Multi-Gene Plots" +author: + - name: Nicholas J. Eagles + affiliation: + - Lieber Institute for Brain Development + email: nickeagles77@gmail.com +output: + BiocStyle::html_document: + self_contained: yes + toc: true + toc_float: true + toc_depth: 2 + code_folding: show +date: "`r doc_date()`" +package: "`r pkg_ver('spatialLIBD')`" +vignette: > + %\VignetteIndexEntry{Guide to Multi-Gene Plots} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r vignetteSetup, echo=FALSE, message=FALSE, warning = FALSE} +## For links +library("BiocStyle") + +## Track time spent on making the vignette +startTime <- Sys.time() + +## Bib setup +library("RefManageR") + +## Write bibliography information +bib <- c( + R = citation(), + knitr = citation("knitr")[3], + RColorBrewer = citation("RColorBrewer")[1], + RefManageR = citation("RefManageR")[1], + rmarkdown = citation("rmarkdown")[1], + sessioninfo = citation("sessioninfo")[1], + SpatialExperiment = citation("SpatialExperiment")[1], + spatialLIBD = citation("spatialLIBD")[1] +) +``` + +# Plotting One Gene + +A typical use of [`vis_gene`](http://research.libd.org/spatialLIBD/reference/vis_gene.html) involves +plotting the spatial distribution of a single gene or continuous variable of interest. + +```{r "setup", message = FALSE, warning = FALSE} +library("spatialLIBD") +spe = fetch_data(type = "spatialDLPFC_Visium_example_subset") + +white_matter_genes = c("GFAP", "AQP4", "MBP", "PLP1") +white_matter_genes = rowData(spe)$gene_search[ + rowData(spe)$gene_name %in% white_matter_genes +] +``` + +```{r "single_gene"} +vis_gene(spe, geneid = white_matter_genes[1]) +``` + +# Plotting Multiple Genes + +However, the `geneid` parameter to `vis_gene` may also take a vector of genes or continuous +variables in `colData(spe)`. In this way, the expression of multiple genes can be summarized +into a single value for each spot, displayed just as a single gene for `geneid` would be. +`spatialLIBD` provides three methods for merging the information from multiple continuous +variables, which may be specified through the `multi_gene_method` parameter to `vis_gene`. + +## Averaging Z-scores + +The default is `multi_gene_method = "z_score"`. Essentially, the expression for each gene is +normalized to be a Z-score. If a particular spot has a value of `1` for a particular gene, +this would indicate that spot has expression one standard deviation above the mean expression +across all spots for that gene. Next, for each spot, Z-scores are averaged across genes. +Compared to simply averaging raw gene expression across genes, the `"z_score"` method +is insensitive to absolute expression levels (highly expressed genes don't dominate plots), +and instead focuses on how each gene varies spatially, weighting each gene equally. + +Let's plot all four white matter genes using this method. + +```{r "single_gene"} +vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "z_score") +``` + +## Summarizing with PCA + +Another option is `multi_gene_method = "pca"`. A matrix is formed, where genes or continuous +features are columns, and spots are rows. PCA is performed, and the first principal component +is plotted spatially. The idea is that the first PC captures the dominant spatial signature +of the feature set. Next, its direction is reversed if the majority of coefficients (from the +"rotation matrix") across features are negative. When the features are genes whose expression +is highly correlated (like our white-matter-gene example!), this optional reversal encourages +higher values in the plot to represent areas of higher expression of the features. For our case, +this leads to the intuitive result that "expression" is higher in white matter for white-matter +genes, which is not otherwise guaranteed (the "sign" of PCs is arbitary)! + +```{r "single_gene"} +vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "pca") +``` + +## Plotting Sparsity of Expression + +This final option is `multi_gene_method = "sparsity"`. For each spot, the proportion of features +with positive expression is plotted. This method is typically only meaningful when features +are raw gene counts that are expected to be quite sparse (have zero counts) at certain regions +of the tissue and not others. It also performs better with a larger number of genes; with our +example of four white-matter genes, the proportion may only hold values of 0, 0.25, 0.5, 0.75, +and 1, which is not visually informative. + +The white-matter example is thus poor due to lack of sparsity and low number of genes: + +```{r "single_gene"} +vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "sparsity") +``` + +Code for creating the vignette + +```{r createVignette, eval=FALSE} +## Create the vignette +library("rmarkdown") +system.time(render("multi_gene_plots.Rmd")) + +## Extract the R code +library("knitr") +knit("multi_gene_plots.Rmd", tangle = TRUE) +``` + + +Date the vignette was generated. + +```{r reproduce1, echo=FALSE} +## Date the vignette was generated +Sys.time() +``` + +Wallclock time spent generating the vignette. + +```{r reproduce2, echo=FALSE} +## Processing time in seconds +totalTime <- diff(c(startTime, Sys.time())) +round(totalTime, digits = 3) +``` + +`R` session information. + +```{r reproduce3, echo=FALSE} +## Session info +library("sessioninfo") +options(width = 120) +session_info() +``` + +# Bibliography + +This vignette was generated using `r Biocpkg('BiocStyle')` `r Citep(bib[['BiocStyle']])`, `r CRANpkg('knitr')` `r Citep(bib[['knitr']])` and `r CRANpkg('rmarkdown')` `r Citep(bib[['rmarkdown']])` running behind the scenes. + +Citations made with `r CRANpkg('RefManageR')` `r Citep(bib[['RefManageR']])`. + +```{r vignetteBiblio, results = 'asis', echo = FALSE, warning = FALSE, message = FALSE} +## Print bibliography +PrintBibliography(bib, .opts = list(hyperlink = "to.doc", style = "html")) +``` From c7c580575b96b6ac456ec72b516d99dd1ac4e8be Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 21 Feb 2024 12:11:12 -0500 Subject: [PATCH 066/259] Style code --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 +-- R/annotate_registered_clusters.R | 16 ++-- R/check_sce.R | 69 ++++++++-------- R/check_spe.R | 15 ++-- R/fetch_data.R | 41 +++++----- R/frame_limits.R | 21 ++--- R/gene_set_enrichment.R | 11 +-- R/gene_set_enrichment_plot.R | 23 +++--- R/geom_spatial.R | 17 ++-- R/img_edit.R | 37 ++++----- R/img_update.R | 13 +-- R/img_update_all.R | 11 +-- R/layer_boxplot.R | 27 ++++--- R/layer_matrix_plot.R | 27 ++++--- R/layer_stat_cor.R | 11 +-- R/layer_stat_cor_plot.R | 11 +-- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 ++--- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 ++- R/registration_stats_anova.R | 17 ++-- R/registration_stats_enrichment.R | 15 ++-- R/registration_stats_pairwise.R | 15 ++-- R/registration_wrapper.R | 19 +++-- R/run_app.R | 97 ++++++++++++----------- R/sig_genes_extract.R | 11 ++- R/sig_genes_extract_all.R | 7 +- R/vis_clus.R | 50 ++++++------ R/vis_clus_p.R | 25 +++--- R/vis_gene.R | 70 ++++++++-------- R/vis_gene_p.R | 35 ++++---- R/vis_grid_clus.R | 33 ++++---- R/vis_grid_gene.R | 37 ++++----- data-raw/create_spatialDLPFC_spe_subset.R | 1 - vignettes/multi_gene_plots.Rmd | 6 +- 36 files changed, 435 insertions(+), 417 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index de4f5fee..dbe49f86 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,8 +29,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function(spe, - visium_analysis) { +add10xVisiumAnalysis <- function( + spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index bfdddbe5..e7b09e5c 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,12 +43,13 @@ #' )) #' } add_images <- - function(spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function( + spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index c2a9ec43..13e1d5ab 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,9 +48,10 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function(cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function( + cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -86,10 +87,11 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function(remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function( + remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 0d17423b..1d625342 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,40 +24,41 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function(sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function( + sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index 47de3c0a..d0344daa 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,13 +25,14 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function(spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function( + spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index cc715e4a..3426ae6d 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,27 +84,26 @@ #' #> 172.28 MB #' } fetch_data <- - function( - type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function(type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index b22b5c8a..320cc643 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,16 +37,17 @@ #' } #' frame_limits <- - function(spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function( + spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index 1accea28..e6b6a63d 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,11 +58,12 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function(gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function( + gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index 4ccbfcbc..c155e672 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,17 +84,18 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function(enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function( + enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 64f00cc3..965db758 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,14 +58,15 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function(mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function( + mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index ec6fae90..93aceee3 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,24 +58,25 @@ #' plot(x) #' } img_edit <- - function(spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function( + spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index db6dfcb1..fdfe5b83 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,12 +41,13 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function(spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 31c368c9..314b9b0d 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,11 +22,12 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function(spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 345d5499..6a671a5e 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,19 +114,20 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function(i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function( + i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index f1530fb1..4a44fd18 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,19 +55,20 @@ #' cex = 2 #' ) layer_matrix_plot <- - function(matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function( + matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index 0ccf0bf2..f484c912 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,11 +49,12 @@ #' top_n = 10 #' )) layer_stat_cor <- - function(stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function( + stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index c0f4e924..0d2653b8 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,11 +72,12 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function(cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function( + cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index ef76f1d0..70bc49ac 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,9 +24,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 501a744d..d9f31fc2 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,16 +44,17 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 3f36260c..6921dbb9 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,9 +24,10 @@ #' head(registration_mod) #' registration_model <- - function(sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function( + sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 5f3c5dd2..2d859e4e 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,13 +51,12 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index c899459d..d1d0b135 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,14 +50,15 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index d186547e..cd3ee182 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,14 +34,13 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index afb9771a..09bb3ff9 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,14 +32,13 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function( - sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 49896d78..38a1c297 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,16 +50,15 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index b7beae48..93701444 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -186,54 +186,55 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function(spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - ...) { +run_app <- function( + spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index b21902c1..fac5f65b 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,12 +59,11 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index d2c3c01f..0d68b880 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,10 +27,9 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index d3f00dc1..54fca688 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -92,32 +92,32 @@ #' ... = " LIBD Layers" #' ) #' print(p4) -#' #' } -vis_clus <- function(spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { +vis_clus <- function( + spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index a91ce369..d2b37cec 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,18 +42,19 @@ #' rm(spe_sub) #' } vis_clus_p <- - function(spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function( + spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 05336eb2..cd7c75cc 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -112,7 +112,7 @@ #' auto_crop = FALSE #' ) #' print(p5) -#' +#' #' ## Plot two genes at once using the Z-score combination method #' p6 <- vis_gene( #' spe = spe, @@ -125,76 +125,78 @@ #' print(p6) #' } vis_gene <- - function(spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - ...) { + function( + spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + ...) { spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) - multi_gene_method = rlang::arg_match(multi_gene_method) + multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify legitimacy of names in geneid - geneid_is_valid = (geneid %in% rowData(spe_sub)$gene_search) | + geneid_is_valid <- (geneid %in% rowData(spe_sub)$gene_search) | (geneid %in% rownames(spe_sub)) | (geneid %in% colnames(colData(spe_sub))) if (any(!geneid_is_valid)) { stop( "Could not find the 'geneid'(s) ", - paste(geneid[!geneid_is_valid], collapse = ', '), + paste(geneid[!geneid_is_valid], collapse = ", "), call. = FALSE ) } # Grab any continuous colData columns - cont_cols = as.matrix( + cont_cols <- as.matrix( colData(spe_sub)[ - , geneid[geneid %in% colnames(colData(spe_sub))], drop = FALSE + , geneid[geneid %in% colnames(colData(spe_sub))], + drop = FALSE ] ) # Get the integer indices of each gene in the SpatialExperiment, since we # aren't guaranteed that rownames are gene names - remaining_geneid = geneid[!(geneid %in% colnames(colData(spe_sub)))] - valid_gene_indices = unique( + remaining_geneid <- geneid[!(geneid %in% colnames(colData(spe_sub)))] + valid_gene_indices <- unique( c( match(remaining_geneid, rowData(spe_sub)$gene_search), match(remaining_geneid, rownames(spe_sub)) ) ) - valid_gene_indices = valid_gene_indices[!is.na(valid_gene_indices)] + valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] # Grab any genes - gene_cols = t( + gene_cols <- t( as.matrix(assays(spe_sub[valid_gene_indices, ])[[assayname]]) ) # Combine into one matrix where rows are genes and columns are continuous # features - cont_matrix = cbind(cont_cols, gene_cols) + cont_matrix <- cbind(cont_cols, gene_cols) if (ncol(cont_matrix) == 1) { - plot_title = paste(sampleid, geneid, ...) - d$COUNT = cont_matrix[,1] + plot_title <- paste(sampleid, geneid, ...) + d$COUNT <- cont_matrix[, 1] } else { - plot_title = paste(sampleid, ...) - if (multi_gene_method == 'z_score') { - d$COUNT = multi_gene_z_score(cont_matrix) - } else if (multi_gene_method == 'sparsity') { - d$COUNT = multi_gene_sparsity(cont_matrix) + plot_title <- paste(sampleid, ...) + if (multi_gene_method == "z_score") { + d$COUNT <- multi_gene_z_score(cont_matrix) + } else if (multi_gene_method == "sparsity") { + d$COUNT <- multi_gene_sparsity(cont_matrix) } else { # must be 'pca' - d$COUNT = multi_gene_pca(cont_matrix) + d$COUNT <- multi_gene_pca(cont_matrix) } } d$COUNT[d$COUNT <= minCount] <- NA diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index e659d477..9bc3dc0a 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,23 +48,24 @@ #' rm(spe_sub) #' } vis_gene_p <- - function(spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function( + spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 40ead6b3..8c81ace6 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,22 +47,23 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function(spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index e21b5bf1..2504cce5 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,24 +35,25 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function(spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/data-raw/create_spatialDLPFC_spe_subset.R b/data-raw/create_spatialDLPFC_spe_subset.R index ca5e83ab..74cf9d21 100644 --- a/data-raw/create_spatialDLPFC_spe_subset.R +++ b/data-raw/create_spatialDLPFC_spe_subset.R @@ -241,4 +241,3 @@ session_info() # [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library # # ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index 15abaec6..f62aec95 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -57,10 +57,10 @@ plotting the spatial distribution of a single gene or continuous variable of int ```{r "setup", message = FALSE, warning = FALSE} library("spatialLIBD") -spe = fetch_data(type = "spatialDLPFC_Visium_example_subset") +spe <- fetch_data(type = "spatialDLPFC_Visium_example_subset") -white_matter_genes = c("GFAP", "AQP4", "MBP", "PLP1") -white_matter_genes = rowData(spe)$gene_search[ +white_matter_genes <- c("GFAP", "AQP4", "MBP", "PLP1") +white_matter_genes <- rowData(spe)$gene_search[ rowData(spe)$gene_name %in% white_matter_genes ] ``` From abc608749ad68645fd20e5a8063b24f597f05764 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 21 Feb 2024 12:30:59 -0500 Subject: [PATCH 067/259] Add checks for legitimacy of 'assayname' and 'sampleid' for 'vis_gene' and 'vis_clus' to give more informative errors --- R/vis_clus.R | 62 +++++++++++++++++++++++++++++++--------------------- R/vis_gene.R | 52 ++++++++++++++++++++++++++++--------------- 2 files changed, 71 insertions(+), 43 deletions(-) diff --git a/R/vis_clus.R b/R/vis_clus.R index 54fca688..5e1cfc1a 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -93,31 +93,43 @@ #' ) #' print(p4) #' } -vis_clus <- function( - spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { +vis_clus <- function(spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { + # Verify existence and legitimacy of 'sampleid' + if ( + !("sample_id" %in% colnames(colData(spe))) || + !(sampleid %in% spe$sample_id) + ) { + stop( + paste( + "'spe$sample_id' must exist and contain the ID", sampleid + ), + call. = FALSE + ) + } + spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_gene.R b/R/vis_gene.R index cd7c75cc..d0ab9114 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -125,27 +125,43 @@ #' print(p6) #' } vis_gene <- - function( - spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - ...) { + function(spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + ...) { + multi_gene_method <- rlang::arg_match(multi_gene_method) + # Verify existence and legitimacy of 'sampleid' + if ( + !("sample_id" %in% colnames(colData(spe))) || + !(sampleid %in% spe$sample_id) + ) { + stop( + paste( + "'spe$sample_id' must exist and contain the ID", sampleid + ), + call. = FALSE + ) + } + + # Verify 'assayname' + if (!(assayname %in% names(assays(spe)))) { + stop(sprintf("'%s' is not an assay in 'spe'", assayname), call. = FALSE) + } + spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) - multi_gene_method <- rlang::arg_match(multi_gene_method) - # Verify legitimacy of names in geneid geneid_is_valid <- (geneid %in% rowData(spe_sub)$gene_search) | (geneid %in% rownames(spe_sub)) | From ff49a2eaa1eb5477c5df8e46cf1652cdd8ec7244 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 21 Feb 2024 12:32:19 -0500 Subject: [PATCH 068/259] Fix duplicate vignette chunk labels --- vignettes/multi_gene_plots.Rmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index f62aec95..9c2ff4ac 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -89,7 +89,7 @@ and instead focuses on how each gene varies spatially, weighting each gene equal Let's plot all four white matter genes using this method. -```{r "single_gene"} +```{r "multi_gene_z"} vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "z_score") ``` @@ -105,7 +105,7 @@ higher values in the plot to represent areas of higher expression of the feature this leads to the intuitive result that "expression" is higher in white matter for white-matter genes, which is not otherwise guaranteed (the "sign" of PCs is arbitary)! -```{r "single_gene"} +```{r "multi_gene_pca"} vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "pca") ``` @@ -120,7 +120,7 @@ and 1, which is not visually informative. The white-matter example is thus poor due to lack of sparsity and low number of genes: -```{r "single_gene"} +```{r "multi_gene_sparsity"} vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "sparsity") ``` From f477dd08001483035afc46db104f51a412c70583 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 13:21:16 -0400 Subject: [PATCH 069/259] Make multi-gene plotting functions internal (in terms of documentation) --- R/multi_gene_pca.R | 1 + R/multi_gene_sparsity.R | 1 + R/multi_gene_z_score.R | 1 + man/multi_gene_pca.Rd | 1 + man/multi_gene_sparsity.Rd | 1 + man/multi_gene_z_score.Rd | 1 + man/vis_clus.Rd | 1 - 7 files changed, 6 insertions(+), 1 deletion(-) diff --git a/R/multi_gene_pca.R b/R/multi_gene_pca.R index 6a4521ba..dedd496c 100644 --- a/R/multi_gene_pca.R +++ b/R/multi_gene_pca.R @@ -16,6 +16,7 @@ #' @author Nicholas J. Eagles #' @importFrom stats prcomp #' @family functions for summarizing expression of multiple continuous variables simultaneously +#' @keywords internal multi_gene_pca <- function(cont_mat) { pc_exp <- stats::prcomp(cont_mat, center = TRUE, scale = TRUE) pc_vec <- pc_exp$x[, "PC1"] diff --git a/R/multi_gene_sparsity.R b/R/multi_gene_sparsity.R index 0ae47e19..45e3d4ce 100644 --- a/R/multi_gene_sparsity.R +++ b/R/multi_gene_sparsity.R @@ -12,6 +12,7 @@ #' @author Nicholas J. Eagles #' @import MatrixGenerics #' @family functions for summarizing expression of multiple continuous variables simultaneously +#' @keywords internal multi_gene_sparsity <- function(cont_mat) { return(rowMeans(cont_mat > 0)) } diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R index 67ee4614..38e8e33f 100644 --- a/R/multi_gene_z_score.R +++ b/R/multi_gene_z_score.R @@ -12,6 +12,7 @@ #' @author Nicholas J. Eagles #' @import MatrixGenerics #' @family functions for summarizing expression of multiple continuous variables simultaneously +#' @keywords internal multi_gene_z_score <- function(cont_mat) { # For each spot, average Z-scores across all features cont_z <- (cont_mat - colMeans(cont_mat)) / colSds(cont_mat) diff --git a/man/multi_gene_pca.Rd b/man/multi_gene_pca.Rd index 364394c6..c6845d8a 100644 --- a/man/multi_gene_pca.Rd +++ b/man/multi_gene_pca.Rd @@ -31,3 +31,4 @@ Other functions for summarizing expression of multiple continuous variables simu Nicholas J. Eagles } \concept{functions for summarizing expression of multiple continuous variables simultaneously} +\keyword{internal} diff --git a/man/multi_gene_sparsity.Rd b/man/multi_gene_sparsity.Rd index 31ca2a0b..8a564aa9 100644 --- a/man/multi_gene_sparsity.Rd +++ b/man/multi_gene_sparsity.Rd @@ -27,3 +27,4 @@ Other functions for summarizing expression of multiple continuous variables simu Nicholas J. Eagles } \concept{functions for summarizing expression of multiple continuous variables simultaneously} +\keyword{internal} diff --git a/man/multi_gene_z_score.Rd b/man/multi_gene_z_score.Rd index 6869e53d..1d4d12cb 100644 --- a/man/multi_gene_z_score.Rd +++ b/man/multi_gene_z_score.Rd @@ -27,3 +27,4 @@ Other functions for summarizing expression of multiple continuous variables simu Nicholas J. Eagles } \concept{functions for summarizing expression of multiple continuous variables simultaneously} +\keyword{internal} diff --git a/man/vis_clus.Rd b/man/vis_clus.Rd index ebb948c2..3354bfb4 100644 --- a/man/vis_clus.Rd +++ b/man/vis_clus.Rd @@ -127,7 +127,6 @@ if (enough_ram()) { ... = " LIBD Layers" ) print(p4) - } } \seealso{ From e38a96016a24f66422021763c0eb319faf602a55 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 13:24:29 -0400 Subject: [PATCH 070/259] Cite MatrixGenerics (not citing 'stats', since it says to cite R, which we do already) --- vignettes/multi_gene_plots.Rmd | 1 + 1 file changed, 1 insertion(+) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index 9c2ff4ac..4b1d5ae0 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -40,6 +40,7 @@ library("RefManageR") ## Write bibliography information bib <- c( R = citation(), + MatrixGenerics = citation("MatrixGenerics")[1], knitr = citation("knitr")[3], RColorBrewer = citation("RColorBrewer")[1], RefManageR = citation("RefManageR")[1], From c4c5665976f471429bcc725ea9e62ff4f9cb4c73 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 13:44:12 -0400 Subject: [PATCH 071/259] Add a brief intro to the multi-gene vignette --- vignettes/multi_gene_plots.Rmd | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index 4b1d5ae0..1cf8cdba 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -51,6 +51,15 @@ bib <- c( ) ``` +One of the goals of `spatialLIBD` is to provide options for visualizing Visium data. In +particular, `vis_gene()` and `vis_clus()` allow plotting of individual continuous or +discrete quantities belonging to each Visium spot, in a spatially accurate manner and +optionally atop histology images. + +This vignette explores a more complex capability of `vis_gene()`: to visualize a summary +metric of several continuous variables simultaneously. We'll start with a basic one-gene +use case for `vis_gene()` before moving to more advanced cases. + # Plotting One Gene A typical use of [`vis_gene`](http://research.libd.org/spatialLIBD/reference/vis_gene.html) involves From ecca74649b530439bcfba1c50d0fcc7449eafb7b Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 13:48:23 -0400 Subject: [PATCH 072/259] Add back a deleted header --- vignettes/multi_gene_plots.Rmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index 1cf8cdba..603379ec 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -134,6 +134,8 @@ The white-matter example is thus poor due to lack of sparsity and low number of vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "sparsity") ``` +# Reproducibility + Code for creating the vignette ```{r createVignette, eval=FALSE} From 21191c0d696f77816a8b5d3589b5eb32681305dd Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 13:52:13 -0400 Subject: [PATCH 073/259] Cite Tran et al for choice of white matter genes --- vignettes/multi_gene_plots.Rmd | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index 603379ec..b8425459 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -47,7 +47,15 @@ bib <- c( rmarkdown = citation("rmarkdown")[1], sessioninfo = citation("sessioninfo")[1], SpatialExperiment = citation("SpatialExperiment")[1], - spatialLIBD = citation("spatialLIBD")[1] + spatialLIBD = citation("spatialLIBD")[1], + tran2021 = RefManageR::BibEntry( + bibtype = "Article", + key = "tran2021", + author = "Tran, Matthew N. and Maynard, Kristen R. and Spangler, Abby and Huuki, Louise A. and Montgomery, Kelsey D. and Sadashivaiah, Vijay and Tippani, Madhavi and Barry, Brianna K. and Hancock, Dana B. and Hicks, Stephanie C. and Kleinman, Joel E. and Hyde, Thomas M. and Collado-Torres, Leonardo and Jaffe, Andrew E. and Martinowich, Keri", + title = "Single-nucleus transcriptome analysis reveals cell-type-specific molecular signatures across reward circuitry in the human brain", + year = 2021, doi = "10.1016/j.neuron.2021.09.001", + journal = "Neuron" + ) ) ``` @@ -63,7 +71,8 @@ use case for `vis_gene()` before moving to more advanced cases. # Plotting One Gene A typical use of [`vis_gene`](http://research.libd.org/spatialLIBD/reference/vis_gene.html) involves -plotting the spatial distribution of a single gene or continuous variable of interest. +plotting the spatial distribution of a single gene or continuous variable of interest. We'll +first define several genes known to be markers for white matter `r Citep(bib[['tran2021']])`. ```{r "setup", message = FALSE, warning = FALSE} library("spatialLIBD") @@ -75,6 +84,8 @@ white_matter_genes <- rowData(spe)$gene_search[ ] ``` +Next, we'll plot just the expression of *GFAP*. + ```{r "single_gene"} vis_gene(spe, geneid = white_matter_genes[1]) ``` From 5b334a0d57853b0fa3928f07c181400e69608255 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 13:59:03 -0400 Subject: [PATCH 074/259] Add multi-gene-plotting examples to the 'vis_gene' examples --- R/vis_gene.R | 33 +++++++++++++++++++++++++++++---- man/vis_gene.Rd | 33 +++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index d0ab9114..98180900 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -113,16 +113,41 @@ #' ) #' print(p5) #' -#' ## Plot two genes at once using the Z-score combination method +#' # Define several markers for white matter +#' white_matter_genes <- c( +#' "ENSG00000197971", "ENSG00000131095", "ENSG00000123560", +#' "ENSG00000171885" +#' ) +#' +#' ## Plot all white matter markers at once using the Z-score combination +#' ## method #' p6 <- vis_gene( #' spe = spe, #' sampleid = "151507", -#' geneid = rownames(spe)[ -#' which(rowData(spe)$gene_name %in% c("MBP", "GFAP")) -#' ], +#' geneid = white_matter_genes, #' multi_gene_method = "z_score" #' ) #' print(p6) +#' +#' ## Plot all white matter markers at once using the sparsity combination +#' ## method +#' p7 <- vis_gene( +#' spe = spe, +#' sampleid = "151507", +#' geneid = white_matter_genes, +#' multi_gene_method = "sparsity" +#' ) +#' print(p7) +#' +#' ## Plot all white matter markers at once using the PCA combination +#' ## method +#' p8 <- vis_gene( +#' spe = spe, +#' sampleid = "151507", +#' geneid = white_matter_genes, +#' multi_gene_method = "pca" +#' ) +#' print(p8) #' } vis_gene <- function(spe, diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index 95cd7b03..d7943c43 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -175,16 +175,41 @@ if (enough_ram()) { ) print(p5) - ## Plot two genes at once using the Z-score combination method + # Define several markers for white matter + white_matter_genes <- c( + "ENSG00000197971", "ENSG00000131095", "ENSG00000123560", + "ENSG00000171885" + ) + + ## Plot all white matter markers at once using the Z-score combination + ## method p6 <- vis_gene( spe = spe, sampleid = "151507", - geneid = rownames(spe)[ - which(rowData(spe)$gene_name \%in\% c("MBP", "GFAP")) - ], + geneid = white_matter_genes, multi_gene_method = "z_score" ) print(p6) + + ## Plot all white matter markers at once using the sparsity combination + ## method + p7 <- vis_gene( + spe = spe, + sampleid = "151507", + geneid = white_matter_genes, + multi_gene_method = "sparsity" + ) + print(p7) + + ## Plot all white matter markers at once using the PCA combination + ## method + p8 <- vis_gene( + spe = spe, + sampleid = "151507", + geneid = white_matter_genes, + multi_gene_method = "pca" + ) + print(p8) } } \seealso{ From 900eb817ee5ef2fd5a58930fdbd46b2a1c1f42cb Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 14:19:07 -0400 Subject: [PATCH 075/259] Fix legend title for multi-gene plots --- R/vis_gene.R | 55 +++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index 98180900..49dec567 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -118,7 +118,7 @@ #' "ENSG00000197971", "ENSG00000131095", "ENSG00000123560", #' "ENSG00000171885" #' ) -#' +#' #' ## Plot all white matter markers at once using the Z-score combination #' ## method #' p6 <- vis_gene( @@ -128,7 +128,7 @@ #' multi_gene_method = "z_score" #' ) #' print(p6) -#' +#' #' ## Plot all white matter markers at once using the sparsity combination #' ## method #' p7 <- vis_gene( @@ -138,7 +138,7 @@ #' multi_gene_method = "sparsity" #' ) #' print(p7) -#' +#' #' ## Plot all white matter markers at once using the PCA combination #' ## method #' p8 <- vis_gene( @@ -150,21 +150,22 @@ #' print(p8) #' } vis_gene <- - function(spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - ...) { + function( + spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' if ( @@ -227,17 +228,26 @@ vis_gene <- # features cont_matrix <- cbind(cont_cols, gene_cols) + # Determine plot and legend titles if (ncol(cont_matrix) == 1) { plot_title <- paste(sampleid, geneid, ...) d$COUNT <- cont_matrix[, 1] + if (!(geneid %in% colnames(colData(spe_sub)))) { + legend_title <- sprintf("%s\n min > %s", assayname, minCount) + } else { + legend_title <- sprintf("min > %s", minCount) + } } else { plot_title <- paste(sampleid, ...) if (multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) + legend_title <- paste("Z score\n min > ", minCount) } else if (multi_gene_method == "sparsity") { d$COUNT <- multi_gene_sparsity(cont_matrix) + legend_title <- paste("Prop. nonzero\n min > ", minCount) } else { # must be 'pca' d$COUNT <- multi_gene_pca(cont_matrix) + legend_title <- paste("PC1\n min > ", minCount) } } d$COUNT[d$COUNT <= minCount] <- NA @@ -255,14 +265,7 @@ vis_gene <- point_size = point_size, auto_crop = auto_crop, na_color = na_color, - legend_title = paste0( - if (!any(geneid %in% colnames(colData(spe_sub)))) { - paste0(assayname, "\n") - } else { - NULL - }, - " min > ", minCount - ) + legend_title = legend_title ) return(p) } From 079a0f84e0f1026f84c085dfbf614a589914a653 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 14:19:14 -0400 Subject: [PATCH 076/259] Style code --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 ++--- R/annotate_registered_clusters.R | 16 +++-- R/check_sce.R | 69 +++++++++++----------- R/check_spe.R | 15 +++-- R/fetch_data.R | 41 ++++++------- R/frame_limits.R | 21 ++++--- R/gene_set_enrichment.R | 11 ++-- R/gene_set_enrichment_plot.R | 23 ++++---- R/geom_spatial.R | 17 +++--- R/img_edit.R | 37 ++++++------ R/img_update.R | 13 ++--- R/img_update_all.R | 11 ++-- R/layer_boxplot.R | 27 +++++---- R/layer_matrix_plot.R | 27 +++++---- R/layer_stat_cor.R | 11 ++-- R/layer_stat_cor_plot.R | 11 ++-- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 ++++--- R/registration_model.R | 7 +-- R/registration_pseudobulk.R | 13 +++-- R/registration_stats_anova.R | 17 +++--- R/registration_stats_enrichment.R | 15 ++--- R/registration_stats_pairwise.R | 15 ++--- R/registration_wrapper.R | 19 +++--- R/run_app.R | 97 +++++++++++++++---------------- R/sig_genes_extract.R | 11 ++-- R/sig_genes_extract_all.R | 7 ++- R/vis_clus.R | 49 ++++++++-------- R/vis_clus_p.R | 25 ++++---- R/vis_gene_p.R | 35 ++++++----- R/vis_grid_clus.R | 33 +++++------ R/vis_grid_gene.R | 37 ++++++------ 33 files changed, 379 insertions(+), 395 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index dbe49f86..de4f5fee 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,9 +29,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function( - spe, - visium_analysis) { +add10xVisiumAnalysis <- function(spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index e7b09e5c..bfdddbe5 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,13 +43,12 @@ #' )) #' } add_images <- - function( - spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function(spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index 13e1d5ab..c2a9ec43 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,10 +48,9 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function( - cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function(cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -87,11 +86,10 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function( - remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function(remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 1d625342..0d17423b 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,41 +24,40 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function( - sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function(sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index d0344daa..47de3c0a 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,14 +25,13 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function( - spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function(spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index 3426ae6d..cc715e4a 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,26 +84,27 @@ #' #> 172.28 MB #' } fetch_data <- - function(type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function( + type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index 320cc643..b22b5c8a 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,17 +37,16 @@ #' } #' frame_limits <- - function( - spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function(spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index e6b6a63d..1accea28 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,12 +58,11 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function( - gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function(gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index c155e672..4ccbfcbc 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,18 +84,17 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function( - enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function(enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 965db758..64f00cc3 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,15 +58,14 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function( - mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function(mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index 93aceee3..ec6fae90 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,25 +58,24 @@ #' plot(x) #' } img_edit <- - function( - spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function(spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index fdfe5b83..db6dfcb1 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,13 +41,12 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function( - spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 314b9b0d..31c368c9 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,12 +22,11 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function( - spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 6a671a5e..345d5499 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,20 +114,19 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function( - i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function(i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index 4a44fd18..f1530fb1 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,20 +55,19 @@ #' cex = 2 #' ) layer_matrix_plot <- - function( - matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function(matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index f484c912..0ccf0bf2 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,12 +49,11 @@ #' top_n = 10 #' )) layer_stat_cor <- - function( - stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function(stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 0d2653b8..c0f4e924 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,12 +72,11 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function( - cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function(cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 70bc49ac..ef76f1d0 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,8 +24,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index d9f31fc2..501a744d 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,17 +44,16 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 6921dbb9..3f36260c 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,10 +24,9 @@ #' head(registration_mod) #' registration_model <- - function( - sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function(sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 2d859e4e..5f3c5dd2 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,12 +51,13 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index d1d0b135..c899459d 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,15 +50,14 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index cd3ee182..d186547e 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,13 +34,14 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index 09bb3ff9..afb9771a 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,13 +32,14 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function(sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 38a1c297..49896d78 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,15 +50,16 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index 93701444..b7beae48 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -186,55 +186,54 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function( - spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - ...) { +run_app <- function(spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index fac5f65b..b21902c1 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,11 +59,12 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index 0d68b880..d2c3c01f 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,9 +27,10 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index 5e1cfc1a..fb95c390 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -93,30 +93,31 @@ #' ) #' print(p4) #' } -vis_clus <- function(spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { +vis_clus <- function( + spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { # Verify existence and legitimacy of 'sampleid' if ( !("sample_id" %in% colnames(colData(spe))) || diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index d2b37cec..a91ce369 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,19 +42,18 @@ #' rm(spe_sub) #' } vis_clus_p <- - function( - spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function(spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 9bc3dc0a..e659d477 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,24 +48,23 @@ #' rm(spe_sub) #' } vis_gene_p <- - function( - spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function(spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 8c81ace6..40ead6b3 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,23 +47,22 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function( - spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index 2504cce5..e21b5bf1 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,25 +35,24 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function( - spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { From c63e2ee9e4d825621aa35f92007dece2f0589613 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 12 Mar 2024 16:00:17 -0400 Subject: [PATCH 077/259] Use up-to-date 'vis_gene' code (supporting multiple genes) when computing 'output' --- R/app_server.R | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 865e1cb2..34d42d4d 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -605,15 +605,50 @@ app_server <- function(input, output, session) { } ## From vis_gene() in global.R + spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], optional = TRUE ) - if (geneid %in% colnames(d)) { - d$COUNT <- d[[geneid]] + # Grab any continuous colData columns + cont_cols <- as.matrix( + colData(spe_sub)[ + , geneid[geneid %in% colnames(colData(spe_sub))], + drop = FALSE + ] + ) + + # Get the integer indices of each gene in the SpatialExperiment, since we + # aren't guaranteed that rownames are gene names + remaining_geneid <- geneid[!(geneid %in% colnames(colData(spe_sub)))] + valid_gene_indices <- unique( + c( + match(remaining_geneid, rowData(spe_sub)$gene_search), + match(remaining_geneid, rownames(spe_sub)) + ) + ) + valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] + + # Grab any genes + gene_cols <- t( + as.matrix(assays(spe_sub[valid_gene_indices, ])[[assayname]]) + ) + + # Combine into one matrix where rows are genes and columns are continuous + # features + cont_matrix <- cbind(cont_cols, gene_cols) + + # Determine plot and legend titles + if (ncol(cont_matrix) == 1) { + d$COUNT <- cont_matrix[, 1] } else { - d$COUNT <- - assays(spe)[[assayname]][which(rowData(spe)$gene_search == geneid), spe$sample_id == sampleid] + if (multi_gene_method == "z_score") { + d$COUNT <- multi_gene_z_score(cont_matrix) + } else if (multi_gene_method == "sparsity") { + d$COUNT <- multi_gene_sparsity(cont_matrix) + } else { # must be 'pca' + d$COUNT <- multi_gene_pca(cont_matrix) + } } d$COUNT[d$COUNT <= minCount] <- NA From 3192ebe451736377cd1ece23e86a3f23302e84c1 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 11:50:04 -0400 Subject: [PATCH 078/259] Use up-to-date (supporting multiple genes) 'vis_gene' code for the interactive gene Shiny tab --- R/app_server.R | 51 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 34d42d4d..50a4fd0e 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1088,19 +1088,48 @@ app_server <- function(input, output, session) { ) } else { ## Prepare the data - d <- - as.data.frame( - cbind( - colData(spe), - SpatialExperiment::spatialCoords(spe) - )[spe$key %in% event.data$key, ], - optional = TRUE + spe_sub <- spe[, spe$key %in% event.data$key] + d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) + + # Grab any continuous colData columns + cont_cols <- as.matrix( + colData(spe_sub)[ + , input$geneid[input$geneid %in% colnames(colData(spe_sub))], + drop = FALSE + ] + ) + + # Get the integer indices of each gene in the SpatialExperiment, since we + # aren't guaranteed that rownames are gene names + remaining_geneid <- input$geneid[!(input$geneid %in% colnames(colData(spe_sub)))] + valid_gene_indices <- unique( + c( + match(remaining_geneid, rowData(spe_sub)$gene_search), + match(remaining_geneid, rownames(spe_sub)) ) - if (input$geneid %in% colnames(d)) { - d$COUNT <- d[[input$geneid]] + ) + valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] + + # Grab any genes + gene_cols <- t( + as.matrix(assays(spe_sub[valid_gene_indices, ])[[input$assayname]]) + ) + + # Combine into one matrix where rows are genes and columns are continuous + # features + cont_matrix <- cbind(cont_cols, gene_cols) + + # Determine plot and legend titles + if (ncol(cont_matrix) == 1) { + d$COUNT <- cont_matrix[, 1] } else { - d$COUNT <- - assays(spe)[[input$assayname]][which(rowData(spe)$gene_search == input$geneid), spe$key %in% event.data$key] + if (multi_gene_method == "z_score") { + d$COUNT <- multi_gene_z_score(cont_matrix) + } else if (multi_gene_method == "sparsity") { + d$COUNT <- multi_gene_sparsity(cont_matrix) + } else { # must be 'pca' + d$COUNT <- multi_gene_pca(cont_matrix) + } } d$COUNT[d$COUNT <= input$minCount] <- NA From 530fc875a870cd6f86de72d8ee97808567385e0c Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 12:02:17 -0400 Subject: [PATCH 079/259] Enable selection of multiple genes in Shiny app --- R/app_ui.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/app_ui.R b/R/app_ui.R index 410bb374..2c402415 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -110,7 +110,8 @@ app_ui <- function() { golem::get_golem_options("spe_continuous_vars"), sort(rowData(spe)$gene_search) ), - options = pickerOptions(liveSearch = TRUE) + options = pickerOptions(liveSearch = TRUE), + multiple = TRUE ), helpText("Typically a gene or any other continuous variable."), hr(), From 8e19b0c1e7631357eb2f1e7a0baa0d5b62d173eb Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 12:17:01 -0400 Subject: [PATCH 080/259] Add a selection menu for multi-gene method, though it appears to be ignored right now (always choosing the default: z_score) --- R/app_server.R | 4 ++-- R/app_ui.R | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 50a4fd0e..6cfb2c63 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1123,9 +1123,9 @@ app_server <- function(input, output, session) { if (ncol(cont_matrix) == 1) { d$COUNT <- cont_matrix[, 1] } else { - if (multi_gene_method == "z_score") { + if (input$multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) - } else if (multi_gene_method == "sparsity") { + } else if (input$multi_gene_method == "sparsity") { d$COUNT <- multi_gene_sparsity(cont_matrix) } else { # must be 'pca' d$COUNT <- multi_gene_pca(cont_matrix) diff --git a/R/app_ui.R b/R/app_ui.R index 2c402415..29820f50 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -113,7 +113,15 @@ app_ui <- function() { options = pickerOptions(liveSearch = TRUE), multiple = TRUE ), - helpText("Typically a gene or any other continuous variable."), + helpText("Typically gene(s) or any other continuous variable(s)."), + hr(), + selectInput( + inputId = "multi_gene_method", + label = "Multi-gene method", + choices = c("z_score", "pca", "sparsity"), + selected = "z_score" + ), + helpText("When applicable, the method used to combine multiple continuous variables."), hr(), selectInput( inputId = "assayname", From e8d09572d48e6de8fddbcdde36550c4ec9499972 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 13:17:12 -0400 Subject: [PATCH 081/259] Use 'input', not 'multi_gene_method', which is undefined --- R/app_server.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 6cfb2c63..10482e1d 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -642,9 +642,9 @@ app_server <- function(input, output, session) { if (ncol(cont_matrix) == 1) { d$COUNT <- cont_matrix[, 1] } else { - if (multi_gene_method == "z_score") { + if (input$multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) - } else if (multi_gene_method == "sparsity") { + } else if (input$multi_gene_method == "sparsity") { d$COUNT <- multi_gene_sparsity(cont_matrix) } else { # must be 'pca' d$COUNT <- multi_gene_pca(cont_matrix) From 9aa017771fcbec58488fdc8a0aff0a38b759ec9d Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 13:46:50 -0400 Subject: [PATCH 082/259] Add the 'multi_gene_method' parameter for static gene tabs so it isn't ignored --- R/app_server.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/app_server.R b/R/app_server.R index 10482e1d..6059863d 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -225,6 +225,7 @@ app_server <- function(input, output, session) { spe, sampleid = input$sample, geneid = input$geneid, + multi_gene_method = input$multi_gene_method, assayname = input$assayname, minCount = input$minCount, cont_colors = cont_colors(), @@ -259,6 +260,7 @@ app_server <- function(input, output, session) { vis_grid_gene( spe, geneid = isolate(input$geneid), + multi_gene_method = input$multi_gene_method, assayname = isolate(input$assayname), minCount = isolate(input$minCount), return_plots = TRUE, From 32ef99517aab46bd8d84734ecd0b64595346480d Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 14:22:55 -0400 Subject: [PATCH 083/259] Make downloaded filenames make sense with 1 or mor genes (before, worked only for 1 gene) --- R/app_server.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 6059863d..9015ff99 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -418,7 +418,7 @@ app_server <- function(input, output, session) { "_", paste0( "spatialLIBD_static_gene_", - input$geneid, + paste0(input$geneid, collapse = "_"), "_", input$sample, "_", @@ -446,7 +446,7 @@ app_server <- function(input, output, session) { "_", paste0( "spatialLIBD_static_gene_grid_", - input$geneid, + paste0(input$geneid, collapse = "_"), "_", paste0(input$grid_samples, collapse = "_"), "_", From d7ac81257e3c95b131e735fd48fabdc83e42df40 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 15:06:00 -0400 Subject: [PATCH 084/259] Experimental fix: don't subset the SpatialExperiment to selected genes, which was producing a bug and didn't appear to change behavior --- R/app_server.R | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 9015ff99..31f3fdb6 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -937,15 +937,9 @@ app_server <- function(input, output, session) { return(NULL) } - gene_selected <- ifelse( - input$geneid %in% rowData(spe)$gene_search, - which(rowData(spe)$gene_search == input$geneid), - 1 - ) - p <- vis_gene( - spe[gene_selected, cluster_opts], + spe[, cluster_opts], sampleid = input$sample, geneid = input$geneid, assayname = input$assayname, From d7f77e4508026c6cd10f5958095cd09788bd9a9f Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 15:11:01 -0400 Subject: [PATCH 085/259] Add 'mult_gene_method' as a parameter to intereactive gene plotly plots --- R/app_server.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/app_server.R b/R/app_server.R index 31f3fdb6..f638b665 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -942,6 +942,7 @@ app_server <- function(input, output, session) { spe[, cluster_opts], sampleid = input$sample, geneid = input$geneid, + multi_gene_method = input$multi_gene_method, assayname = input$assayname, minCount = input$minCount, spatial = FALSE, From c9d9928ce95e9a6dead819b7244dca1c2a78f9b2 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Wed, 13 Mar 2024 15:23:57 -0400 Subject: [PATCH 086/259] Use up-to-date vis_gene code in code to update manual annotations of selected points --- R/app_server.R | 51 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index f638b665..c618cbb7 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1049,19 +1049,48 @@ app_server <- function(input, output, session) { } if (!is.null(event.data)) { ## Prepare the data - d <- - as.data.frame( - cbind( - colData(spe), - SpatialExperiment::spatialCoords(spe) - )[spe$key %in% event.data$key, ], - optional = TRUE + spe_sub <- spe[, spe$key %in% event.data$key] + d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) + + # Grab any continuous colData columns + cont_cols <- as.matrix( + colData(spe_sub)[ + , input$geneid[input$geneid %in% colnames(colData(spe_sub))], + drop = FALSE + ] + ) + + # Get the integer indices of each gene in the SpatialExperiment, since we + # aren't guaranteed that rownames are gene names + remaining_geneid <- input$geneid[!(input$geneid %in% colnames(colData(spe_sub)))] + valid_gene_indices <- unique( + c( + match(remaining_geneid, rowData(spe_sub)$gene_search), + match(remaining_geneid, rownames(spe_sub)) ) - if (input$geneid %in% colnames(d)) { - d$COUNT <- d[[input$geneid]] + ) + valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] + + # Grab any genes + gene_cols <- t( + as.matrix(assays(spe_sub[valid_gene_indices, ])[[input$assayname]]) + ) + + # Combine into one matrix where rows are genes and columns are continuous + # features + cont_matrix <- cbind(cont_cols, gene_cols) + + # Determine plot and legend titles + if (ncol(cont_matrix) == 1) { + d$COUNT <- cont_matrix[, 1] } else { - d$COUNT <- - assays(spe)[[input$assayname]][which(rowData(spe)$gene_search == input$geneid), spe$key %in% event.data$key] + if (input$multi_gene_method == "z_score") { + d$COUNT <- multi_gene_z_score(cont_matrix) + } else if (input$multi_gene_method == "sparsity") { + d$COUNT <- multi_gene_sparsity(cont_matrix) + } else { # must be 'pca' + d$COUNT <- multi_gene_pca(cont_matrix) + } } d$COUNT[d$COUNT <= input$minCount] <- NA From faf2863164bebc72d30c091d492cf80c4f6dc22d Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 14 Mar 2024 08:38:13 -0400 Subject: [PATCH 087/259] Document the updated multi-gene-related Shiny tabs --- R/app_ui.R | 2 +- inst/app/www/documentation_spe.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/R/app_ui.R b/R/app_ui.R index 29820f50..ad9d199f 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -105,7 +105,7 @@ app_ui <- function() { hr(), pickerInput( inputId = "geneid", - label = "Continuous variable to plot", + label = "Continuous variable(s) to plot", choices = c( golem::get_golem_options("spe_continuous_vars"), sort(rowData(spe)$gene_search) diff --git a/inst/app/www/documentation_spe.md b/inst/app/www/documentation_spe.md index 68e374ae..8c85e69a 100644 --- a/inst/app/www/documentation_spe.md +++ b/inst/app/www/documentation_spe.md @@ -43,7 +43,8 @@ Throughout the rest of this document, we'll refer to this object by the name `sp - resulting from using a shared nearest neighbors approach with 50 neighbors cut at 4 up to 28 clusters. These are `SNN_k50_k4` up to `SNN_k50_k28`. - described in Figure 7 from our paper (DOI: [10.1038/s41593-020-00787-0](https://doi.org/10.1038/s41593-020-00787-0)) such as `SpatialDE_PCA`, `SpatialDE_pool_PCA` and others. * `Reduced dimensions`: which reduced dimension to visualize on the `clusters (interactive)` tab. Only the first two dimensions will be shown. -* `Continuous variable to plot`: which gene or continuous variable (such as the cell count, the ratio of the mitochondrial chromosome expression) to visualize in the gene tabs as well as on the `clusters (interactive)` tab. +* `Continuous variable(s) to plot`: which gene(s) or continuous variable(s) (such as the cell count, the ratio of the mitochondrial chromosome expression) to visualize in the gene tabs as well as on the `clusters (interactive)` tab. Multiple choices may be selected, in which case "Multi-gene method" controls the method used to combine information from all selected variables. +* `Multi-gene method`: when selecting more than one continuous variable, the method used to combine information from all selected variables. * `Gene scale`: whether to use the raw expression values (`counts`) or the scaled and log transformed values (`logcounts`). * `Image name`: the name of the background image to use. You can edit this image on the `Edit image` tab. * `Spot transparency level`: the transparency of the spots in the visualizations. It can be useful if the spot colors are blocking the background image. From 8801ac6b163935b84e1160ad74b1d024d3aca989 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 15 Mar 2024 09:32:45 -0400 Subject: [PATCH 088/259] Add checks and subsetting for zero-variance features when plotting multiple features and using 'pca' or 'z_score' methods --- R/vis_gene.R | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index 49dec567..b1f4e5ae 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -224,7 +224,7 @@ vis_gene <- as.matrix(assays(spe_sub[valid_gene_indices, ])[[assayname]]) ) - # Combine into one matrix where rows are genes and columns are continuous + # Combine into one matrix where rows are samples and columns are continuous # features cont_matrix <- cbind(cont_cols, gene_cols) @@ -239,6 +239,25 @@ vis_gene <- } } else { plot_title <- paste(sampleid, ...) + + # PCA and Z-score calculation requires at least 2 features with + # nonzero variance. Verify this and drop any zero-variance features + if (multi_gene_method %in% c("z_score", "pca")) { + good_indices <- which(colSds(cont_matrix) != 0) + if (length(good_indices) < 2) { + stop("After dropping features with no expression variation, less than 2 features were left") + } + if (ncol(cont_matrix) - length(good_indices) > 0) { + warning( + sprintf( + "Dropping features(s) '%s' which have no expression variation", + paste(colnames(cont_matrix)[-good_indices], collapse = "', '") + ) + ) + } + cont_matrix = cont_matrix[, good_indices] + } + if (multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) legend_title <- paste("Z score\n min > ", minCount) From e3adf9dd60f1acf2430f68752a1408f0b30f9648 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 18 Mar 2024 12:19:06 -0400 Subject: [PATCH 089/259] Fix handling of title in clusters:interactive to support multiple genes --- R/app_server.R | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index c618cbb7..b7654150 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -642,14 +642,26 @@ app_server <- function(input, output, session) { # Determine plot and legend titles if (ncol(cont_matrix) == 1) { + if (!(geneid %in% colnames(colData(spe_sub)))) { + plot_title <- sprintf( + "%s %s %s min > %s", sampleid, geneid, assayname, minCount + ) + } else { + plot_title <- sprintf( + "%s %s min > %s", sampleid, geneid, minCount + ) + } d$COUNT <- cont_matrix[, 1] } else { if (input$multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) + plot_title <- paste(sampleid, "Z-score min > ", minCount) } else if (input$multi_gene_method == "sparsity") { d$COUNT <- multi_gene_sparsity(cont_matrix) + plot_title <- paste(sampleid, "Prop. nonzero min > ", minCount) } else { # must be 'pca' d$COUNT <- multi_gene_pca(cont_matrix) + plot_title <- paste(sampleid, "PC1 min >", minCount) } } d$COUNT[d$COUNT <= minCount] <- NA @@ -677,18 +689,7 @@ app_server <- function(input, output, session) { sampleid = sampleid, colors = get_colors(colors, d[, clustervar]), spatial = FALSE, - title = paste( - sampleid, - clustervar, - geneid, - if (!geneid %in% colnames(colData(spe))) { - assayname - } else { - NULL - }, - "min >", - minCount - ), + title = plot_title, image_id = input$imageid, alpha = input$alphalevel, point_size = input$pointsize, @@ -1051,7 +1052,7 @@ app_server <- function(input, output, session) { ## Prepare the data spe_sub <- spe[, spe$key %in% event.data$key] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) - + # Grab any continuous colData columns cont_cols <- as.matrix( colData(spe_sub)[ @@ -1059,7 +1060,7 @@ app_server <- function(input, output, session) { drop = FALSE ] ) - + # Get the integer indices of each gene in the SpatialExperiment, since we # aren't guaranteed that rownames are gene names remaining_geneid <- input$geneid[!(input$geneid %in% colnames(colData(spe_sub)))] @@ -1070,16 +1071,16 @@ app_server <- function(input, output, session) { ) ) valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] - + # Grab any genes gene_cols <- t( as.matrix(assays(spe_sub[valid_gene_indices, ])[[input$assayname]]) ) - + # Combine into one matrix where rows are genes and columns are continuous # features cont_matrix <- cbind(cont_cols, gene_cols) - + # Determine plot and legend titles if (ncol(cont_matrix) == 1) { d$COUNT <- cont_matrix[, 1] @@ -1116,7 +1117,7 @@ app_server <- function(input, output, session) { ## Prepare the data spe_sub <- spe[, spe$key %in% event.data$key] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) - + # Grab any continuous colData columns cont_cols <- as.matrix( colData(spe_sub)[ @@ -1124,7 +1125,7 @@ app_server <- function(input, output, session) { drop = FALSE ] ) - + # Get the integer indices of each gene in the SpatialExperiment, since we # aren't guaranteed that rownames are gene names remaining_geneid <- input$geneid[!(input$geneid %in% colnames(colData(spe_sub)))] @@ -1135,16 +1136,16 @@ app_server <- function(input, output, session) { ) ) valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] - + # Grab any genes gene_cols <- t( as.matrix(assays(spe_sub[valid_gene_indices, ])[[input$assayname]]) ) - + # Combine into one matrix where rows are genes and columns are continuous # features cont_matrix <- cbind(cont_cols, gene_cols) - + # Determine plot and legend titles if (ncol(cont_matrix) == 1) { d$COUNT <- cont_matrix[, 1] From 7704abc577337058931a03e9935fe830aec2e790 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 16:38:27 -0400 Subject: [PATCH 090/259] Memory saving oriented changes Co-authored-by: Nick Eagles --- R/app_server.R | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index b7654150..664d6548 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1115,31 +1115,37 @@ app_server <- function(input, output, session) { ) } else { ## Prepare the data - spe_sub <- spe[, spe$key %in% event.data$key] - d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) + d <- + as.data.frame( + cbind( + colData(spe), + SpatialExperiment::spatialCoords(spe) + )[spe$key %in% event.data$key, ], + optional = TRUE + ) # Grab any continuous colData columns cont_cols <- as.matrix( - colData(spe_sub)[ - , input$geneid[input$geneid %in% colnames(colData(spe_sub))], + d[ + , input$geneid[input$geneid %in% colnames(d)], drop = FALSE ] ) # Get the integer indices of each gene in the SpatialExperiment, since we # aren't guaranteed that rownames are gene names - remaining_geneid <- input$geneid[!(input$geneid %in% colnames(colData(spe_sub)))] + remaining_geneid <- input$geneid[!(input$geneid %in% colnames(d))] valid_gene_indices <- unique( c( - match(remaining_geneid, rowData(spe_sub)$gene_search), - match(remaining_geneid, rownames(spe_sub)) + match(remaining_geneid, rowData(spe)$gene_search), + match(remaining_geneid, rownames(spe)) ) ) valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] # Grab any genes gene_cols <- t( - as.matrix(assays(spe_sub[valid_gene_indices, ])[[input$assayname]]) + as.matrix(assays(spe[valid_gene_indices, spe$key %in% event.data$key])[[input$assayname]]) ) # Combine into one matrix where rows are genes and columns are continuous @@ -1148,7 +1154,7 @@ app_server <- function(input, output, session) { # Determine plot and legend titles if (ncol(cont_matrix) == 1) { - d$COUNT <- cont_matrix[, 1] + d$COUNT <- as.vector(cont_matrix) } else { if (input$multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) From 01b17a624d622c5bbc71f73a22aa3eb74d742f85 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 16:39:01 -0400 Subject: [PATCH 091/259] Message for debugging "Gene (interactive)" Co-authored-by: Nick Eagles --- R/app_server.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/app_server.R b/R/app_server.R index 664d6548..31741244 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1106,6 +1106,7 @@ app_server <- function(input, output, session) { output$click_gene <- renderPrint({ if (!is.null(input$gene_plotly_cluster_subset)) { event.data <- event_data("plotly_click", source = "plotly_gene") + warning("hm... ", event.data$key[1]) } else { event.data <- NULL } From a9360368128b23c6f55f67ed7c52f96b85497ef0 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 16:56:05 -0400 Subject: [PATCH 092/259] Change default dragmode to lasso, which is the one I intuitively expect to be selected --- R/app_server.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 31741244..62ad234b 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -812,7 +812,7 @@ app_server <- function(input, output, session) { opacity = 0.8 ) ), - dragmode = "select" + dragmode = "lasso" ) plotly_gene <- layout( @@ -837,7 +837,7 @@ app_server <- function(input, output, session) { opacity = 0.8 ) ), - dragmode = "select" + dragmode = "lasso" ) plotly_dim <- @@ -1001,7 +1001,7 @@ app_server <- function(input, output, session) { opacity = 0.8 ) ), - dragmode = "select" + dragmode = "lasso" ) ))) }) From 92c4e95d0d8f79e9eee8de77d70fa0fcea2f546b Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 17:18:26 -0400 Subject: [PATCH 093/259] We were not using event.data$key to assign the "Gene (interactive)" results. We didn't need to run a bunch of the count for creating d$COUNT. I think this resolves https://github.com/LieberInstitute/spatialLIBD/issues/75#issuecomment-2023785904. --- R/app_server.R | 62 +++----------------------------------------------- 1 file changed, 3 insertions(+), 59 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 62ad234b..dd951e41 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1104,73 +1104,17 @@ app_server <- function(input, output, session) { }) output$click_gene <- renderPrint({ - if (!is.null(input$gene_plotly_cluster_subset)) { - event.data <- event_data("plotly_click", source = "plotly_gene") - warning("hm... ", event.data$key[1]) - } else { - event.data <- NULL - } + event.data <- + event_data("plotly_click", source = "plotly_gene") if (is.null(event.data)) { return( "Single points clicked and updated with a manual annotation appear here (double-click to clear)" ) } else { - ## Prepare the data - d <- - as.data.frame( - cbind( - colData(spe), - SpatialExperiment::spatialCoords(spe) - )[spe$key %in% event.data$key, ], - optional = TRUE - ) - - # Grab any continuous colData columns - cont_cols <- as.matrix( - d[ - , input$geneid[input$geneid %in% colnames(d)], - drop = FALSE - ] - ) - - # Get the integer indices of each gene in the SpatialExperiment, since we - # aren't guaranteed that rownames are gene names - remaining_geneid <- input$geneid[!(input$geneid %in% colnames(d))] - valid_gene_indices <- unique( - c( - match(remaining_geneid, rowData(spe)$gene_search), - match(remaining_geneid, rownames(spe)) - ) - ) - valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] - - # Grab any genes - gene_cols <- t( - as.matrix(assays(spe[valid_gene_indices, spe$key %in% event.data$key])[[input$assayname]]) - ) - - # Combine into one matrix where rows are genes and columns are continuous - # features - cont_matrix <- cbind(cont_cols, gene_cols) - - # Determine plot and legend titles - if (ncol(cont_matrix) == 1) { - d$COUNT <- as.vector(cont_matrix) - } else { - if (input$multi_gene_method == "z_score") { - d$COUNT <- multi_gene_z_score(cont_matrix) - } else if (input$multi_gene_method == "sparsity") { - d$COUNT <- multi_gene_sparsity(cont_matrix) - } else { # must be 'pca' - d$COUNT <- multi_gene_pca(cont_matrix) - } - } - d$COUNT[d$COUNT <= input$minCount] <- NA - isolate({ ## Now update with the ManualAnnotation input if (input$label_click_gene) { - rv$ManualAnnotation[spe$key %in% d$key[!is.na(d$COUNT)]] <- + rv$ManualAnnotation[spe$key %in% event.data$key] <- input$label_manual_ann_gene } }) From 4fdef4fc4e861bde955f3e83c3782bf999344063 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 17:27:42 -0400 Subject: [PATCH 094/259] Never mind. The simple version allows one to click on spots not that we don't want to (aka below minCount or not even shown with a fill color) and annotate them, which makes it easy to introduce errors. --- R/app_server.R | 64 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index dd951e41..fd9fc0a0 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1104,17 +1104,75 @@ app_server <- function(input, output, session) { }) output$click_gene <- renderPrint({ - event.data <- - event_data("plotly_click", source = "plotly_gene") + if (!is.null(input$gene_plotly_cluster_subset)) { + event.data <- event_data("plotly_click", source = "plotly_gene", priority = "event") + warning("hm... ", event.data$key[1]) + } else { + event.data <- NULL + } if (is.null(event.data)) { return( "Single points clicked and updated with a manual annotation appear here (double-click to clear)" ) } else { + ## Prepare the data + d <- + as.data.frame( + cbind( + colData(spe), + SpatialExperiment::spatialCoords(spe) + )[spe$key %in% event.data$key, ], + optional = TRUE + ) + + # Grab any continuous colData columns + cont_cols <- as.matrix( + d[ + , input$geneid[input$geneid %in% colnames(d)], + drop = FALSE + ] + ) + + # Get the integer indices of each gene in the SpatialExperiment, since we + # aren't guaranteed that rownames are gene names + remaining_geneid <- input$geneid[!(input$geneid %in% colnames(d))] + valid_gene_indices <- unique( + c( + match(remaining_geneid, rowData(spe)$gene_search), + match(remaining_geneid, rownames(spe)) + ) + ) + valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] + + # Grab any genes + gene_cols <- t( + as.matrix(assays(spe[valid_gene_indices, spe$key %in% event.data$key])[[input$assayname]]) + ) + + # Combine into one matrix where rows are genes and columns are continuous + # features + cont_matrix <- cbind(cont_cols, gene_cols) + + # Determine plot and legend titles + if (ncol(cont_matrix) == 1) { + d$COUNT <- as.vector(cont_matrix) + } else { + if (input$multi_gene_method == "z_score") { + d$COUNT <- multi_gene_z_score(cont_matrix) + } else if (input$multi_gene_method == "sparsity") { + d$COUNT <- multi_gene_sparsity(cont_matrix) + } else { # must be 'pca' + d$COUNT <- multi_gene_pca(cont_matrix) + } + } + d$COUNT[d$COUNT <= input$minCount] <- NA + isolate({ ## Now update with the ManualAnnotation input if (input$label_click_gene) { - rv$ManualAnnotation[spe$key %in% event.data$key] <- + warning("attempting to save the label result") + warning(d$key[!is.na(d$COUNT)][1]) + rv$ManualAnnotation[spe$key %in% d$key[!is.na(d$COUNT)]] <- input$label_manual_ann_gene } }) From 418f2b18c0c7262f1340cc7e78c11bfa0854ef2f Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 17:48:46 -0400 Subject: [PATCH 095/259] I've now found the root of the issue with data for debugging. `multi_gene_z_score()` is returning a NaN with an input matrix that only has 1 row ```R shiny_updates* > cont_matrix cell_count sum_umi GATTCCCTTGTCGCAG-1 1 2036 shiny_updates* > d sample_id Cluster sum_umi sum_gene subject position replicate subject_position discard GATTCCCTTGTCGCAG-1 151508 1 2036 1148 Br5292 0 2 Br5292_pos0 FALSE key cell_count SNN_k50_k4 SNN_k50_k5 SNN_k50_k6 SNN_k50_k7 SNN_k50_k8 GATTCCCTTGTCGCAG-1 151508_GATTCCCTTGTCGCAG-1 1 1 1 1 3 3 SNN_k50_k9 SNN_k50_k10 SNN_k50_k11 SNN_k50_k12 SNN_k50_k13 SNN_k50_k14 SNN_k50_k15 GATTCCCTTGTCGCAG-1 4 4 5 5 5 6 7 SNN_k50_k16 SNN_k50_k17 SNN_k50_k18 SNN_k50_k19 SNN_k50_k20 SNN_k50_k21 SNN_k50_k22 GATTCCCTTGTCGCAG-1 7 8 9 9 9 9 10 SNN_k50_k23 SNN_k50_k24 SNN_k50_k25 SNN_k50_k26 SNN_k50_k27 SNN_k50_k28 GraphBased Maynard GATTCCCTTGTCGCAG-1 10 10 11 12 12 13 1 4 Martinowich layer_guess layer_guess_reordered layer_guess_reordered_short expr_chrM GATTCCCTTGTCGCAG-1 4 Layer3 Layer3 L3 428 expr_chrM_ratio SpatialDE_PCA SpatialDE_pool_PCA HVG_PCA pseudobulk_PCA markers_PCA GATTCCCTTGTCGCAG-1 0.2102161 1 2 5 2 1 SpatialDE_UMAP SpatialDE_pool_UMAP HVG_UMAP pseudobulk_UMAP markers_UMAP GATTCCCTTGTCGCAG-1 6 3 5 1 9 SpatialDE_PCA_spatial SpatialDE_pool_PCA_spatial HVG_PCA_spatial pseudobulk_PCA_spatial GATTCCCTTGTCGCAG-1 2 1 3 2 markers_PCA_spatial SpatialDE_UMAP_spatial SpatialDE_pool_UMAP_spatial HVG_UMAP_spatial GATTCCCTTGTCGCAG-1 1 1 4 4 pseudobulk_UMAP_spatial markers_UMAP_spatial spatialLIBD ManualAnnotation in_tissue GATTCCCTTGTCGCAG-1 1 9 L3 NA TRUE array_row array_col pxl_col_in_fullres pxl_row_in_fullres COUNT GATTCCCTTGTCGCAG-1 25 67 6771 5584 NaN ``` --- R/app_server.R | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index fd9fc0a0..f1859fec 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1104,6 +1104,7 @@ app_server <- function(input, output, session) { }) output$click_gene <- renderPrint({ + if (!is.null(input$gene_plotly_cluster_subset)) { event.data <- event_data("plotly_click", source = "plotly_gene", priority = "event") warning("hm... ", event.data$key[1]) @@ -1114,28 +1115,46 @@ app_server <- function(input, output, session) { return( "Single points clicked and updated with a manual annotation appear here (double-click to clear)" ) - } else { + } else if (input$label_click_gene) { + ## Only run this code if we are actually going to annotate anything + + ## Define arguments for debugging + event_keys <- event.data$key + geneid <- input$geneid + assayname <- input$assayname + minCount <- input$minCount + multi_gene_method <- input$multi_gene_method + + # ## Testing: + # set.seed(20240327) + # event_keys <- sample(spe$key, 1) + # geneid <- "SCGB2A2; ENSG00000110484" + # geneid <- c("cell_count", "sum_umi") + # assayname <- 'logcounts' + # multi_gene_method <- "z_score" + # minCount <- 0 + ## Prepare the data d <- as.data.frame( cbind( colData(spe), SpatialExperiment::spatialCoords(spe) - )[spe$key %in% event.data$key, ], + )[spe$key %in% event_keys, ], optional = TRUE ) # Grab any continuous colData columns cont_cols <- as.matrix( d[ - , input$geneid[input$geneid %in% colnames(d)], + , geneid[geneid %in% colnames(d)], drop = FALSE ] ) # Get the integer indices of each gene in the SpatialExperiment, since we # aren't guaranteed that rownames are gene names - remaining_geneid <- input$geneid[!(input$geneid %in% colnames(d))] + remaining_geneid <- geneid[!(geneid %in% colnames(d))] valid_gene_indices <- unique( c( match(remaining_geneid, rowData(spe)$gene_search), @@ -1146,7 +1165,7 @@ app_server <- function(input, output, session) { # Grab any genes gene_cols <- t( - as.matrix(assays(spe[valid_gene_indices, spe$key %in% event.data$key])[[input$assayname]]) + as.matrix(assays(spe[valid_gene_indices, spe$key %in% event_keys])[[assayname]]) ) # Combine into one matrix where rows are genes and columns are continuous @@ -1157,26 +1176,27 @@ app_server <- function(input, output, session) { if (ncol(cont_matrix) == 1) { d$COUNT <- as.vector(cont_matrix) } else { - if (input$multi_gene_method == "z_score") { + if (multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) - } else if (input$multi_gene_method == "sparsity") { + } else if (multi_gene_method == "sparsity") { d$COUNT <- multi_gene_sparsity(cont_matrix) } else { # must be 'pca' d$COUNT <- multi_gene_pca(cont_matrix) } } - d$COUNT[d$COUNT <= input$minCount] <- NA + d$COUNT[d$COUNT <= minCount] <- NA isolate({ ## Now update with the ManualAnnotation input - if (input$label_click_gene) { - warning("attempting to save the label result") - warning(d$key[!is.na(d$COUNT)][1]) - rv$ManualAnnotation[spe$key %in% d$key[!is.na(d$COUNT)]] <- - input$label_manual_ann_gene - } + warning("attempting to save the label result") + warning(length(unique(d$key))) + warning(sum(!is.na(d$COUNT))) + warning(d$key[!is.na(d$COUNT)][1]) + rv$ManualAnnotation[spe$key %in% d$key[!is.na(d$COUNT)]] <- + input$label_manual_ann_gene + + return(event.data$key) }) - return(event.data$key) } }) From 263a6870ac323873a3245b10f57d5c3aafbfc951 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 17:52:08 -0400 Subject: [PATCH 096/259] Apply same memory-saving changes to the annotation by selection under "Gene (interactive)" --- R/app_server.R | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index f1859fec..609ebd6b 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1050,31 +1050,37 @@ app_server <- function(input, output, session) { } if (!is.null(event.data)) { ## Prepare the data - spe_sub <- spe[, spe$key %in% event.data$key] - d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) + d <- + as.data.frame( + cbind( + colData(spe), + SpatialExperiment::spatialCoords(spe) + )[spe$key %in% event.data$key, ], + optional = TRUE + ) # Grab any continuous colData columns cont_cols <- as.matrix( - colData(spe_sub)[ - , input$geneid[input$geneid %in% colnames(colData(spe_sub))], + d[ + , input$geneid[input$geneid %in% colnames(d)], drop = FALSE ] ) # Get the integer indices of each gene in the SpatialExperiment, since we # aren't guaranteed that rownames are gene names - remaining_geneid <- input$geneid[!(input$geneid %in% colnames(colData(spe_sub)))] + remaining_geneid <- input$geneid[!(input$geneid %in% colnames(d))] valid_gene_indices <- unique( c( - match(remaining_geneid, rowData(spe_sub)$gene_search), - match(remaining_geneid, rownames(spe_sub)) + match(remaining_geneid, rowData(spe)$gene_search), + match(remaining_geneid, rownames(spe)) ) ) valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] # Grab any genes gene_cols <- t( - as.matrix(assays(spe_sub[valid_gene_indices, ])[[input$assayname]]) + as.matrix(assays(spe[valid_gene_indices, spe$key %in% event.data$key])[[input$assayname]]) ) # Combine into one matrix where rows are genes and columns are continuous @@ -1083,7 +1089,7 @@ app_server <- function(input, output, session) { # Determine plot and legend titles if (ncol(cont_matrix) == 1) { - d$COUNT <- cont_matrix[, 1] + d$COUNT <- as.vector(cont_matrix) } else { if (input$multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) From cc59a1d453813bf205e5ab2d9c9369f5d1d71dc6 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 18:18:40 -0400 Subject: [PATCH 097/259] Speed things up by using reactiveValues to save the results. This also circumvents the current bugs / limitations in the multi_gene_*() functions as the d$COUNT data across all spots of a given sample are saved for later re-use. --- R/app_server.R | 76 ++++---------------------------------------------- 1 file changed, 5 insertions(+), 71 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 609ebd6b..e511352a 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -30,7 +30,7 @@ app_server <- function(input, output, session) { # List the first level callModules here ## Global variables needed throughout the app - rv <- reactiveValues(ManualAnnotation = rep("NA", ncol(spe))) + rv <- reactiveValues(ManualAnnotation = rep("NA", ncol(spe)), ContCount = data.frame(key = spe$key, COUNT = NA)) ## From /dcs04/lieber/lcolladotor/with10x_LIBD001/HumanPilot/Analysis/rda_scran/clust_10x_layer_maynard_martinowich.Rdata # cat(paste0("'", names(cols_layers_martinowich), "' = '", cols_layers_martinowich, "',\n")) @@ -960,6 +960,9 @@ app_server <- function(input, output, session) { alpha = input$alphalevel ) + ## Update the reactiveValues data + rv$ContCount <- p$data[, c("key", "COUNT")] + ## Read in the histology image img <- SpatialExperiment::imgRaster(spe, @@ -1122,79 +1125,10 @@ app_server <- function(input, output, session) { "Single points clicked and updated with a manual annotation appear here (double-click to clear)" ) } else if (input$label_click_gene) { - ## Only run this code if we are actually going to annotate anything - - ## Define arguments for debugging - event_keys <- event.data$key - geneid <- input$geneid - assayname <- input$assayname - minCount <- input$minCount - multi_gene_method <- input$multi_gene_method - - # ## Testing: - # set.seed(20240327) - # event_keys <- sample(spe$key, 1) - # geneid <- "SCGB2A2; ENSG00000110484" - # geneid <- c("cell_count", "sum_umi") - # assayname <- 'logcounts' - # multi_gene_method <- "z_score" - # minCount <- 0 - - ## Prepare the data - d <- - as.data.frame( - cbind( - colData(spe), - SpatialExperiment::spatialCoords(spe) - )[spe$key %in% event_keys, ], - optional = TRUE - ) - - # Grab any continuous colData columns - cont_cols <- as.matrix( - d[ - , geneid[geneid %in% colnames(d)], - drop = FALSE - ] - ) - - # Get the integer indices of each gene in the SpatialExperiment, since we - # aren't guaranteed that rownames are gene names - remaining_geneid <- geneid[!(geneid %in% colnames(d))] - valid_gene_indices <- unique( - c( - match(remaining_geneid, rowData(spe)$gene_search), - match(remaining_geneid, rownames(spe)) - ) - ) - valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] - - # Grab any genes - gene_cols <- t( - as.matrix(assays(spe[valid_gene_indices, spe$key %in% event_keys])[[assayname]]) - ) - - # Combine into one matrix where rows are genes and columns are continuous - # features - cont_matrix <- cbind(cont_cols, gene_cols) - - # Determine plot and legend titles - if (ncol(cont_matrix) == 1) { - d$COUNT <- as.vector(cont_matrix) - } else { - if (multi_gene_method == "z_score") { - d$COUNT <- multi_gene_z_score(cont_matrix) - } else if (multi_gene_method == "sparsity") { - d$COUNT <- multi_gene_sparsity(cont_matrix) - } else { # must be 'pca' - d$COUNT <- multi_gene_pca(cont_matrix) - } - } - d$COUNT[d$COUNT <= minCount] <- NA - isolate({ ## Now update with the ManualAnnotation input warning("attempting to save the label result") + d <- subset(rv$ContCount, key %in% event.data$key) warning(length(unique(d$key))) warning(sum(!is.na(d$COUNT))) warning(d$key[!is.na(d$COUNT)][1]) From 4a3e6b510d52f89d7d8b9358df69e43ba3b88400 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 18:20:36 -0400 Subject: [PATCH 098/259] Remove warning() calls that we used to debug this issue. --- R/app_server.R | 6 ------ 1 file changed, 6 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index e511352a..62cb54f2 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1113,10 +1113,8 @@ app_server <- function(input, output, session) { }) output$click_gene <- renderPrint({ - if (!is.null(input$gene_plotly_cluster_subset)) { event.data <- event_data("plotly_click", source = "plotly_gene", priority = "event") - warning("hm... ", event.data$key[1]) } else { event.data <- NULL } @@ -1127,11 +1125,7 @@ app_server <- function(input, output, session) { } else if (input$label_click_gene) { isolate({ ## Now update with the ManualAnnotation input - warning("attempting to save the label result") d <- subset(rv$ContCount, key %in% event.data$key) - warning(length(unique(d$key))) - warning(sum(!is.na(d$COUNT))) - warning(d$key[!is.na(d$COUNT)][1]) rv$ManualAnnotation[spe$key %in% d$key[!is.na(d$COUNT)]] <- input$label_manual_ann_gene From de731c4a181c73cb6b211529b994f48e37f5a9f6 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 18:23:58 -0400 Subject: [PATCH 099/259] Simplify code for lasso selection annotation under "Gene (interactive)" again using the reactiveValues() shortcut --- R/app_server.R | 53 +------------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 62cb54f2..af18dbb7 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1052,60 +1052,9 @@ app_server <- function(input, output, session) { event.data <- NULL } if (!is.null(event.data)) { - ## Prepare the data - d <- - as.data.frame( - cbind( - colData(spe), - SpatialExperiment::spatialCoords(spe) - )[spe$key %in% event.data$key, ], - optional = TRUE - ) - - # Grab any continuous colData columns - cont_cols <- as.matrix( - d[ - , input$geneid[input$geneid %in% colnames(d)], - drop = FALSE - ] - ) - - # Get the integer indices of each gene in the SpatialExperiment, since we - # aren't guaranteed that rownames are gene names - remaining_geneid <- input$geneid[!(input$geneid %in% colnames(d))] - valid_gene_indices <- unique( - c( - match(remaining_geneid, rowData(spe)$gene_search), - match(remaining_geneid, rownames(spe)) - ) - ) - valid_gene_indices <- valid_gene_indices[!is.na(valid_gene_indices)] - - # Grab any genes - gene_cols <- t( - as.matrix(assays(spe[valid_gene_indices, spe$key %in% event.data$key])[[input$assayname]]) - ) - - # Combine into one matrix where rows are genes and columns are continuous - # features - cont_matrix <- cbind(cont_cols, gene_cols) - - # Determine plot and legend titles - if (ncol(cont_matrix) == 1) { - d$COUNT <- as.vector(cont_matrix) - } else { - if (input$multi_gene_method == "z_score") { - d$COUNT <- multi_gene_z_score(cont_matrix) - } else if (input$multi_gene_method == "sparsity") { - d$COUNT <- multi_gene_sparsity(cont_matrix) - } else { # must be 'pca' - d$COUNT <- multi_gene_pca(cont_matrix) - } - } - d$COUNT[d$COUNT <= input$minCount] <- NA - isolate({ ## Now update with the ManualAnnotation input + d <- subset(rv$ContCount, key %in% event.data$key) rv$ManualAnnotation[spe$key %in% d$key[!is.na(d$COUNT)]] <- input$label_manual_ann_gene }) From 59529ed5fd3e434d996ff060b1f5cdc1c4a63a5d Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 18:29:19 -0400 Subject: [PATCH 100/259] Restore the default behavior of pickerInput(multiple = FALSE) that has by default selected the first value. This resolves https://github.com/LieberInstitute/spatialLIBD/issues/75#issuecomment-2023773865. Close #75 --- R/app_ui.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/app_ui.R b/R/app_ui.R index ad9d199f..e9af3215 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -111,7 +111,11 @@ app_ui <- function() { sort(rowData(spe)$gene_search) ), options = pickerOptions(liveSearch = TRUE), - multiple = TRUE + multiple = TRUE, + selected = c( + golem::get_golem_options("spe_continuous_vars"), + sort(rowData(spe)$gene_search) + )[1] ), helpText("Typically gene(s) or any other continuous variable(s)."), hr(), From 653a8f19ebf53d78035ab2e2af92a835c6ebc9fd Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 18:40:35 -0400 Subject: [PATCH 101/259] Improved the documentation of `pca`, `sparsity`, and `z_score` for the `multi_gene_method()`. Used internal documentation for these functions that @Nick-Eagles originally wrote. --- R/vis_gene.R | 9 ++++++++- inst/app/www/documentation_spe.md | 3 +++ man/vis_gene.Rd | 9 ++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index 49dec567..55bd9cf3 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -27,7 +27,14 @@ #' `viridis` argument. #' @param multi_gene_method A \code{character(1)}: either "pca", "sparsity", or #' "z_score". This parameter controls how multiple continuous variables are -#' combined for visualization, and only applies when \code{geneid} has length > 1. +#' combined for visualization, and only applies when \code{geneid} has length +#' great than 1. `z_score`: to summarize multiple continuous variables, each is +#' normalized to represent a Z-score. The multiple scores are then averaged. +#' `pca`: PCA dimension reduction is conducted on the matrix formed by the +#' continuous variables, and the first PC is then used and multiplied by -1 if +#' needed to have the majority of the values for PC1 to be positive. `sparsity`: +#' the proportion of continuous variables with positive values for each spot is +#' computed. #' #' @return A [ggplot2][ggplot2::ggplot] object. #' @export diff --git a/inst/app/www/documentation_spe.md b/inst/app/www/documentation_spe.md index 8c85e69a..78792649 100644 --- a/inst/app/www/documentation_spe.md +++ b/inst/app/www/documentation_spe.md @@ -45,6 +45,9 @@ Throughout the rest of this document, we'll refer to this object by the name `sp * `Reduced dimensions`: which reduced dimension to visualize on the `clusters (interactive)` tab. Only the first two dimensions will be shown. * `Continuous variable(s) to plot`: which gene(s) or continuous variable(s) (such as the cell count, the ratio of the mitochondrial chromosome expression) to visualize in the gene tabs as well as on the `clusters (interactive)` tab. Multiple choices may be selected, in which case "Multi-gene method" controls the method used to combine information from all selected variables. * `Multi-gene method`: when selecting more than one continuous variable, the method used to combine information from all selected variables. + * `z_score`: to summarize multiple continuous variables, each is normalized to represent a Z-score. The multiple scores are then averaged. + * `pca`: PCA dimension reduction is conducted on the matrix formed by the continuous variables, and the first PC is then used and multiplied by -1 if needed to have the majority of the values for PC1 to be positive. + * `sparsity`: the proportion of continuous variables with positive values for each spot is computed. * `Gene scale`: whether to use the raw expression values (`counts`) or the scaled and log transformed values (`logcounts`). * `Image name`: the name of the background image to use. You can edit this image on the `Edit image` tab. * `Spot transparency level`: the transparency of the spots in the visualizations. It can be useful if the spot colors are blocking the background image. diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index d7943c43..08943729 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -82,7 +82,14 @@ set to a non-\code{NA} value.} \item{multi_gene_method}{A \code{character(1)}: either "pca", "sparsity", or "z_score". This parameter controls how multiple continuous variables are -combined for visualization, and only applies when \code{geneid} has length > 1.} +combined for visualization, and only applies when \code{geneid} has length +great than 1. \code{z_score}: to summarize multiple continuous variables, each is +normalized to represent a Z-score. The multiple scores are then averaged. +\code{pca}: PCA dimension reduction is conducted on the matrix formed by the +continuous variables, and the first PC is then used and multiplied by -1 if +needed to have the majority of the values for PC1 to be positive. \code{sparsity}: +the proportion of continuous variables with positive values for each spot is +computed.} \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} From 606a6eec7cd6a8ed43e126aab51da8f404e4bf36 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 18:45:21 -0400 Subject: [PATCH 102/259] Refer users to https://research.libd.org/spatialLIBD/articles/multi_gene_plots.html --- R/vis_gene.R | 3 ++- inst/app/www/documentation_spe.md | 2 +- man/vis_gene.Rd | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index 55bd9cf3..19e39602 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -34,7 +34,8 @@ #' continuous variables, and the first PC is then used and multiplied by -1 if #' needed to have the majority of the values for PC1 to be positive. `sparsity`: #' the proportion of continuous variables with positive values for each spot is -#' computed. +#' computed. For more details, check the multi gene vignette at +#' . #' #' @return A [ggplot2][ggplot2::ggplot] object. #' @export diff --git a/inst/app/www/documentation_spe.md b/inst/app/www/documentation_spe.md index 78792649..61bc610c 100644 --- a/inst/app/www/documentation_spe.md +++ b/inst/app/www/documentation_spe.md @@ -44,7 +44,7 @@ Throughout the rest of this document, we'll refer to this object by the name `sp - described in Figure 7 from our paper (DOI: [10.1038/s41593-020-00787-0](https://doi.org/10.1038/s41593-020-00787-0)) such as `SpatialDE_PCA`, `SpatialDE_pool_PCA` and others. * `Reduced dimensions`: which reduced dimension to visualize on the `clusters (interactive)` tab. Only the first two dimensions will be shown. * `Continuous variable(s) to plot`: which gene(s) or continuous variable(s) (such as the cell count, the ratio of the mitochondrial chromosome expression) to visualize in the gene tabs as well as on the `clusters (interactive)` tab. Multiple choices may be selected, in which case "Multi-gene method" controls the method used to combine information from all selected variables. -* `Multi-gene method`: when selecting more than one continuous variable, the method used to combine information from all selected variables. +* `Multi-gene method`: when selecting more than one continuous variable, the method used to combine information from all selected variables. See [the multi gene plots vignette](https://research.libd.org/spatialLIBD/articles/multi_gene_plots.html) for more information about these methods for combining multiple continuous variables. * `z_score`: to summarize multiple continuous variables, each is normalized to represent a Z-score. The multiple scores are then averaged. * `pca`: PCA dimension reduction is conducted on the matrix formed by the continuous variables, and the first PC is then used and multiplied by -1 if needed to have the majority of the values for PC1 to be positive. * `sparsity`: the proportion of continuous variables with positive values for each spot is computed. diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index 08943729..644c8afe 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -89,7 +89,8 @@ normalized to represent a Z-score. The multiple scores are then averaged. continuous variables, and the first PC is then used and multiplied by -1 if needed to have the majority of the values for PC1 to be positive. \code{sparsity}: the proportion of continuous variables with positive values for each spot is -computed.} +computed. For more details, check the multi gene vignette at +\url{https://research.libd.org/spatialLIBD/articles/multi_gene_plots.html}.} \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} From 04068b57ef88383739a7283d4d8609e62ec48ab2 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 19:24:11 -0400 Subject: [PATCH 103/259] Greatly expand the multi-gene vignette to show some of the WM marker genes from the HumanPilot project on the subset from the spatialDLPFC data --- vignettes/multi_gene_plots.Rmd | 148 ++++++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 22 deletions(-) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index b8425459..a8435ef1 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -3,8 +3,13 @@ title: "Guide to Multi-Gene Plots" author: - name: Nicholas J. Eagles affiliation: - - Lieber Institute for Brain Development + - &libd Lieber Institute for Brain Development, Johns Hopkins Medical Campus email: nickeagles77@gmail.com + - name: Leonardo Collado-Torres + affiliation: + - *libd + - &biostats Department of Biostatistics, Johns Hopkins Bloomberg School of Public Health + email: lcolladotor@gmail.com output: BiocStyle::html_document: self_contained: yes @@ -48,6 +53,8 @@ bib <- c( sessioninfo = citation("sessioninfo")[1], SpatialExperiment = citation("SpatialExperiment")[1], spatialLIBD = citation("spatialLIBD")[1], + HumanPilot = citation("spatialLIBD")[2], + spatialDLPFC = citation("spatialLIBD")[3], tran2021 = RefManageR::BibEntry( bibtype = "Article", key = "tran2021", @@ -59,7 +66,7 @@ bib <- c( ) ``` -One of the goals of `spatialLIBD` is to provide options for visualizing Visium data. In +One of the goals of `spatialLIBD` is to provide options for visualizing Visium data by 10x Genomics. In particular, `vis_gene()` and `vis_clus()` allow plotting of individual continuous or discrete quantities belonging to each Visium spot, in a spatially accurate manner and optionally atop histology images. @@ -68,42 +75,77 @@ This vignette explores a more complex capability of `vis_gene()`: to visualize a metric of several continuous variables simultaneously. We'll start with a basic one-gene use case for `vis_gene()` before moving to more advanced cases. -# Plotting One Gene - -A typical use of [`vis_gene`](http://research.libd.org/spatialLIBD/reference/vis_gene.html) involves -plotting the spatial distribution of a single gene or continuous variable of interest. We'll -first define several genes known to be markers for white matter `r Citep(bib[['tran2021']])`. +First, let's load some example data for us to work on. This data is a subset from a recent publication with Visium data from the dorsolateral prefrontal cortex (DLPFC) `r Citep(bib[['spatialDLPFC']])`. ```{r "setup", message = FALSE, warning = FALSE} library("spatialLIBD") spe <- fetch_data(type = "spatialDLPFC_Visium_example_subset") - -white_matter_genes <- c("GFAP", "AQP4", "MBP", "PLP1") -white_matter_genes <- rowData(spe)$gene_search[ - rowData(spe)$gene_name %in% white_matter_genes -] +spe ``` -Next, we'll plot just the expression of *GFAP*. +# Plotting One Gene + +A typical use of `vis_gene()` involves +plotting the spatial distribution of a single gene or continuous variable of interest. +For example, let's plot just the expression of *GFAP*. ```{r "single_gene"} vis_gene(spe, geneid = white_matter_genes[1]) ``` +We can see a little **V** shaped section with higher expression of this gene. This seems to mark the location of layer 1. The bottom right corner seems to mark the location of white matter. + +```{r "histology_only"} +plot(imgRaster(spe)) +``` + +This particular gene is known to have high expression in both Layer 1 and white matter in the dorsolateral prefrontal cortex as can be seen below `r Citep(bib[['HumanPilot']])`. It's the 386th highest ranked white matter marker gene based on the enrichment test. + +```{r "GFAP_boxplot"} +modeling_results <- fetch_data(type = "modeling_results") +sce_layer <- fetch_data(type = "sce_layer") +sig_genes <- sig_genes_extract_all( + n = 400, + modeling_results = modeling_results, + sce_layer = sce_layer +) +i_gfap <- subset(sig_genes, gene == "GFAP" & + test == "WM")$top +i_gfap +set.seed(20200206) +layer_boxplot( + i = i_gfap, + sig_genes = sig_genes, + sce_layer = sce_layer +) +``` + # Plotting Multiple Genes -However, the `geneid` parameter to `vis_gene` may also take a vector of genes or continuous -variables in `colData(spe)`. In this way, the expression of multiple genes can be summarized -into a single value for each spot, displayed just as a single gene for `geneid` would be. +Next, let's define several genes known to be markers for white matter `r Citep(bib[['tran2021']])`. + +```{r "white_matter_genes"} +white_matter_genes <- c("GFAP", "AQP4", "MBP", "PLP1") +white_matter_genes <- rowData(spe)$gene_search[ + rowData(spe)$gene_name %in% white_matter_genes +] + +## Our list of white matter genes +white_matter_genes +``` + +As of version 1.15.2, the `geneid` parameter to `vis_gene()` may also take a vector of genes or continuous +variables in `colData(spe)`. In this way, the expression of multiple continuous variables can be summarized +into a single value for each spot, displayed just as a single input for `geneid` would be. `spatialLIBD` provides three methods for merging the information from multiple continuous -variables, which may be specified through the `multi_gene_method` parameter to `vis_gene`. +variables, which may be specified through the `multi_gene_method` parameter to `vis_gene()`. ## Averaging Z-scores -The default is `multi_gene_method = "z_score"`. Essentially, the expression for each gene is -normalized to be a Z-score. If a particular spot has a value of `1` for a particular gene, +The default is `multi_gene_method = "z_score"`. Essentially, each continuous variable (could be a mix of genes with spot-level covariates) is +normalized to be a Z-score by centering and scaling. If a particular spot has a value of `1` for a particular continuous variable, this would indicate that spot has expression one standard deviation above the mean expression -across all spots for that gene. Next, for each spot, Z-scores are averaged across genes. +across all spots for that continuous variable. Next, for each spot, Z-scores are averaged across continuous variables. Compared to simply averaging raw gene expression across genes, the `"z_score"` method is insensitive to absolute expression levels (highly expressed genes don't dominate plots), and instead focuses on how each gene varies spatially, weighting each gene equally. @@ -114,6 +156,8 @@ Let's plot all four white matter genes using this method. vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "z_score") ``` +Now the bottom right corner where the white matter is located starts to pop up more, though the mixed layer 1 and white matter signal provided by *GFAP* is still noticeable (the **V** shape). + ## Summarizing with PCA Another option is `multi_gene_method = "pca"`. A matrix is formed, where genes or continuous @@ -124,7 +168,7 @@ of the feature set. Next, its direction is reversed if the majority of coefficie is highly correlated (like our white-matter-gene example!), this optional reversal encourages higher values in the plot to represent areas of higher expression of the features. For our case, this leads to the intuitive result that "expression" is higher in white matter for white-matter -genes, which is not otherwise guaranteed (the "sign" of PCs is arbitary)! +genes, which is not otherwise guaranteed (the "sign" of PCs is arbitrary)! ```{r "multi_gene_pca"} vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "pca") @@ -139,12 +183,72 @@ of the tissue and not others. It also performs better with a larger number of ge example of four white-matter genes, the proportion may only hold values of 0, 0.25, 0.5, 0.75, and 1, which is not visually informative. -The white-matter example is thus poor due to lack of sparsity and low number of genes: +The white-matter example is thus poor due to lack of sparsity and low number of genes as you can see below. ```{r "multi_gene_sparsity"} vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "sparsity") ``` +# With more marker genes + +Below we can plot via `multi_gene_method = "z_score"` the top 25 or top 50 white matter marker genes identified via the enrichment test in a previous dataset `r Citep(bib[['HumanPilot']])`. + +```{r "multi_gene_z_score_top_enriched"} +vis_gene( + spe, + geneid = subset(sig_genes, test == "WM")$ensembl[seq_len(25)], + multi_gene_method = "z_score", + point_size = 1.5 +) + +vis_gene( + spe, + geneid = subset(sig_genes, test == "WM")$ensembl[seq_len(50)], + multi_gene_method = "z_score", + point_size = 1.5 +) +``` + +We can repeat this process for `multi_gene_method = "pca"`. + +```{r "multi_gene_pca_top_enriched"} +vis_gene( + spe, + geneid = subset(sig_genes, test == "WM")$ensembl[seq_len(25)], + multi_gene_method = "pca", + point_size = 1.5 +) + +vis_gene( + spe, + geneid = subset(sig_genes, test == "WM")$ensembl[seq_len(50)], + multi_gene_method = "pca", + point_size = 1.5 +) +``` + +And finally, lets look at the results of `multi_gene_method = "sparsity"`. + +```{r "multi_gene_sparsity_top_enriched"} +vis_gene( + spe, + geneid = subset(sig_genes, test == "WM")$ensembl[seq_len(25)], + multi_gene_method = "sparsity", + point_size = 1.5 +) + +vis_gene( + spe, + geneid = subset(sig_genes, test == "WM")$ensembl[seq_len(50)], + multi_gene_method = "sparsity", + point_size = 1.5 +) +``` + +In this case, it seems that for both the top 25 or top 50 marker genes, `z_score` and `pca` provided cleaner visualizations than `sparsity`. Give them a try on your own datasets! + + + # Reproducibility Code for creating the vignette From 567d3a452bb421907e4f30589015bc55f2fc4b67 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 19:24:46 -0400 Subject: [PATCH 104/259] v1.15.2 -- bump version and announce the new vignette contributed by @Nick-Eagles for multi-gene plots. --- DESCRIPTION | 4 ++-- NEWS.md | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c9572a82..0b5a29b9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.15.1 -Date: 2023-11-29 +Version: 1.15.2 +Date: 2024-03-27 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 72d76cb4..2da9df7f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,14 @@ +# spatialLIBD 1.15.2 + +SIGNIFICANT USER-VISIBLE CHANGES + +* `vis_gene()` now has a `multi_gene_method` argument which provides 3 methods +for combining multiple continuous variables: `z_score`, `pca`, and `sparsity`. +These options can now be used with `run_app()` (the interactive websites). These +methods are further illustrated and documented in a new vignette available at +. This +work was contributed by @Nick-Eagles. + # spatialLIBD 1.13.6 NEW FEATURES From 40763064be27caaa5b49f5d734bab0f51dce33a3 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 19:54:17 -0400 Subject: [PATCH 105/259] Fix some code order in the multi-gene vignette. Add examples of combining genes with colData()'s continuous vars as well as just showing continuous vars. --- vignettes/multi_gene_plots.Rmd | 81 +++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index a8435ef1..2c42a3cd 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -83,6 +83,18 @@ spe <- fetch_data(type = "spatialDLPFC_Visium_example_subset") spe ``` +Next, let's define several genes known to be markers for white matter `r Citep(bib[['tran2021']])`. + +```{r "white_matter_genes"} +white_matter_genes <- c("GFAP", "AQP4", "MBP", "PLP1") +white_matter_genes <- rowData(spe)$gene_search[ + rowData(spe)$gene_name %in% white_matter_genes +] + +## Our list of white matter genes +white_matter_genes +``` + # Plotting One Gene A typical use of `vis_gene()` involves @@ -90,7 +102,11 @@ plotting the spatial distribution of a single gene or continuous variable of int For example, let's plot just the expression of *GFAP*. ```{r "single_gene"} -vis_gene(spe, geneid = white_matter_genes[1]) +vis_gene( + spe, + geneid = white_matter_genes[1], + point_size = 1.5 +) ``` We can see a little **V** shaped section with higher expression of this gene. This seems to mark the location of layer 1. The bottom right corner seems to mark the location of white matter. @@ -122,18 +138,6 @@ layer_boxplot( # Plotting Multiple Genes -Next, let's define several genes known to be markers for white matter `r Citep(bib[['tran2021']])`. - -```{r "white_matter_genes"} -white_matter_genes <- c("GFAP", "AQP4", "MBP", "PLP1") -white_matter_genes <- rowData(spe)$gene_search[ - rowData(spe)$gene_name %in% white_matter_genes -] - -## Our list of white matter genes -white_matter_genes -``` - As of version 1.15.2, the `geneid` parameter to `vis_gene()` may also take a vector of genes or continuous variables in `colData(spe)`. In this way, the expression of multiple continuous variables can be summarized into a single value for each spot, displayed just as a single input for `geneid` would be. @@ -153,7 +157,12 @@ and instead focuses on how each gene varies spatially, weighting each gene equal Let's plot all four white matter genes using this method. ```{r "multi_gene_z"} -vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "z_score") +vis_gene( + spe, + geneid = white_matter_genes, + multi_gene_method = "z_score", + point_size = 1.5 +) ``` Now the bottom right corner where the white matter is located starts to pop up more, though the mixed layer 1 and white matter signal provided by *GFAP* is still noticeable (the **V** shape). @@ -171,7 +180,12 @@ this leads to the intuitive result that "expression" is higher in white matter f genes, which is not otherwise guaranteed (the "sign" of PCs is arbitrary)! ```{r "multi_gene_pca"} -vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "pca") +vis_gene( + spe, + geneid = white_matter_genes, + multi_gene_method = "pca", + point_size = 1.5 +) ``` ## Plotting Sparsity of Expression @@ -186,7 +200,12 @@ and 1, which is not visually informative. The white-matter example is thus poor due to lack of sparsity and low number of genes as you can see below. ```{r "multi_gene_sparsity"} -vis_gene(spe, geneid = white_matter_genes, multi_gene_method = "sparsity") +vis_gene( + spe, + geneid = white_matter_genes, + multi_gene_method = "sparsity", + point_size = 1.5 +) ``` # With more marker genes @@ -247,6 +266,36 @@ vis_gene( In this case, it seems that for both the top 25 or top 50 marker genes, `z_score` and `pca` provided cleaner visualizations than `sparsity`. Give them a try on your own datasets! +# Visualizing non-gene continuous variables + +So far, we have only visualized multiple genes. But these methods can be applied to several continuous variables stored in `colData(spe)` as shown below. + +```{r "colData_example"} +vis_gene( + spe, + geneid = c("sum_gene", "sum_umi"), + multi_gene_method = "z_score", + point_size = 1.5 +) +``` + +We can also combine continuous variables from `colData(spe)` along with actual genes. We can combine for example the expression of *GFAP*, which is a known astrocyte marker gene, with the spot deconvolution results for astrocytes computed using Tangram `r Citep(bib[['spatialDLPFC']])`. + +```{r "colData_plus_gene"} +vis_gene( + spe, + geneid = c("broad_tangram_astro"), + point_size = 1.5 +) +vis_gene( + spe, + geneid = c("broad_tangram_astro", white_matter_genes[1]), + multi_gene_method = "pca", + point_size = 1.5 +) +``` + +These tools enable you to further explore your data in new ways. Have fun using them! # Reproducibility From 621be76e0ce8aded4d599b029edb472bf6d86036 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 27 Mar 2024 19:55:30 -0400 Subject: [PATCH 106/259] auto-style code --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 +++-- R/annotate_registered_clusters.R | 16 ++--- R/check_sce.R | 69 +++++++++++----------- R/check_spe.R | 15 ++--- R/fetch_data.R | 41 +++++++------ R/frame_limits.R | 21 +++---- R/gene_set_enrichment.R | 11 ++-- R/gene_set_enrichment_plot.R | 23 ++++---- R/geom_spatial.R | 17 +++--- R/img_edit.R | 37 ++++++------ R/img_update.R | 13 +++-- R/img_update_all.R | 11 ++-- R/layer_boxplot.R | 27 ++++----- R/layer_matrix_plot.R | 27 ++++----- R/layer_stat_cor.R | 11 ++-- R/layer_stat_cor_plot.R | 11 ++-- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 +++---- R/registration_model.R | 7 ++- R/registration_pseudobulk.R | 13 ++--- R/registration_stats_anova.R | 17 +++--- R/registration_stats_enrichment.R | 15 +++-- R/registration_stats_pairwise.R | 15 +++-- R/registration_wrapper.R | 19 +++--- R/run_app.R | 97 ++++++++++++++++--------------- R/sig_genes_extract.R | 11 ++-- R/sig_genes_extract_all.R | 7 +-- R/vis_clus.R | 49 ++++++++-------- R/vis_clus_p.R | 25 ++++---- R/vis_gene.R | 31 +++++----- R/vis_gene_p.R | 35 +++++------ R/vis_grid_clus.R | 33 ++++++----- R/vis_grid_gene.R | 37 ++++++------ vignettes/multi_gene_plots.Rmd | 2 +- 35 files changed, 411 insertions(+), 396 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index de4f5fee..dbe49f86 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,8 +29,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function(spe, - visium_analysis) { +add10xVisiumAnalysis <- function( + spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index bfdddbe5..e7b09e5c 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,12 +43,13 @@ #' )) #' } add_images <- - function(spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function( + spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index c2a9ec43..13e1d5ab 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,9 +48,10 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function(cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function( + cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -86,10 +87,11 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function(remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function( + remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 0d17423b..1d625342 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,40 +24,41 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function(sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function( + sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index 47de3c0a..d0344daa 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,13 +25,14 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function(spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function( + spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index cc715e4a..3426ae6d 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,27 +84,26 @@ #' #> 172.28 MB #' } fetch_data <- - function( - type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function(type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index b22b5c8a..320cc643 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,16 +37,17 @@ #' } #' frame_limits <- - function(spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function( + spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index 1accea28..e6b6a63d 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,11 +58,12 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function(gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function( + gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index 4ccbfcbc..c155e672 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,17 +84,18 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function(enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function( + enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 64f00cc3..965db758 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,14 +58,15 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function(mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function( + mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index ec6fae90..93aceee3 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,24 +58,25 @@ #' plot(x) #' } img_edit <- - function(spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function( + spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index db6dfcb1..fdfe5b83 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,12 +41,13 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function(spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 31c368c9..314b9b0d 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,11 +22,12 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function(spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 345d5499..6a671a5e 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,19 +114,20 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function(i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function( + i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index f1530fb1..4a44fd18 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,19 +55,20 @@ #' cex = 2 #' ) layer_matrix_plot <- - function(matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function( + matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index 0ccf0bf2..f484c912 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,11 +49,12 @@ #' top_n = 10 #' )) layer_stat_cor <- - function(stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function( + stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index c0f4e924..0d2653b8 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,11 +72,12 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function(cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function( + cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index ef76f1d0..70bc49ac 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,9 +24,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 501a744d..d9f31fc2 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,16 +44,17 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 3f36260c..6921dbb9 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,9 +24,10 @@ #' head(registration_mod) #' registration_model <- - function(sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function( + sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 5f3c5dd2..2d859e4e 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,13 +51,12 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index c899459d..d1d0b135 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,14 +50,15 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index d186547e..cd3ee182 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,14 +34,13 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index afb9771a..09bb3ff9 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,14 +32,13 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function( - sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 49896d78..38a1c297 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,16 +50,15 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index b7beae48..93701444 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -186,54 +186,55 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function(spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - ...) { +run_app <- function( + spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index b21902c1..fac5f65b 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,12 +59,11 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index d2c3c01f..0d68b880 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,10 +27,9 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index fb95c390..5e1cfc1a 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -93,31 +93,30 @@ #' ) #' print(p4) #' } -vis_clus <- function( - spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { +vis_clus <- function(spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { # Verify existence and legitimacy of 'sampleid' if ( !("sample_id" %in% colnames(colData(spe))) || diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index a91ce369..d2b37cec 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,18 +42,19 @@ #' rm(spe_sub) #' } vis_clus_p <- - function(spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function( + spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 19e39602..d28b128f 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -158,22 +158,21 @@ #' print(p8) #' } vis_gene <- - function( - spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - ...) { + function(spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' if ( diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index e659d477..9bc3dc0a 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,23 +48,24 @@ #' rm(spe_sub) #' } vis_gene_p <- - function(spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function( + spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 40ead6b3..8c81ace6 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,22 +47,23 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function(spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index e21b5bf1..2504cce5 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,24 +35,25 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function(spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index 2c42a3cd..f19e1bc5 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -126,7 +126,7 @@ sig_genes <- sig_genes_extract_all( sce_layer = sce_layer ) i_gfap <- subset(sig_genes, gene == "GFAP" & - test == "WM")$top + test == "WM")$top i_gfap set.seed(20200206) layer_boxplot( From d38e1e0f668a1177062e6efeaeeee5d0f2872abc Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 28 Mar 2024 10:47:29 -0400 Subject: [PATCH 107/259] Make the z-score multi-gene method more robust against NA values, and put the checks inside 'multi_gene_z_score' instead of 'vis_gene' to make things more robust to direct calls to 'multi_gene_z_score' (as done in the Shiny app, for example) --- R/multi_gene_z_score.R | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R index 38e8e33f..192fb9af 100644 --- a/R/multi_gene_z_score.R +++ b/R/multi_gene_z_score.R @@ -14,9 +14,26 @@ #' @family functions for summarizing expression of multiple continuous variables simultaneously #' @keywords internal multi_gene_z_score <- function(cont_mat) { + # Z-score calculation requires at least 2 features with nonzero variance. + # Verify this and drop any zero-variance features + good_indices <- which(colSds(cont_mat, na.rm = TRUE) != 0) + if (length(good_indices) < 2) { + stop("After dropping features with no expression variation, less than 2 features were left") + } + if (ncol(cont_mat) - length(good_indices) > 0) { + warning( + sprintf( + "Dropping features(s) '%s' which have no expression variation", + paste(colnames(cont_mat)[-good_indices], collapse = "', '") + ) + ) + } + cont_mat = cont_mat[, good_indices] + # For each spot, average Z-scores across all features - cont_z <- (cont_mat - colMeans(cont_mat)) / colSds(cont_mat) - z_vec <- rowMeans(cont_z, na.rm = TRUE) + cont_z <- (cont_mat - colMeans(cont_mat, na.rm = TRUE)) / + colSds(cont_mat, na.rm = TRUE) + z_vec <- rowMeans(cont_z) return(z_vec) } From 8f6fcdb008b9ff323115da3e6add0ae5b9a57276 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 28 Mar 2024 13:10:36 -0400 Subject: [PATCH 108/259] Make 'multi_gene_pca' robust to NAs and move a check from 'vis_gene' --- R/multi_gene_pca.R | 19 +++++++++++++++++++ R/vis_gene.R | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/R/multi_gene_pca.R b/R/multi_gene_pca.R index dedd496c..f33a8b22 100644 --- a/R/multi_gene_pca.R +++ b/R/multi_gene_pca.R @@ -18,6 +18,25 @@ #' @family functions for summarizing expression of multiple continuous variables simultaneously #' @keywords internal multi_gene_pca <- function(cont_mat) { + # PCA calculation requires at least 2 features with no NAs and nonzero + # variance. Verify this and drop any bad features + good_indices <- which( + (colSums(is.na(cont_mat)) == 0) & + (colSds(cont_mat) != 0) + ) + if (length(good_indices) < 2) { + stop("After dropping features with NAs or no expression variation, less than 2 features were left") + } + if (ncol(cont_mat) - length(good_indices) > 0) { + warning( + sprintf( + "Dropping features(s) '%s' which have NAs or no expression variation", + paste(colnames(cont_mat)[-good_indices], collapse = "', '") + ) + ) + } + cont_mat = cont_mat[, good_indices] + pc_exp <- stats::prcomp(cont_mat, center = TRUE, scale = TRUE) pc_vec <- pc_exp$x[, "PC1"] diff --git a/R/vis_gene.R b/R/vis_gene.R index 59b36d61..49b64f34 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -246,25 +246,6 @@ vis_gene <- } } else { plot_title <- paste(sampleid, ...) - - # PCA and Z-score calculation requires at least 2 features with - # nonzero variance. Verify this and drop any zero-variance features - if (multi_gene_method %in% c("z_score", "pca")) { - good_indices <- which(colSds(cont_matrix) != 0) - if (length(good_indices) < 2) { - stop("After dropping features with no expression variation, less than 2 features were left") - } - if (ncol(cont_matrix) - length(good_indices) > 0) { - warning( - sprintf( - "Dropping features(s) '%s' which have no expression variation", - paste(colnames(cont_matrix)[-good_indices], collapse = "', '") - ) - ) - } - cont_matrix = cont_matrix[, good_indices] - } - if (multi_gene_method == "z_score") { d$COUNT <- multi_gene_z_score(cont_matrix) legend_title <- paste("Z score\n min > ", minCount) From 7ccd6c2b23ec973e8d9793ee76a6f1aaed2ad5eb Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 28 Mar 2024 13:23:03 -0400 Subject: [PATCH 109/259] Add a unit test for 'multi_gene_pca' to ensure it gives proper warnings and errors in edge cases --- tests/testthat/test-multi_gene_pca.R | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/testthat/test-multi_gene_pca.R diff --git a/tests/testthat/test-multi_gene_pca.R b/tests/testthat/test-multi_gene_pca.R new file mode 100644 index 00000000..ddde6afe --- /dev/null +++ b/tests/testthat/test-multi_gene_pca.R @@ -0,0 +1,30 @@ +test_that( + "multi_gene_pca", + { + # With two good columns but 1 zero-variance column, the zero-variance + # column should be dropped with a warning + cont_mat = matrix(c(1, 0, 3, 3, 2, -5), ncol = 3) + colnames(cont_mat) = c('good1', 'bad', 'good2') + expect_warning( + multi_gene_pca(cont_mat), + "Dropping features\\(s\\) 'bad' which have NAs or no expression variation" + ) + + # With two good columns but 1 zero-variance column, the zero-variance + # column should be dropped with a warning + cont_mat = matrix(c(1, NA, 3, 4, 2, -5), ncol = 3) + colnames(cont_mat) = c('bad', 'good1', 'good2') + expect_warning( + multi_gene_pca(cont_mat), + "Dropping features\\(s\\) 'bad' which have NAs or no expression variation" + ) + + # With only one good column, an error should be thrown + cont_mat = matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) + colnames(cont_mat) = c('bad1', 'good', 'bad2') + expect_error( + multi_gene_pca(cont_mat), + "After dropping features with NAs or no expression variation, less than 2 features were left" + ) + } +) From 730af197b801cac80b331ee2ec34174dfa12fc0e Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 28 Mar 2024 13:37:46 -0400 Subject: [PATCH 110/259] Add a test for proper errors, warnings, and lack of NAs in edge cases. Also fix 'multi_gene_z_score' in response to an initially failed test --- R/multi_gene_z_score.R | 2 +- tests/testthat/test-multi_gene_z_score.R | 27 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/testthat/test-multi_gene_z_score.R diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R index 192fb9af..d7e21550 100644 --- a/R/multi_gene_z_score.R +++ b/R/multi_gene_z_score.R @@ -33,7 +33,7 @@ multi_gene_z_score <- function(cont_mat) { # For each spot, average Z-scores across all features cont_z <- (cont_mat - colMeans(cont_mat, na.rm = TRUE)) / colSds(cont_mat, na.rm = TRUE) - z_vec <- rowMeans(cont_z) + z_vec <- rowMeans(cont_z, na.rm = TRUE) return(z_vec) } diff --git a/tests/testthat/test-multi_gene_z_score.R b/tests/testthat/test-multi_gene_z_score.R new file mode 100644 index 00000000..d1c69ad1 --- /dev/null +++ b/tests/testthat/test-multi_gene_z_score.R @@ -0,0 +1,27 @@ +test_that( + "multi_gene_z_score", + { + # With two good columns but 1 zero-variance column, the zero-variance + # column should be dropped with a warning + cont_mat = matrix(c(1, 0, 3, 3, 2, -5), ncol = 3) + colnames(cont_mat) = c('good1', 'bad', 'good2') + expect_warning( + multi_gene_z_score(cont_mat), + "Dropping features\\(s\\) 'bad' which have no expression variation" + ) + + # NAs should be correctly removed from columns (as long as 2 non-NAs remain + # in at least 2 columns), and the result should have no NAs + cont_mat = matrix(c(1, NA, 3, NA, 2, 0), ncol = 2) + colnames(cont_mat) = c('good1', 'good2') + expect_equal(any(is.na(multi_gene_z_score(cont_mat))), FALSE) + + # With only one good column, an error should be thrown + cont_mat = matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) + colnames(cont_mat) = c('bad1', 'good', 'bad2') + expect_error( + multi_gene_z_score(cont_mat), + "After dropping features with no expression variation, less than 2 features were left" + ) + } +) From 0cace3e06f598475fafd4cb7ec4058c47581de18 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 28 Mar 2024 13:39:17 -0400 Subject: [PATCH 111/259] Make 'multi_gene_sparsity' robust to NAs --- R/multi_gene_sparsity.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/multi_gene_sparsity.R b/R/multi_gene_sparsity.R index 45e3d4ce..4f53290b 100644 --- a/R/multi_gene_sparsity.R +++ b/R/multi_gene_sparsity.R @@ -14,5 +14,5 @@ #' @family functions for summarizing expression of multiple continuous variables simultaneously #' @keywords internal multi_gene_sparsity <- function(cont_mat) { - return(rowMeans(cont_mat > 0)) + return(rowMeans(cont_mat > 0, na.rm = TRUE)) } From 3948cf23be758a977b4c6f74578b9437894373ea Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 5 Apr 2024 15:21:44 -0400 Subject: [PATCH 112/259] Use call. = FALSE in stop() and warning() Co-authored-by: Nick Eagles --- R/multi_gene_pca.R | 5 +++-- R/multi_gene_z_score.R | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/R/multi_gene_pca.R b/R/multi_gene_pca.R index f33a8b22..886e89d5 100644 --- a/R/multi_gene_pca.R +++ b/R/multi_gene_pca.R @@ -25,14 +25,15 @@ multi_gene_pca <- function(cont_mat) { (colSds(cont_mat) != 0) ) if (length(good_indices) < 2) { - stop("After dropping features with NAs or no expression variation, less than 2 features were left") + stop("After dropping features with NAs or no expression variation, less than 2 features were left. This error can occur when using data from only 1 spot.", call. = FALSE) } if (ncol(cont_mat) - length(good_indices) > 0) { warning( sprintf( "Dropping features(s) '%s' which have NAs or no expression variation", paste(colnames(cont_mat)[-good_indices], collapse = "', '") - ) + ), + call. = FALSE ) } cont_mat = cont_mat[, good_indices] diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R index d7e21550..72d5e187 100644 --- a/R/multi_gene_z_score.R +++ b/R/multi_gene_z_score.R @@ -18,17 +18,18 @@ multi_gene_z_score <- function(cont_mat) { # Verify this and drop any zero-variance features good_indices <- which(colSds(cont_mat, na.rm = TRUE) != 0) if (length(good_indices) < 2) { - stop("After dropping features with no expression variation, less than 2 features were left") + stop("After dropping features with no expression variation, less than 2 features were left. This error can occur when using data from only 1 spot.", call. = FALSE) } if (ncol(cont_mat) - length(good_indices) > 0) { warning( sprintf( "Dropping features(s) '%s' which have no expression variation", paste(colnames(cont_mat)[-good_indices], collapse = "', '") - ) + ), + call. = FALSE ) } - cont_mat = cont_mat[, good_indices] + cont_mat = cont_mat[, good_indices, drop = FALSE] # For each spot, average Z-scores across all features cont_z <- (cont_mat - colMeans(cont_mat, na.rm = TRUE)) / From cf3d240bd3f98251e612ecfe9f248a9ee46d5b9e Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 5 Apr 2024 15:22:51 -0400 Subject: [PATCH 113/259] Auto-style code --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 ++-- R/annotate_registered_clusters.R | 16 ++-- R/check_sce.R | 69 +++++++++-------- R/check_spe.R | 15 ++-- R/fetch_data.R | 41 +++++----- R/frame_limits.R | 21 +++-- R/gene_set_enrichment.R | 11 ++- R/gene_set_enrichment_plot.R | 23 +++--- R/geom_spatial.R | 17 ++--- R/img_edit.R | 37 +++++---- R/img_update.R | 13 ++-- R/img_update_all.R | 11 ++- R/layer_boxplot.R | 27 ++++--- R/layer_matrix_plot.R | 27 ++++--- R/layer_stat_cor.R | 11 ++- R/layer_stat_cor_plot.R | 11 ++- R/multi_gene_pca.R | 4 +- R/multi_gene_z_score.R | 2 +- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 +++-- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 ++-- R/registration_stats_anova.R | 17 ++--- R/registration_stats_enrichment.R | 15 ++-- R/registration_stats_pairwise.R | 15 ++-- R/registration_wrapper.R | 19 ++--- R/run_app.R | 97 ++++++++++++------------ R/sig_genes_extract.R | 11 +-- R/sig_genes_extract_all.R | 7 +- R/vis_clus.R | 49 ++++++------ R/vis_clus_p.R | 25 +++--- R/vis_gene.R | 31 ++++---- R/vis_gene_p.R | 35 +++++---- R/vis_grid_clus.R | 33 ++++---- R/vis_grid_gene.R | 37 +++++---- tests/testthat/test-multi_gene_pca.R | 12 +-- tests/testthat/test-multi_gene_z_score.R | 12 +-- 38 files changed, 410 insertions(+), 425 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index dbe49f86..de4f5fee 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,9 +29,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function( - spe, - visium_analysis) { +add10xVisiumAnalysis <- function(spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index e7b09e5c..bfdddbe5 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,13 +43,12 @@ #' )) #' } add_images <- - function( - spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function(spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index 13e1d5ab..c2a9ec43 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,10 +48,9 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function( - cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function(cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -87,11 +86,10 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function( - remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function(remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 1d625342..0d17423b 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,41 +24,40 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function( - sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function(sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index d0344daa..47de3c0a 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,14 +25,13 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function( - spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function(spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index 3426ae6d..cc715e4a 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,26 +84,27 @@ #' #> 172.28 MB #' } fetch_data <- - function(type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function( + type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index 320cc643..b22b5c8a 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,17 +37,16 @@ #' } #' frame_limits <- - function( - spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function(spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index e6b6a63d..1accea28 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,12 +58,11 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function( - gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function(gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index c155e672..4ccbfcbc 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,18 +84,17 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function( - enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function(enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 965db758..64f00cc3 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,15 +58,14 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function( - mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function(mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index 93aceee3..ec6fae90 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,25 +58,24 @@ #' plot(x) #' } img_edit <- - function( - spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function(spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index fdfe5b83..db6dfcb1 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,13 +41,12 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function( - spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 314b9b0d..31c368c9 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,12 +22,11 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function( - spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 6a671a5e..345d5499 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,20 +114,19 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function( - i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function(i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index 4a44fd18..f1530fb1 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,20 +55,19 @@ #' cex = 2 #' ) layer_matrix_plot <- - function( - matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function(matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index f484c912..0ccf0bf2 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,12 +49,11 @@ #' top_n = 10 #' )) layer_stat_cor <- - function( - stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function(stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 0d2653b8..c0f4e924 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,12 +72,11 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function( - cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function(cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/multi_gene_pca.R b/R/multi_gene_pca.R index 886e89d5..c3ec9a12 100644 --- a/R/multi_gene_pca.R +++ b/R/multi_gene_pca.R @@ -22,7 +22,7 @@ multi_gene_pca <- function(cont_mat) { # variance. Verify this and drop any bad features good_indices <- which( (colSums(is.na(cont_mat)) == 0) & - (colSds(cont_mat) != 0) + (colSds(cont_mat) != 0) ) if (length(good_indices) < 2) { stop("After dropping features with NAs or no expression variation, less than 2 features were left. This error can occur when using data from only 1 spot.", call. = FALSE) @@ -36,7 +36,7 @@ multi_gene_pca <- function(cont_mat) { call. = FALSE ) } - cont_mat = cont_mat[, good_indices] + cont_mat <- cont_mat[, good_indices] pc_exp <- stats::prcomp(cont_mat, center = TRUE, scale = TRUE) pc_vec <- pc_exp$x[, "PC1"] diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R index 72d5e187..3c6f3c1a 100644 --- a/R/multi_gene_z_score.R +++ b/R/multi_gene_z_score.R @@ -29,7 +29,7 @@ multi_gene_z_score <- function(cont_mat) { call. = FALSE ) } - cont_mat = cont_mat[, good_indices, drop = FALSE] + cont_mat <- cont_mat[, good_indices, drop = FALSE] # For each spot, average Z-scores across all features cont_z <- (cont_mat - colMeans(cont_mat, na.rm = TRUE)) / diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 70bc49ac..ef76f1d0 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,8 +24,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index d9f31fc2..501a744d 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,17 +44,16 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 6921dbb9..3f36260c 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,10 +24,9 @@ #' head(registration_mod) #' registration_model <- - function( - sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function(sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 2d859e4e..5f3c5dd2 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,12 +51,13 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index d1d0b135..c899459d 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,15 +50,14 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index cd3ee182..d186547e 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,13 +34,14 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index 09bb3ff9..afb9771a 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,13 +32,14 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function(sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 38a1c297..49896d78 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,15 +50,16 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index 93701444..b7beae48 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -186,55 +186,54 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function( - spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - ...) { +run_app <- function(spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index fac5f65b..b21902c1 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,11 +59,12 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index 0d68b880..d2c3c01f 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,9 +27,10 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index 5e1cfc1a..fb95c390 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -93,30 +93,31 @@ #' ) #' print(p4) #' } -vis_clus <- function(spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { +vis_clus <- function( + spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { # Verify existence and legitimacy of 'sampleid' if ( !("sample_id" %in% colnames(colData(spe))) || diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index d2b37cec..a91ce369 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,19 +42,18 @@ #' rm(spe_sub) #' } vis_clus_p <- - function( - spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function(spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 49b64f34..994347d7 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -158,21 +158,22 @@ #' print(p8) #' } vis_gene <- - function(spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - ...) { + function( + spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' if ( diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 9bc3dc0a..e659d477 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,24 +48,23 @@ #' rm(spe_sub) #' } vis_gene_p <- - function( - spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function(spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 8c81ace6..40ead6b3 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,23 +47,22 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function( - spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index 2504cce5..e21b5bf1 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,25 +35,24 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function( - spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/tests/testthat/test-multi_gene_pca.R b/tests/testthat/test-multi_gene_pca.R index ddde6afe..32c1d83d 100644 --- a/tests/testthat/test-multi_gene_pca.R +++ b/tests/testthat/test-multi_gene_pca.R @@ -3,8 +3,8 @@ test_that( { # With two good columns but 1 zero-variance column, the zero-variance # column should be dropped with a warning - cont_mat = matrix(c(1, 0, 3, 3, 2, -5), ncol = 3) - colnames(cont_mat) = c('good1', 'bad', 'good2') + cont_mat <- matrix(c(1, 0, 3, 3, 2, -5), ncol = 3) + colnames(cont_mat) <- c("good1", "bad", "good2") expect_warning( multi_gene_pca(cont_mat), "Dropping features\\(s\\) 'bad' which have NAs or no expression variation" @@ -12,16 +12,16 @@ test_that( # With two good columns but 1 zero-variance column, the zero-variance # column should be dropped with a warning - cont_mat = matrix(c(1, NA, 3, 4, 2, -5), ncol = 3) - colnames(cont_mat) = c('bad', 'good1', 'good2') + cont_mat <- matrix(c(1, NA, 3, 4, 2, -5), ncol = 3) + colnames(cont_mat) <- c("bad", "good1", "good2") expect_warning( multi_gene_pca(cont_mat), "Dropping features\\(s\\) 'bad' which have NAs or no expression variation" ) # With only one good column, an error should be thrown - cont_mat = matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) - colnames(cont_mat) = c('bad1', 'good', 'bad2') + cont_mat <- matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) + colnames(cont_mat) <- c("bad1", "good", "bad2") expect_error( multi_gene_pca(cont_mat), "After dropping features with NAs or no expression variation, less than 2 features were left" diff --git a/tests/testthat/test-multi_gene_z_score.R b/tests/testthat/test-multi_gene_z_score.R index d1c69ad1..cd701abb 100644 --- a/tests/testthat/test-multi_gene_z_score.R +++ b/tests/testthat/test-multi_gene_z_score.R @@ -3,8 +3,8 @@ test_that( { # With two good columns but 1 zero-variance column, the zero-variance # column should be dropped with a warning - cont_mat = matrix(c(1, 0, 3, 3, 2, -5), ncol = 3) - colnames(cont_mat) = c('good1', 'bad', 'good2') + cont_mat <- matrix(c(1, 0, 3, 3, 2, -5), ncol = 3) + colnames(cont_mat) <- c("good1", "bad", "good2") expect_warning( multi_gene_z_score(cont_mat), "Dropping features\\(s\\) 'bad' which have no expression variation" @@ -12,13 +12,13 @@ test_that( # NAs should be correctly removed from columns (as long as 2 non-NAs remain # in at least 2 columns), and the result should have no NAs - cont_mat = matrix(c(1, NA, 3, NA, 2, 0), ncol = 2) - colnames(cont_mat) = c('good1', 'good2') + cont_mat <- matrix(c(1, NA, 3, NA, 2, 0), ncol = 2) + colnames(cont_mat) <- c("good1", "good2") expect_equal(any(is.na(multi_gene_z_score(cont_mat))), FALSE) # With only one good column, an error should be thrown - cont_mat = matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) - colnames(cont_mat) = c('bad1', 'good', 'bad2') + cont_mat <- matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) + colnames(cont_mat) <- c("bad1", "good", "bad2") expect_error( multi_gene_z_score(cont_mat), "After dropping features with no expression variation, less than 2 features were left" From db1e73351f0fec26ee81997e4d0777581046fb8b Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 5 Apr 2024 15:32:26 -0400 Subject: [PATCH 114/259] Attempt to fix GHA badge --- README.Rmd | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index 27248ae7..af5e96c7 100644 --- a/README.Rmd +++ b/README.Rmd @@ -24,7 +24,7 @@ knitr::opts_chunk$set( [![Bioc last commit](https://bioconductor.org/shields/lastcommit/devel/data-experiment/spatialLIBD.svg)](http://bioconductor.org/checkResults/devel/data-experiment-LATEST/spatialLIBD/) [![Bioc dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD.svg)](https://bioconductor.org/packages/release/data-experiment/html/spatialLIBD.html#since) [![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) -[![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) +[![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) [![GitHub pulls](https://img.shields.io/github/issues-pr/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/pulls) [![DOI](https://zenodo.org/badge/225913568.svg)](https://zenodo.org/badge/latestdoi/225913568) diff --git a/README.md b/README.md index b15cfbdc..972ea836 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD. [![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) [![R build -status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) +status](https://github.com/LieberInstitute/spatialLIBD/workflows/check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) [![GitHub From d65232c1ba243f9994f578842f01e32fab9c04a8 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 5 Apr 2024 15:33:29 -0400 Subject: [PATCH 115/259] Revert "Attempt to fix GHA badge" This reverts commit db1e73351f0fec26ee81997e4d0777581046fb8b. --- README.Rmd | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index af5e96c7..27248ae7 100644 --- a/README.Rmd +++ b/README.Rmd @@ -24,7 +24,7 @@ knitr::opts_chunk$set( [![Bioc last commit](https://bioconductor.org/shields/lastcommit/devel/data-experiment/spatialLIBD.svg)](http://bioconductor.org/checkResults/devel/data-experiment-LATEST/spatialLIBD/) [![Bioc dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD.svg)](https://bioconductor.org/packages/release/data-experiment/html/spatialLIBD.html#since) [![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) -[![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) +[![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) [![GitHub pulls](https://img.shields.io/github/issues-pr/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/pulls) [![DOI](https://zenodo.org/badge/225913568.svg)](https://zenodo.org/badge/latestdoi/225913568) diff --git a/README.md b/README.md index 972ea836..b15cfbdc 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD. [![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) [![R build -status](https://github.com/LieberInstitute/spatialLIBD/workflows/check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) +status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) [![GitHub From be2bcb8690a0c11fbdc583ce3308019034b54f64 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Mon, 8 Apr 2024 10:55:51 -0400 Subject: [PATCH 116/259] Make capitalization consistent for layer names --- vignettes/multi_gene_plots.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index f19e1bc5..6a3dda43 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -115,7 +115,7 @@ We can see a little **V** shaped section with higher expression of this gene. Th plot(imgRaster(spe)) ``` -This particular gene is known to have high expression in both Layer 1 and white matter in the dorsolateral prefrontal cortex as can be seen below `r Citep(bib[['HumanPilot']])`. It's the 386th highest ranked white matter marker gene based on the enrichment test. +This particular gene is known to have high expression in both layer 1 and white matter in the dorsolateral prefrontal cortex as can be seen below `r Citep(bib[['HumanPilot']])`. It's the 386th highest ranked white matter marker gene based on the enrichment test. ```{r "GFAP_boxplot"} modeling_results <- fetch_data(type = "modeling_results") From b4d2165c1b95cbdd564cf3f3d1d58d1b2bd2ca95 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 9 Apr 2024 09:49:17 -0400 Subject: [PATCH 117/259] Add check that 'geneid' columns are numeric --- R/vis_gene.R | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index 994347d7..01119da4 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -208,13 +208,18 @@ vis_gene <- ) } - # Grab any continuous colData columns - cont_cols <- as.matrix( - colData(spe_sub)[ - , geneid[geneid %in% colnames(colData(spe_sub))], - drop = FALSE - ] - ) + # Grab any continuous colData columns and verify they're all numeric + cont_cols = colData(spe_sub)[ + , geneid[geneid %in% colnames(colData(spe_sub))], + drop = FALSE + ] + if (!all(sapply(cont_cols, class) %in% c("numeric", "integer"))) { + stop( + "'geneid' can not contain non-numeric colData columns.", + call. = FALSE + ) + } + cont_cols <- as.matrix(cont_cols) # Get the integer indices of each gene in the SpatialExperiment, since we # aren't guaranteed that rownames are gene names From 8e24b3c448c6b71809b4ed1046235839fc85e4c3 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 9 Apr 2024 09:49:41 -0400 Subject: [PATCH 118/259] Add several unit tests for vis_gene --- tests/testthat/test-vis_gene.R | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/testthat/test-vis_gene.R diff --git a/tests/testthat/test-vis_gene.R b/tests/testthat/test-vis_gene.R new file mode 100644 index 00000000..12960771 --- /dev/null +++ b/tests/testthat/test-vis_gene.R @@ -0,0 +1,50 @@ +test_that( + "vis_gene", + { + if (!exists("spe")) spe <- fetch_data("spe") + + # Non-numeric column to plot + expect_error( + { + p = vis_gene( + spe, geneid = c('sum_umi', rownames(spe)[1], 'layer_guess') + ) + }, + "'geneid' can not contain non-numeric colData columns\\." + ) + + # Bad sample ID + expect_error( + { + p = vis_gene( + spe, geneid = c('sum_umi', rownames(spe)[1]), + sampleid = "aaa" + ) + }, + "'spe\\$sample_id' must exist and contain the ID aaa" + ) + + # Bad assayname + expect_error( + { + p = vis_gene( + spe, geneid = c('sum_umi', rownames(spe)[1]), + assayname = "aaa" + ) + }, + "'aaa' is not an assay in 'spe'" + ) + + # Bad geneid + expect_error( + { p = vis_gene(spe, geneid = 'aaa') }, + "Could not find the 'geneid'\\(s\\) aaa" + ) + + # Trivially check success with legitimate input + expect_equal( + class(vis_gene(spe, geneid = c('sum_umi', rownames(spe)[1]))), + c("gg", "ggplot") + ) + } +) From 9e4c25aea3fa8320c84bd77b0d4a9d0f6f0b6212 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 9 Apr 2024 09:53:22 -0400 Subject: [PATCH 119/259] Auto-style code --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 +++-- R/annotate_registered_clusters.R | 16 ++--- R/check_sce.R | 69 +++++++++++----------- R/check_spe.R | 15 ++--- R/fetch_data.R | 41 +++++++------ R/frame_limits.R | 21 +++---- R/gene_set_enrichment.R | 11 ++-- R/gene_set_enrichment_plot.R | 23 ++++---- R/geom_spatial.R | 17 +++--- R/img_edit.R | 37 ++++++------ R/img_update.R | 13 +++-- R/img_update_all.R | 11 ++-- R/layer_boxplot.R | 27 ++++----- R/layer_matrix_plot.R | 27 ++++----- R/layer_stat_cor.R | 11 ++-- R/layer_stat_cor_plot.R | 11 ++-- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 +++---- R/registration_model.R | 7 ++- R/registration_pseudobulk.R | 13 ++--- R/registration_stats_anova.R | 17 +++--- R/registration_stats_enrichment.R | 15 +++-- R/registration_stats_pairwise.R | 15 +++-- R/registration_wrapper.R | 19 +++--- R/run_app.R | 97 ++++++++++++++++--------------- R/sig_genes_extract.R | 11 ++-- R/sig_genes_extract_all.R | 7 +-- R/vis_clus.R | 49 ++++++++-------- R/vis_clus_p.R | 25 ++++---- R/vis_gene.R | 33 +++++------ R/vis_gene_p.R | 35 +++++------ R/vis_grid_clus.R | 33 ++++++----- R/vis_grid_gene.R | 37 ++++++------ tests/testthat/test-vis_gene.R | 21 ++++--- 35 files changed, 424 insertions(+), 404 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index de4f5fee..dbe49f86 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,8 +29,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function(spe, - visium_analysis) { +add10xVisiumAnalysis <- function( + spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index bfdddbe5..e7b09e5c 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,12 +43,13 @@ #' )) #' } add_images <- - function(spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function( + spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index c2a9ec43..13e1d5ab 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,9 +48,10 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function(cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function( + cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -86,10 +87,11 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function(remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function( + remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 0d17423b..1d625342 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,40 +24,41 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function(sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function( + sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index 47de3c0a..d0344daa 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,13 +25,14 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function(spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function( + spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index cc715e4a..3426ae6d 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,27 +84,26 @@ #' #> 172.28 MB #' } fetch_data <- - function( - type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function(type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index b22b5c8a..320cc643 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,16 +37,17 @@ #' } #' frame_limits <- - function(spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function( + spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index 1accea28..e6b6a63d 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,11 +58,12 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function(gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function( + gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index 4ccbfcbc..c155e672 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,17 +84,18 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function(enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function( + enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 64f00cc3..965db758 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,14 +58,15 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function(mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function( + mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index ec6fae90..93aceee3 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,24 +58,25 @@ #' plot(x) #' } img_edit <- - function(spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function( + spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index db6dfcb1..fdfe5b83 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,12 +41,13 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function(spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 31c368c9..314b9b0d 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,11 +22,12 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function(spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 345d5499..6a671a5e 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,19 +114,20 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function(i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function( + i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index f1530fb1..4a44fd18 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,19 +55,20 @@ #' cex = 2 #' ) layer_matrix_plot <- - function(matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function( + matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index 0ccf0bf2..f484c912 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,11 +49,12 @@ #' top_n = 10 #' )) layer_stat_cor <- - function(stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function( + stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index c0f4e924..0d2653b8 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,11 +72,12 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function(cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function( + cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index ef76f1d0..70bc49ac 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,9 +24,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 501a744d..d9f31fc2 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,16 +44,17 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 3f36260c..6921dbb9 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,9 +24,10 @@ #' head(registration_mod) #' registration_model <- - function(sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function( + sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 5f3c5dd2..2d859e4e 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,13 +51,12 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index c899459d..d1d0b135 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,14 +50,15 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index d186547e..cd3ee182 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,14 +34,13 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index afb9771a..09bb3ff9 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,14 +32,13 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function( - sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 49896d78..38a1c297 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,16 +50,15 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index b7beae48..93701444 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -186,54 +186,55 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function(spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - ...) { +run_app <- function( + spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index b21902c1..fac5f65b 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,12 +59,11 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index d2c3c01f..0d68b880 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,10 +27,9 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index fb95c390..5e1cfc1a 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -93,31 +93,30 @@ #' ) #' print(p4) #' } -vis_clus <- function( - spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { +vis_clus <- function(spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { # Verify existence and legitimacy of 'sampleid' if ( !("sample_id" %in% colnames(colData(spe))) || diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index a91ce369..d2b37cec 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,18 +42,19 @@ #' rm(spe_sub) #' } vis_clus_p <- - function(spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function( + spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 01119da4..594940af 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -158,22 +158,21 @@ #' print(p8) #' } vis_gene <- - function( - spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - ...) { + function(spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' if ( @@ -209,7 +208,7 @@ vis_gene <- } # Grab any continuous colData columns and verify they're all numeric - cont_cols = colData(spe_sub)[ + cont_cols <- colData(spe_sub)[ , geneid[geneid %in% colnames(colData(spe_sub))], drop = FALSE ] diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index e659d477..9bc3dc0a 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,23 +48,24 @@ #' rm(spe_sub) #' } vis_gene_p <- - function(spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function( + spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 40ead6b3..8c81ace6 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,22 +47,23 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function(spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index e21b5bf1..2504cce5 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,24 +35,25 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function(spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function( + spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/tests/testthat/test-vis_gene.R b/tests/testthat/test-vis_gene.R index 12960771..27a8dfdd 100644 --- a/tests/testthat/test-vis_gene.R +++ b/tests/testthat/test-vis_gene.R @@ -6,8 +6,9 @@ test_that( # Non-numeric column to plot expect_error( { - p = vis_gene( - spe, geneid = c('sum_umi', rownames(spe)[1], 'layer_guess') + p <- vis_gene( + spe, + geneid = c("sum_umi", rownames(spe)[1], "layer_guess") ) }, "'geneid' can not contain non-numeric colData columns\\." @@ -16,8 +17,9 @@ test_that( # Bad sample ID expect_error( { - p = vis_gene( - spe, geneid = c('sum_umi', rownames(spe)[1]), + p <- vis_gene( + spe, + geneid = c("sum_umi", rownames(spe)[1]), sampleid = "aaa" ) }, @@ -27,8 +29,9 @@ test_that( # Bad assayname expect_error( { - p = vis_gene( - spe, geneid = c('sum_umi', rownames(spe)[1]), + p <- vis_gene( + spe, + geneid = c("sum_umi", rownames(spe)[1]), assayname = "aaa" ) }, @@ -37,13 +40,15 @@ test_that( # Bad geneid expect_error( - { p = vis_gene(spe, geneid = 'aaa') }, + { + p <- vis_gene(spe, geneid = "aaa") + }, "Could not find the 'geneid'\\(s\\) aaa" ) # Trivially check success with legitimate input expect_equal( - class(vis_gene(spe, geneid = c('sum_umi', rownames(spe)[1]))), + class(vis_gene(spe, geneid = c("sum_umi", rownames(spe)[1]))), c("gg", "ggplot") ) } From 49313b7eea189993ca5fd0d4fd124f30013120e1 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 19 Apr 2024 09:38:01 -0400 Subject: [PATCH 120/259] v1.15.3 -- bump version after Nick's latest commits --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0b5a29b9..c70880fa 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.15.2 -Date: 2024-03-27 +Version: 1.15.3 +Date: 2024-04-19 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From 77a5303f91edb7b9ffb1ce00b4193dae5d16a8a1 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 19 Apr 2024 15:17:07 -0400 Subject: [PATCH 121/259] Resolve https://github.com/LieberInstitute/Habenula_Visium/issues/5 reported by @cyntsc --- DESCRIPTION | 2 +- R/vis_grid_clus.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c70880fa..6b928419 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.15.3 +Version: 1.15.4 Date: 2024-04-19 Authors@R: c( diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 8c81ace6..74b4d3ce 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -89,7 +89,7 @@ vis_grid_clus <- if (!return_plots) { - pdf(pdf_file, height = 24, width = 36) + pdf(pdf_file, height = height, width = width) print(cowplot::plot_grid(plotlist = plots)) dev.off() return(pdf_file) From 57981f8dbd790e0efd722328366934931db4bdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Pag=C3=A8s?= Date: Tue, 30 Apr 2024 11:07:20 -0400 Subject: [PATCH 122/259] bump x.y.z version to even y prior to creation of RELEASE_3_19 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 6b928419..79e2c1d0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.15.4 +Version: 1.16.0 Date: 2024-04-19 Authors@R: c( From 09177dfaa910edd53e0b5fab31a1f98694fde790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Pag=C3=A8s?= Date: Tue, 30 Apr 2024 11:07:20 -0400 Subject: [PATCH 123/259] bump x.y.z version to odd y following creation of RELEASE_3_19 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 79e2c1d0..59d21beb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.16.0 +Version: 1.17.0 Date: 2024-04-19 Authors@R: c( From 897c9b5271f4901984bdddc1d15c561fde16017e Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 3 May 2024 15:11:11 -0400 Subject: [PATCH 124/259] Copied metrics_qc from https://github.com/LieberInstitute/spatial_NAc/blob/56c67e7c0421e6dcf71fe2db6ef2c7b62ed15e58/code/05_harmony_BayesSpace/02-compute_QC_metrics.R#L68-L128 Co-authored-by: Leonardo Collado Torres --- R/metrics_qc.R | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 R/metrics_qc.R diff --git a/R/metrics_qc.R b/R/metrics_qc.R new file mode 100644 index 00000000..367d3956 --- /dev/null +++ b/R/metrics_qc.R @@ -0,0 +1,69 @@ + +#' Quality Control for Spatial Data +#' +#' @param spe a [SpatialExperiment][SpatialExperiment::SpatialExperiment-class] +#' +#' @return +#' @export +#' +#' @examples +metrics_qc <- function(spe) { + + qc_df <- data.frame( + log2sum = log2(spe$sum_umi), + log2detected = log2(spe$sum_gene), + subsets_Mito_percent = spe$expr_chrM_ratio*100, + sample_id = spe$sample_id_original + ) + + qcfilter <- DataFrame( + low_lib_size = isOutlier(qc_df$log2sum, type = "lower", log = TRUE, batch = qc_df$sample_id), + low_n_features = isOutlier(qc_df$log2detected, type = "lower", log = TRUE, batch = qc_df$sample_id), + high_subsets_Mito_percent = isOutlier(qc_df$subsets_Mito_percent, type = "higher", batch = qc_df$sample_id) + ) + qcfilter$discard <- (qcfilter$low_lib_size | qcfilter$low_n_features) | qcfilter$high_subsets_Mito_percent + + + spe$scran_low_lib_size_low_mito <- factor(qcfilter$low_lib_size & qc_df$subsets_Mito_percent < 0.5, levels = c("TRUE", "FALSE")) + + + spe$scran_discard <- + factor(qcfilter$discard, levels = c("TRUE", "FALSE")) + spe$scran_low_lib_size <- + factor(qcfilter$low_lib_size, levels = c("TRUE", "FALSE")) + spe$scran_low_n_features <- + factor(qcfilter$low_n_features, levels = c("TRUE", "FALSE")) + spe$scran_high_subsets_Mito_percent <- + factor(qcfilter$high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) + + ## Find edge spots + spots <- data.frame( + row = spe$array_row, + col = spe$array_col, + sample_id = spe$sample_id_original + ) + + edge_spots_row <- group_by(spots, sample_id, row) %>% summarize(min_col = min(col), max_col = max(col)) + edge_spots_col <- group_by(spots, sample_id, col) %>% summarize(min_row = min(row), max_row = max(row)) + + spots <- left_join(spots, edge_spots_row) %>% left_join(edge_spots_col) + spots$edge_spots <- with(spots, row == min_row | row == max_row | col == min_col | col == max_col) + + spots$row_distance <- with(spots, pmin(abs(row - min_row), abs(row - max_row))) + spots$col_distance <- with(spots, pmin(abs(col - min_col), abs(col - max_col))) + ## spots$edge_distance <- with(spots, sqrt(row_distance^2 + col_distance^2)) + ## The above is from: + ## sqrt((x_1 - x_2)^2 + (y_1 - y_2)^2) + ## but it was wrong, here's a case the the smallest distance is on the column: + ## sqrt(0^2 + col_distance^2) = col_distance + spots$edge_distance <- with(spots, pmin(row_distance, col_distance)) + + + spe$edge_spots <- factor(spots$edge_spots, levels = c("TRUE", "FALSE")) + spe$edge_distance <- spots$edge_distance + + + spe$scran_low_lib_size_edge <- factor(qcfilter$low_lib_size & spots$edge_distance < 1, levels = c("TRUE", "FALSE")) + + return(spe) +} \ No newline at end of file From 2956125c5062d0385f3d8abc38d7856030021cc8 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 12:00:35 -0400 Subject: [PATCH 125/259] Add example, add imports, update colnames --- R/metrics_qc.R | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index 367d3956..ed11b06c 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -7,19 +7,39 @@ #' @export #' #' @examples +#' if (enough_ram()) { +#' ## Obtain the necessary data +#' if (!exists("spe")) spe <- fetch_data("spe") +#' +#' +#' vis_gene( +#' spe = spe, +#' gene= "sum_umi", +#' sampleid = "151507", +#' cont_colors = rev(viridisLite::viridis(21, option = "magma")) +#' ) +#' +#' spe_qc <- metrics_qc(spe) +#' +#' ## visulize edge spots +#' vis_clus(spe_qc, sample_id = "151507", clustervar = "edge_spots") +#' +#' } +#' #' +#' @importFrom dplyr group_by summarize left_join metrics_qc <- function(spe) { qc_df <- data.frame( log2sum = log2(spe$sum_umi), log2detected = log2(spe$sum_gene), subsets_Mito_percent = spe$expr_chrM_ratio*100, - sample_id = spe$sample_id_original + sample_id = spe$sample_id ) qcfilter <- DataFrame( - low_lib_size = isOutlier(qc_df$log2sum, type = "lower", log = TRUE, batch = qc_df$sample_id), - low_n_features = isOutlier(qc_df$log2detected, type = "lower", log = TRUE, batch = qc_df$sample_id), - high_subsets_Mito_percent = isOutlier(qc_df$subsets_Mito_percent, type = "higher", batch = qc_df$sample_id) + low_lib_size = scater::isOutlier(qc_df$log2sum, type = "lower", log = TRUE, batch = qc_df$sample_id), + low_n_features = scater::isOutlier(qc_df$log2detected, type = "lower", log = TRUE, batch = qc_df$sample_id), + high_subsets_Mito_percent = scater::isOutlier(qc_df$subsets_Mito_percent, type = "higher", batch = qc_df$sample_id) ) qcfilter$discard <- (qcfilter$low_lib_size | qcfilter$low_n_features) | qcfilter$high_subsets_Mito_percent @@ -29,10 +49,13 @@ metrics_qc <- function(spe) { spe$scran_discard <- factor(qcfilter$discard, levels = c("TRUE", "FALSE")) + spe$scran_low_lib_size <- factor(qcfilter$low_lib_size, levels = c("TRUE", "FALSE")) + spe$scran_low_n_features <- factor(qcfilter$low_n_features, levels = c("TRUE", "FALSE")) + spe$scran_high_subsets_Mito_percent <- factor(qcfilter$high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) @@ -40,13 +63,13 @@ metrics_qc <- function(spe) { spots <- data.frame( row = spe$array_row, col = spe$array_col, - sample_id = spe$sample_id_original + sample_id = spe$sample_id ) - edge_spots_row <- group_by(spots, sample_id, row) %>% summarize(min_col = min(col), max_col = max(col)) - edge_spots_col <- group_by(spots, sample_id, col) %>% summarize(min_row = min(row), max_row = max(row)) + edge_spots_row <- group_by(spots, sample_id, row) |> dplyr::summarize(min_col = min(col), max_col = max(col)) + edge_spots_col <- group_by(spots, sample_id, col) |> dplyr::summarize(min_row = min(row), max_row = max(row)) - spots <- left_join(spots, edge_spots_row) %>% left_join(edge_spots_col) + spots <- dplyr::left_join(spots, edge_spots_row) |> dplyr::left_join(edge_spots_col) spots$edge_spots <- with(spots, row == min_row | row == max_row | col == min_col | col == max_col) spots$row_distance <- with(spots, pmin(abs(row - min_row), abs(row - max_row))) From c81f0ba1804092f2bf164fecb0ad5d47944f8eb0 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 13:18:18 -0400 Subject: [PATCH 126/259] Add more examples, use tidy style tools to find edge spots + edge distance --- R/metrics_qc.R | 92 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 32 deletions(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index ed11b06c..75480efd 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -12,17 +12,25 @@ #' if (!exists("spe")) spe <- fetch_data("spe") #' #' -#' vis_gene( -#' spe = spe, -#' gene= "sum_umi", -#' sampleid = "151507", -#' cont_colors = rev(viridisLite::viridis(21, option = "magma")) -#' ) -#' +#' ## adds QC metrics to colData of the spe #' spe_qc <- metrics_qc(spe) +#' colData(spe_qc) +#' +#' table(spe_qc$edge_spot, spe_qc$scran_low_lib_size_edge) +#' +#' ## visualize edge spots +#' vis_clus(spe_qc, sample_id = "151507", clustervar = "edge_spot") +#' vis_gene(spe_qc, sample_id = "151507", geneid = "edge_distance", minCount = -1) +#' +#' ## visualize scran QC flags #' -#' ## visulize edge spots -#' vis_clus(spe_qc, sample_id = "151507", clustervar = "edge_spots") +#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") +#' +#' scater::plotColData(spe_qc, x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") +#' +#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_n_features") +#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_discard") +#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size_edge") #' #' } #' #' @@ -36,17 +44,14 @@ metrics_qc <- function(spe) { sample_id = spe$sample_id ) - qcfilter <- DataFrame( + qcfilter <- data.frame( low_lib_size = scater::isOutlier(qc_df$log2sum, type = "lower", log = TRUE, batch = qc_df$sample_id), low_n_features = scater::isOutlier(qc_df$log2detected, type = "lower", log = TRUE, batch = qc_df$sample_id), high_subsets_Mito_percent = scater::isOutlier(qc_df$subsets_Mito_percent, type = "higher", batch = qc_df$sample_id) - ) - qcfilter$discard <- (qcfilter$low_lib_size | qcfilter$low_n_features) | qcfilter$high_subsets_Mito_percent - - - spe$scran_low_lib_size_low_mito <- factor(qcfilter$low_lib_size & qc_df$subsets_Mito_percent < 0.5, levels = c("TRUE", "FALSE")) + ) |> mutate(discard = (low_lib_size | low_n_features) | high_subsets_Mito_percent) + ## Add qcfilter cols to colData(spe) after factoring spe$scran_discard <- factor(qcfilter$discard, levels = c("TRUE", "FALSE")) @@ -59,34 +64,57 @@ metrics_qc <- function(spe) { spe$scran_high_subsets_Mito_percent <- factor(qcfilter$high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) - ## Find edge spots - spots <- data.frame( - row = spe$array_row, - col = spe$array_col, - sample_id = spe$sample_id - ) + spe$scran_low_lib_size_low_mito <- + factor(qcfilter$low_lib_size & + qc_df$subsets_Mito_percent < 0.5, levels = c("TRUE", "FALSE")) - edge_spots_row <- group_by(spots, sample_id, row) |> dplyr::summarize(min_col = min(col), max_col = max(col)) - edge_spots_col <- group_by(spots, sample_id, col) |> dplyr::summarize(min_row = min(row), max_row = max(row)) - - spots <- dplyr::left_join(spots, edge_spots_row) |> dplyr::left_join(edge_spots_col) - spots$edge_spots <- with(spots, row == min_row | row == max_row | col == min_col | col == max_col) + ## Find edge spots - spots$row_distance <- with(spots, pmin(abs(row - min_row), abs(row - max_row))) - spots$col_distance <- with(spots, pmin(abs(col - min_col), abs(col - max_col))) + ## Find edge spots + spot_coords <- colData(spe) |> + as.data.frame() |> + select(sample_id, array_row, array_col) |> + group_by(sample_id, array_row) |> + mutate(edge_col = array_col == min(array_col) | array_col == max(array_col), + col_distance = pmin(abs(array_col - min(array_col)), + abs(array_col - max(array_col))) + ) |> + group_by(sample_id, array_col) |> + mutate(edge_row = array_row == min(array_row) | array_row == max(array_row), + row_distance = pmin(abs(array_row - min(array_row)), + abs(array_row - max(array_row))) + ) |> + group_by(sample_id) |> + mutate(edge_spot = edge_row | edge_col, + edge_distance = pmin(row_distance, col_distance)) + + # spots <- data.frame( + # row = spe$array_row, + # col = spe$array_col, + # sample_id = spe$sample_id + # ) + + # edge_spots_row <- group_by(spots, sample_id, row) |> dplyr::summarize(min_col = min(col), max_col = max(col)) + # edge_spots_col <- group_by(spots, sample_id, col) |> dplyr::summarize(min_row = min(row), max_row = max(row)) + # + # spots <- dplyr::left_join(spots, edge_spots_row) |> dplyr::left_join(edge_spots_col) + # spots$edge_spots <- with(spots, row == min_row | row == max_row | col == min_col | col == max_col) + # + # spots$row_distance <- with(spots, pmin(abs(row - min_row), abs(row - max_row))) + # spots$col_distance <- with(spots, pmin(abs(col - min_col), abs(col - max_col))) ## spots$edge_distance <- with(spots, sqrt(row_distance^2 + col_distance^2)) ## The above is from: ## sqrt((x_1 - x_2)^2 + (y_1 - y_2)^2) ## but it was wrong, here's a case the the smallest distance is on the column: ## sqrt(0^2 + col_distance^2) = col_distance - spots$edge_distance <- with(spots, pmin(row_distance, col_distance)) + # spots$edge_distance <- with(spots, pmin(row_distance, col_distance)) - spe$edge_spots <- factor(spots$edge_spots, levels = c("TRUE", "FALSE")) - spe$edge_distance <- spots$edge_distance + spe$edge_spot <- factor(spot_coords$edge_spot,levels = c("TRUE", "FALSE")) + spe$edge_distance <- spot_coords$edge_distance - spe$scran_low_lib_size_edge <- factor(qcfilter$low_lib_size & spots$edge_distance < 1, levels = c("TRUE", "FALSE")) + spe$scran_low_lib_size_edge <- factor(qcfilter$low_lib_size & spot_coords$edge_spot, levels = c("TRUE", "FALSE")) return(spe) } \ No newline at end of file From de0ba4d36b78aa947ecd5065d1299730f8b87cd4 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 13:20:04 -0400 Subject: [PATCH 127/259] Clean up comments & old code --- R/metrics_qc.R | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index 75480efd..611ee874 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -68,8 +68,6 @@ metrics_qc <- function(spe) { factor(qcfilter$low_lib_size & qc_df$subsets_Mito_percent < 0.5, levels = c("TRUE", "FALSE")) - ## Find edge spots - ## Find edge spots spot_coords <- colData(spe) |> as.data.frame() |> @@ -88,28 +86,8 @@ metrics_qc <- function(spe) { mutate(edge_spot = edge_row | edge_col, edge_distance = pmin(row_distance, col_distance)) - # spots <- data.frame( - # row = spe$array_row, - # col = spe$array_col, - # sample_id = spe$sample_id - # ) - - # edge_spots_row <- group_by(spots, sample_id, row) |> dplyr::summarize(min_col = min(col), max_col = max(col)) - # edge_spots_col <- group_by(spots, sample_id, col) |> dplyr::summarize(min_row = min(row), max_row = max(row)) - # - # spots <- dplyr::left_join(spots, edge_spots_row) |> dplyr::left_join(edge_spots_col) - # spots$edge_spots <- with(spots, row == min_row | row == max_row | col == min_col | col == max_col) - # - # spots$row_distance <- with(spots, pmin(abs(row - min_row), abs(row - max_row))) - # spots$col_distance <- with(spots, pmin(abs(col - min_col), abs(col - max_col))) - ## spots$edge_distance <- with(spots, sqrt(row_distance^2 + col_distance^2)) - ## The above is from: - ## sqrt((x_1 - x_2)^2 + (y_1 - y_2)^2) - ## but it was wrong, here's a case the the smallest distance is on the column: - ## sqrt(0^2 + col_distance^2) = col_distance - # spots$edge_distance <- with(spots, pmin(row_distance, col_distance)) - + ## Add Edge info to spe spe$edge_spot <- factor(spot_coords$edge_spot,levels = c("TRUE", "FALSE")) spe$edge_distance <- spot_coords$edge_distance From 1d60d58f6db024eebd734877adc9c56f8724f493 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 15:48:14 -0400 Subject: [PATCH 128/259] Improve metrics_qc() docs --- NAMESPACE | 1 + R/metrics_qc.R | 34 ++++++++++++++++++---------- man/metrics_qc.Rd | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 man/metrics_qc.Rd diff --git a/NAMESPACE b/NAMESPACE index d18236fa..ef0d5c1c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,6 +25,7 @@ export(layer_matrix_plot) export(layer_stat_cor) export(layer_stat_cor_plot) export(locate_images) +export(metrics_qc) export(read10xVisiumAnalysis) export(read10xVisiumWrapper) export(registration_block_cor) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index 611ee874..ce3de929 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -1,9 +1,17 @@ #' Quality Control for Spatial Data #' +#' This function identify spots in a +#' [SpatialExperiment-class][SpatialExperiment::SpatialExperiment-class] (SPE) +#' with outlier quality control values: low `sum_umi` or `sum_gene`, or high +#' `expr_chrM_ratio`, utilizing `scran::isOutlier()`. Also identifies in-tissue +#' edge spots and distance to the edge for each spot. +#' #' @param spe a [SpatialExperiment][SpatialExperiment::SpatialExperiment-class] #' -#' @return +#' @return A [SpatialExperiment][SpatialExperiment::SpatialExperiment-class] +#' with added quiality control information added to the colData. +#' #' @export #' #' @examples @@ -11,16 +19,18 @@ #' ## Obtain the necessary data #' if (!exists("spe")) spe <- fetch_data("spe") #' +#' ## fake out tissue spots in example data (TODO add pre-qc data) +#' spe_qc <- spe +#' spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE #' #' ## adds QC metrics to colData of the spe #' spe_qc <- metrics_qc(spe) #' colData(spe_qc) -#' -#' table(spe_qc$edge_spot, spe_qc$scran_low_lib_size_edge) -#' +#' #' ## visualize edge spots -#' vis_clus(spe_qc, sample_id = "151507", clustervar = "edge_spot") -#' vis_gene(spe_qc, sample_id = "151507", geneid = "edge_distance", minCount = -1) +#' vis_clus(spe_qc, sampleid = "151509", clustervar = "edge_spot") +#' vis_clus(spe_qc, sampleid = "151509", clustervar = "in_tissue") +#' vis_gene(spe_qc, sampleid = "151509", geneid = "edge_distance", minCount = -1) #' #' ## visualize scran QC flags #' @@ -28,15 +38,17 @@ #' #' scater::plotColData(spe_qc, x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") #' -#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_n_features") -#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_discard") -#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size_edge") +#' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_n_features") +#' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") +#' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") #' #' } #' #' -#' @importFrom dplyr group_by summarize left_join +#' @importFrom dplyr group_by summarize left_join select mutate +#' @importFrom SummarizedExperiment colData +#' @importFrom scater isOutlier metrics_qc <- function(spe) { - + qc_df <- data.frame( log2sum = log2(spe$sum_umi), log2detected = log2(spe$sum_gene), diff --git a/man/metrics_qc.Rd b/man/metrics_qc.Rd new file mode 100644 index 00000000..fc967f68 --- /dev/null +++ b/man/metrics_qc.Rd @@ -0,0 +1,56 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/metrics_qc.R +\name{metrics_qc} +\alias{metrics_qc} +\title{Quality Control for Spatial Data} +\usage{ +metrics_qc(spe) +} +\arguments{ +\item{spe}{a \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment}} +} +\value{ +A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment} +with added quiality control information added to the colData. +} +\description{ +This function identify spots in a +\link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} (SPE) +with outlier quality control values: low \code{sum_umi} or \code{sum_gene}, or high +\code{expr_chrM_ratio}, utilizing \code{scran::isOutlier()}. Also identifies in-tissue +edge spots and distance to the edge for each spot. +} +\examples{ + if (enough_ram()) { + ## Obtain the necessary data + if (!exists("spe")) spe <- fetch_data("spe") + + ## fake out tissue spots in example data (TODO add pre-qc data) + spe_qc <- spe + spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE + + ## adds QC metrics to colData of the spe + spe_qc <- metrics_qc(spe) + colData(spe_qc) + + ## visualize edge spots + vis_clus(spe_qc, sampleid = "151509", clustervar = "edge_spot") + vis_clus(spe_qc, sampleid = "151509", clustervar = "in_tissue") + vis_gene(spe_qc, sampleid = "151509", geneid = "edge_distance", minCount = -1) + + ## visualize scran QC flags + + vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") + + scater::plotColData(spe_qc, x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") + + vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_n_features") + vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") + vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") + + } + #' + @importFrom dplyr group_by summarize left_join select mutate + @importFrom SummarizedExperiment colData + @importFrom scater isOutlier +} From bab83f0e76438d868aa06038f49ff890d9b5dead Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 16:52:18 -0400 Subject: [PATCH 129/259] Add handling for in_tissue/out_tissue spots --- R/metrics_qc.R | 76 ++++++++++++++++++++++++++++------------------- man/metrics_qc.Rd | 10 +++---- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index ce3de929..b9b44754 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -24,21 +24,19 @@ #' spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE #' #' ## adds QC metrics to colData of the spe -#' spe_qc <- metrics_qc(spe) +#' spe_qc <- metrics_qc(spe_qc) #' colData(spe_qc) #' #' ## visualize edge spots -#' vis_clus(spe_qc, sampleid = "151509", clustervar = "edge_spot") -#' vis_clus(spe_qc, sampleid = "151509", clustervar = "in_tissue") -#' vis_gene(spe_qc, sampleid = "151509", geneid = "edge_distance", minCount = -1) +#' vis_clus(spe_qc, sampleid = "151507", clustervar = "edge_spot") +#' vis_gene(spe_qc, sampleid = "151507", geneid = "edge_distance", minCount = -1) #' #' ## visualize scran QC flags #' #' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") #' -#' scater::plotColData(spe_qc, x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") +#' scater::plotColData(spe_qc[,spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") #' -#' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_n_features") #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") #' @@ -48,42 +46,53 @@ #' @importFrom SummarizedExperiment colData #' @importFrom scater isOutlier metrics_qc <- function(spe) { - + + # spe_out <- spe[, !spe$in_tissue] + spe_in <- spe[, spe$in_tissue] + + ## QC in-tissue spots qc_df <- data.frame( - log2sum = log2(spe$sum_umi), - log2detected = log2(spe$sum_gene), - subsets_Mito_percent = spe$expr_chrM_ratio*100, - sample_id = spe$sample_id + log2sum = log2(spe_in$sum_umi), + log2detected = log2(spe_in$sum_gene), + subsets_Mito_percent = spe_in$expr_chrM_ratio*100, + sample_id = spe_in$sample_id ) qcfilter <- data.frame( low_lib_size = scater::isOutlier(qc_df$log2sum, type = "lower", log = TRUE, batch = qc_df$sample_id), low_n_features = scater::isOutlier(qc_df$log2detected, type = "lower", log = TRUE, batch = qc_df$sample_id), high_subsets_Mito_percent = scater::isOutlier(qc_df$subsets_Mito_percent, type = "higher", batch = qc_df$sample_id) - ) |> mutate(discard = (low_lib_size | low_n_features) | high_subsets_Mito_percent) - + ) |> + dplyr::mutate(discard = (low_lib_size | low_n_features) | high_subsets_Mito_percent) ## Add qcfilter cols to colData(spe) after factoring - spe$scran_discard <- - factor(qcfilter$discard, levels = c("TRUE", "FALSE")) - - spe$scran_low_lib_size <- - factor(qcfilter$low_lib_size, levels = c("TRUE", "FALSE")) - - spe$scran_low_n_features <- - factor(qcfilter$low_n_features, levels = c("TRUE", "FALSE")) + ## discard + spe$scran_discard <- NA + spe$scran_discard[which(spe$in_tissue)] <- qcfilter$discard + spe$scran_discard <- factor(spe$scran_discard, levels = c("TRUE", "FALSE")) - spe$scran_high_subsets_Mito_percent <- - factor(qcfilter$high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) + ## low_lib_size + spe$scran_low_lib_size <- NA + spe$scran_low_lib_size[which(spe$in_tissue)] <- qcfilter$low_lib_size + spe$scran_low_lib_size <- factor(spe$scran_low_lib_size, + levels = c("TRUE", "FALSE")) + ## low_n_features + spe$scran_low_n_features <- NA + spe$scran_low_n_features[which(spe$in_tissue)] <- qcfilter$low_n_features + spe$sscran_low_n_features<- factor(spe$scran_low_n_features, + levels = c("TRUE", "FALSE")) - spe$scran_low_lib_size_low_mito <- - factor(qcfilter$low_lib_size & - qc_df$subsets_Mito_percent < 0.5, levels = c("TRUE", "FALSE")) + ## high mito percent + spe$scran_high_subsets_Mito_percent <- NA + spe$scran_high_subsets_Mito_percent[which(spe$in_tissue)] <- + qcfilter$high_subsets_Mito_percent + spe$scran_high_subsets_Mito_percent <- + factor(spe$scran_high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) ## Find edge spots - spot_coords <- colData(spe) |> + spot_coords <- colData(spe_in) |> as.data.frame() |> - select(sample_id, array_row, array_col) |> + select(in_tissue, sample_id, array_row, array_col) |> group_by(sample_id, array_row) |> mutate(edge_col = array_col == min(array_col) | array_col == max(array_col), col_distance = pmin(abs(array_col - min(array_col)), @@ -100,11 +109,16 @@ metrics_qc <- function(spe) { ## Add Edge info to spe - spe$edge_spot <- factor(spot_coords$edge_spot,levels = c("TRUE", "FALSE")) - spe$edge_distance <- spot_coords$edge_distance + spe$edge_spot <- NA + spe$edge_spot[which(spe$in_tissue)] <- spot_coords$edge_spot + spe$edge_spot <- factor(spe$edge_spot, levels = c("TRUE", "FALSE")) + spe$edge_distance <- NA + spe$edge_distance[which(spe$in_tissue)] <- spot_coords$edge_distance - spe$scran_low_lib_size_edge <- factor(qcfilter$low_lib_size & spot_coords$edge_spot, levels = c("TRUE", "FALSE")) + spe$scran_low_lib_size_edge <- NA + spe$scran_low_lib_size_edge[which(spe$in_tissue)] <- qcfilter$low_lib_size & spot_coords$edge_spot + spe$scran_low_lib_size_edge <- factor(spe$scran_low_lib_size_edge, levels = c("TRUE", "FALSE")) return(spe) } \ No newline at end of file diff --git a/man/metrics_qc.Rd b/man/metrics_qc.Rd index fc967f68..76ff25a4 100644 --- a/man/metrics_qc.Rd +++ b/man/metrics_qc.Rd @@ -30,21 +30,19 @@ edge spots and distance to the edge for each spot. spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE ## adds QC metrics to colData of the spe - spe_qc <- metrics_qc(spe) + spe_qc <- metrics_qc(spe_qc) colData(spe_qc) ## visualize edge spots - vis_clus(spe_qc, sampleid = "151509", clustervar = "edge_spot") - vis_clus(spe_qc, sampleid = "151509", clustervar = "in_tissue") - vis_gene(spe_qc, sampleid = "151509", geneid = "edge_distance", minCount = -1) + vis_clus(spe_qc, sampleid = "151507", clustervar = "edge_spot") + vis_gene(spe_qc, sampleid = "151507", geneid = "edge_distance", minCount = -1) ## visualize scran QC flags vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") - scater::plotColData(spe_qc, x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") + scater::plotColData(spe_qc[,spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") - vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_n_features") vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") From 2b57c5b7cd0e7ac759bfdcb7957b7d0756d2b434 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 17:08:09 -0400 Subject: [PATCH 130/259] Add checks for key columns --- R/metrics_qc.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index b9b44754..0413bfc5 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -47,7 +47,11 @@ #' @importFrom scater isOutlier metrics_qc <- function(spe) { - # spe_out <- spe[, !spe$in_tissue] + stopifnot("in_tissue" %in% colnames(colData(spe))) + stopifnot("sum_umi" %in% colnames(colData(spe))) + stopifnot("sum_gene" %in% colnames(colData(spe))) + stopifnot("expr_chrM_ratio" %in% colnames(colData(spe))) + spe_in <- spe[, spe$in_tissue] ## QC in-tissue spots From b1bbea6ff24141660732cabdd2245e4e2dec31a5 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 17:08:54 -0400 Subject: [PATCH 131/259] Add basic test for metrics_qc --- tests/testthat/test-metrics_qc.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/testthat/test-metrics_qc.R diff --git a/tests/testthat/test-metrics_qc.R b/tests/testthat/test-metrics_qc.R new file mode 100644 index 00000000..56924cd0 --- /dev/null +++ b/tests/testthat/test-metrics_qc.R @@ -0,0 +1,12 @@ +test_that( + "metrics_qc returns modified spe", + { + if (!exists("spe")) spe <- fetch_data("spe") + + #run metrics spe + spe_qc <- metrics_qc(spe) + expect_equal(ncol(spe), ncol(spe_qc)) ## same number of spots + expect_equal(ncol(colData(spe)) + 8, ncol(colData(spe_qc))) ## add 8 QC cols to colData + + } +) From 95c82af8e7585ec96b3ca6c2ab3682b5af5f3da6 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 6 May 2024 17:11:50 -0400 Subject: [PATCH 132/259] Style code --- R/metrics_qc.R | 197 ++++++++++++++++--------------- man/metrics_qc.Rd | 25 ++-- tests/testthat/test-metrics_qc.R | 19 ++- 3 files changed, 123 insertions(+), 118 deletions(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index 0413bfc5..69225b56 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -1,128 +1,135 @@ - #' Quality Control for Spatial Data #' #' This function identify spots in a #' [SpatialExperiment-class][SpatialExperiment::SpatialExperiment-class] (SPE) #' with outlier quality control values: low `sum_umi` or `sum_gene`, or high #' `expr_chrM_ratio`, utilizing `scran::isOutlier()`. Also identifies in-tissue -#' edge spots and distance to the edge for each spot. +#' edge spots and distance to the edge for each spot. #' #' @param spe a [SpatialExperiment][SpatialExperiment::SpatialExperiment-class] #' #' @return A [SpatialExperiment][SpatialExperiment::SpatialExperiment-class] #' with added quiality control information added to the colData. -#' +#' #' @export #' #' @examples -#' if (enough_ram()) { +#' if (enough_ram()) { #' ## Obtain the necessary data #' if (!exists("spe")) spe <- fetch_data("spe") -#' +#' #' ## fake out tissue spots in example data (TODO add pre-qc data) #' spe_qc <- spe #' spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE -#' +#' #' ## adds QC metrics to colData of the spe #' spe_qc <- metrics_qc(spe_qc) #' colData(spe_qc) -#' +#' #' ## visualize edge spots #' vis_clus(spe_qc, sampleid = "151507", clustervar = "edge_spot") #' vis_gene(spe_qc, sampleid = "151507", geneid = "edge_distance", minCount = -1) -#' +#' #' ## visualize scran QC flags -#' +#' #' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") -#' -#' scater::plotColData(spe_qc[,spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") -#' +#' +#' scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") +#' #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") -#' -#' } -#' #' +#' } +#' #' #' @importFrom dplyr group_by summarize left_join select mutate #' @importFrom SummarizedExperiment colData -#' @importFrom scater isOutlier +#' @importFrom scater isOutlier metrics_qc <- function(spe) { - - stopifnot("in_tissue" %in% colnames(colData(spe))) - stopifnot("sum_umi" %in% colnames(colData(spe))) - stopifnot("sum_gene" %in% colnames(colData(spe))) - stopifnot("expr_chrM_ratio" %in% colnames(colData(spe))) + stopifnot("in_tissue" %in% colnames(colData(spe))) + stopifnot("sum_umi" %in% colnames(colData(spe))) + stopifnot("sum_gene" %in% colnames(colData(spe))) + stopifnot("expr_chrM_ratio" %in% colnames(colData(spe))) + + spe_in <- spe[, spe$in_tissue] + + ## QC in-tissue spots + qc_df <- data.frame( + log2sum = log2(spe_in$sum_umi), + log2detected = log2(spe_in$sum_gene), + subsets_Mito_percent = spe_in$expr_chrM_ratio * 100, + sample_id = spe_in$sample_id + ) + + qcfilter <- data.frame( + low_lib_size = scater::isOutlier(qc_df$log2sum, type = "lower", log = TRUE, batch = qc_df$sample_id), + low_n_features = scater::isOutlier(qc_df$log2detected, type = "lower", log = TRUE, batch = qc_df$sample_id), + high_subsets_Mito_percent = scater::isOutlier(qc_df$subsets_Mito_percent, type = "higher", batch = qc_df$sample_id) + ) |> + dplyr::mutate(discard = (low_lib_size | low_n_features) | high_subsets_Mito_percent) + + ## Add qcfilter cols to colData(spe) after factoring + ## discard + spe$scran_discard <- NA + spe$scran_discard[which(spe$in_tissue)] <- qcfilter$discard + spe$scran_discard <- factor(spe$scran_discard, levels = c("TRUE", "FALSE")) + + ## low_lib_size + spe$scran_low_lib_size <- NA + spe$scran_low_lib_size[which(spe$in_tissue)] <- qcfilter$low_lib_size + spe$scran_low_lib_size <- factor(spe$scran_low_lib_size, + levels = c("TRUE", "FALSE") + ) + ## low_n_features + spe$scran_low_n_features <- NA + spe$scran_low_n_features[which(spe$in_tissue)] <- qcfilter$low_n_features + spe$sscran_low_n_features <- factor(spe$scran_low_n_features, + levels = c("TRUE", "FALSE") + ) + + ## high mito percent + spe$scran_high_subsets_Mito_percent <- NA + spe$scran_high_subsets_Mito_percent[which(spe$in_tissue)] <- + qcfilter$high_subsets_Mito_percent + spe$scran_high_subsets_Mito_percent <- + factor(spe$scran_high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) + + ## Find edge spots + spot_coords <- colData(spe_in) |> + as.data.frame() |> + select(in_tissue, sample_id, array_row, array_col) |> + group_by(sample_id, array_row) |> + mutate( + edge_col = array_col == min(array_col) | array_col == max(array_col), + col_distance = pmin( + abs(array_col - min(array_col)), + abs(array_col - max(array_col)) + ) + ) |> + group_by(sample_id, array_col) |> + mutate( + edge_row = array_row == min(array_row) | array_row == max(array_row), + row_distance = pmin( + abs(array_row - min(array_row)), + abs(array_row - max(array_row)) + ) + ) |> + group_by(sample_id) |> + mutate( + edge_spot = edge_row | edge_col, + edge_distance = pmin(row_distance, col_distance) + ) + + + ## Add Edge info to spe + spe$edge_spot <- NA + spe$edge_spot[which(spe$in_tissue)] <- spot_coords$edge_spot + spe$edge_spot <- factor(spe$edge_spot, levels = c("TRUE", "FALSE")) + + spe$edge_distance <- NA + spe$edge_distance[which(spe$in_tissue)] <- spot_coords$edge_distance + + spe$scran_low_lib_size_edge <- NA + spe$scran_low_lib_size_edge[which(spe$in_tissue)] <- qcfilter$low_lib_size & spot_coords$edge_spot + spe$scran_low_lib_size_edge <- factor(spe$scran_low_lib_size_edge, levels = c("TRUE", "FALSE")) - spe_in <- spe[, spe$in_tissue] - - ## QC in-tissue spots - qc_df <- data.frame( - log2sum = log2(spe_in$sum_umi), - log2detected = log2(spe_in$sum_gene), - subsets_Mito_percent = spe_in$expr_chrM_ratio*100, - sample_id = spe_in$sample_id - ) - - qcfilter <- data.frame( - low_lib_size = scater::isOutlier(qc_df$log2sum, type = "lower", log = TRUE, batch = qc_df$sample_id), - low_n_features = scater::isOutlier(qc_df$log2detected, type = "lower", log = TRUE, batch = qc_df$sample_id), - high_subsets_Mito_percent = scater::isOutlier(qc_df$subsets_Mito_percent, type = "higher", batch = qc_df$sample_id) - ) |> - dplyr::mutate(discard = (low_lib_size | low_n_features) | high_subsets_Mito_percent) - - ## Add qcfilter cols to colData(spe) after factoring - ## discard - spe$scran_discard <- NA - spe$scran_discard[which(spe$in_tissue)] <- qcfilter$discard - spe$scran_discard <- factor(spe$scran_discard, levels = c("TRUE", "FALSE")) - - ## low_lib_size - spe$scran_low_lib_size <- NA - spe$scran_low_lib_size[which(spe$in_tissue)] <- qcfilter$low_lib_size - spe$scran_low_lib_size <- factor(spe$scran_low_lib_size, - levels = c("TRUE", "FALSE")) - ## low_n_features - spe$scran_low_n_features <- NA - spe$scran_low_n_features[which(spe$in_tissue)] <- qcfilter$low_n_features - spe$sscran_low_n_features<- factor(spe$scran_low_n_features, - levels = c("TRUE", "FALSE")) - - ## high mito percent - spe$scran_high_subsets_Mito_percent <- NA - spe$scran_high_subsets_Mito_percent[which(spe$in_tissue)] <- - qcfilter$high_subsets_Mito_percent - spe$scran_high_subsets_Mito_percent <- - factor(spe$scran_high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) - - ## Find edge spots - spot_coords <- colData(spe_in) |> - as.data.frame() |> - select(in_tissue, sample_id, array_row, array_col) |> - group_by(sample_id, array_row) |> - mutate(edge_col = array_col == min(array_col) | array_col == max(array_col), - col_distance = pmin(abs(array_col - min(array_col)), - abs(array_col - max(array_col))) - ) |> - group_by(sample_id, array_col) |> - mutate(edge_row = array_row == min(array_row) | array_row == max(array_row), - row_distance = pmin(abs(array_row - min(array_row)), - abs(array_row - max(array_row))) - ) |> - group_by(sample_id) |> - mutate(edge_spot = edge_row | edge_col, - edge_distance = pmin(row_distance, col_distance)) - - - ## Add Edge info to spe - spe$edge_spot <- NA - spe$edge_spot[which(spe$in_tissue)] <- spot_coords$edge_spot - spe$edge_spot <- factor(spe$edge_spot, levels = c("TRUE", "FALSE")) - - spe$edge_distance <- NA - spe$edge_distance[which(spe$in_tissue)] <- spot_coords$edge_distance - - spe$scran_low_lib_size_edge <- NA - spe$scran_low_lib_size_edge[which(spe$in_tissue)] <- qcfilter$low_lib_size & spot_coords$edge_spot - spe$scran_low_lib_size_edge <- factor(spe$scran_low_lib_size_edge, levels = c("TRUE", "FALSE")) - - return(spe) -} \ No newline at end of file + return(spe) +} diff --git a/man/metrics_qc.Rd b/man/metrics_qc.Rd index 76ff25a4..5f4850de 100644 --- a/man/metrics_qc.Rd +++ b/man/metrics_qc.Rd @@ -21,34 +21,33 @@ with outlier quality control values: low \code{sum_umi} or \code{sum_gene}, or h edge spots and distance to the edge for each spot. } \examples{ - if (enough_ram()) { +if (enough_ram()) { ## Obtain the necessary data if (!exists("spe")) spe <- fetch_data("spe") - + ## fake out tissue spots in example data (TODO add pre-qc data) spe_qc <- spe spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE - + ## adds QC metrics to colData of the spe spe_qc <- metrics_qc(spe_qc) colData(spe_qc) - + ## visualize edge spots vis_clus(spe_qc, sampleid = "151507", clustervar = "edge_spot") vis_gene(spe_qc, sampleid = "151507", geneid = "edge_distance", minCount = -1) - + ## visualize scran QC flags - + vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") - - scater::plotColData(spe_qc[,spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") - + + scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") + vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") - - } - #' +} +#' @importFrom dplyr group_by summarize left_join select mutate @importFrom SummarizedExperiment colData - @importFrom scater isOutlier + @importFrom scater isOutlier } diff --git a/tests/testthat/test-metrics_qc.R b/tests/testthat/test-metrics_qc.R index 56924cd0..e8473813 100644 --- a/tests/testthat/test-metrics_qc.R +++ b/tests/testthat/test-metrics_qc.R @@ -1,12 +1,11 @@ test_that( - "metrics_qc returns modified spe", - { - if (!exists("spe")) spe <- fetch_data("spe") - - #run metrics spe - spe_qc <- metrics_qc(spe) - expect_equal(ncol(spe), ncol(spe_qc)) ## same number of spots - expect_equal(ncol(colData(spe)) + 8, ncol(colData(spe_qc))) ## add 8 QC cols to colData - - } + "metrics_qc returns modified spe", + { + if (!exists("spe")) spe <- fetch_data("spe") + + # run metrics spe + spe_qc <- metrics_qc(spe) + expect_equal(ncol(spe), ncol(spe_qc)) ## same number of spots + expect_equal(ncol(colData(spe)) + 8, ncol(colData(spe_qc))) ## add 8 QC cols to colData + } ) From f25860feda852255423fe315fd99a13f0b0db6a8 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 9 May 2024 10:44:47 -0400 Subject: [PATCH 133/259] Update citation info for spatialDLPFC --- inst/CITATION | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inst/CITATION b/inst/CITATION index 36731c8c..bc6d454d 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -45,7 +45,7 @@ c( url = "https://www.nature.com/articles/s41593-020-00787-0" ), bibentry(bibtype="article", - title = "Integrated single cell and unsupervised spatial transcriptomic analysis defines molecular anatomy of the human dorsolateral prefrontal cortex", + title = "A data-driven single-cell and spatial transcriptomic map of the human prefrontal cortex", author = personList( as.person("Louise A. Huuki-Myers"), as.person("Abby Spangler"), @@ -72,10 +72,10 @@ c( as.person("Leonardo Collado-Torres"), as.person("Kristen R. Maynard") ), - year = 2023, - journal = "bioRxiv", - doi = "10.1101/2023.02.15.528722", - url = "https://www.biorxiv.org/content/10.1101/2023.02.15.528722v1" + year = 2024, + journal = "Science", + doi = "10.1126/science.adh1938", + url = "https://doi.org/10.1126/science.adh1938" ), bibentry(bibtype="article", title = "Influence of Alzheimer’s disease related neuropathology on local microenvironment gene expression in the human inferior temporal cortex", From ad3bbb1ed91f99571183ed6503dd93711bcf9258 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 13:35:20 -0400 Subject: [PATCH 134/259] define variables --- R/metrics_qc.R | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index 69225b56..2f2318ac 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -52,6 +52,10 @@ metrics_qc <- function(spe) { spe_in <- spe[, spe$in_tissue] ## QC in-tissue spots + + # define variables + low_lib_size <- low_n_features <- in_tissue <- sample_id <- NULL + qc_df <- data.frame( log2sum = log2(spe_in$sum_umi), log2detected = log2(spe_in$sum_gene), @@ -93,6 +97,10 @@ metrics_qc <- function(spe) { factor(spe$scran_high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) ## Find edge spots + # define variables + arrary_row <- array_col <- edge_row <- edge_col <- row_distance <- NULL + col_distance <- NULL + spot_coords <- colData(spe_in) |> as.data.frame() |> select(in_tissue, sample_id, array_row, array_col) |> From ba2f3e305727c1305abbf557073a370f4d84f02f Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 13:39:22 -0400 Subject: [PATCH 135/259] comment out scater::plotColData from example to debug --- R/metrics_qc.R | 2 +- man/metrics_qc.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index 2f2318ac..879747c9 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -34,7 +34,7 @@ #' #' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") #' -#' scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") +#' # scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") #' #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") diff --git a/man/metrics_qc.Rd b/man/metrics_qc.Rd index 5f4850de..4f201a95 100644 --- a/man/metrics_qc.Rd +++ b/man/metrics_qc.Rd @@ -41,7 +41,7 @@ if (enough_ram()) { vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") - scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") + # scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") From 42775ceb36c8528122d47fdabdc163dbe963ad5d Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 14:32:44 -0400 Subject: [PATCH 136/259] Add dplyr to DESCRIPTION --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 59d21beb..69dbfc42 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -78,7 +78,8 @@ Imports: limma, statmod, MatrixGenerics, - rlang + rlang, + dplyr RoxygenNote: 7.3.1 Roxygen: list(markdown = TRUE) URL: https://github.com/LieberInstitute/spatialLIBD From 1cd63510f37de03a4022d2a259562944b455fa05 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 14:36:36 -0400 Subject: [PATCH 137/259] add as.logical to in_tissue, fix undefined variables --- R/metrics_qc.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index 879747c9..f734f6ad 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -49,6 +49,7 @@ metrics_qc <- function(spe) { stopifnot("sum_gene" %in% colnames(colData(spe))) stopifnot("expr_chrM_ratio" %in% colnames(colData(spe))) + spe$in_tissue <- as.logical(spe$in_tissue) spe_in <- spe[, spe$in_tissue] ## QC in-tissue spots @@ -98,8 +99,8 @@ metrics_qc <- function(spe) { ## Find edge spots # define variables - arrary_row <- array_col <- edge_row <- edge_col <- row_distance <- NULL - col_distance <- NULL + array_row <- array_col <- edge_row <- edge_col <- row_distance <- NULL + col_distance <- high_subsets_Mito_percent <- NULL spot_coords <- colData(spe_in) |> as.data.frame() |> From 77fed13e8bc433578c08f133ecdea8002679149f Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 14:39:28 -0400 Subject: [PATCH 138/259] Fix imports & example --- NAMESPACE | 7 +++++++ R/metrics_qc.R | 8 ++++---- man/metrics_qc.Rd | 5 +---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index ef0d5c1c..4a9ab05e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -84,8 +84,14 @@ importFrom(SummarizedExperiment,"rowRanges<-") importFrom(SummarizedExperiment,assay) importFrom(SummarizedExperiment,assayNames) importFrom(SummarizedExperiment,assays) +importFrom(SummarizedExperiment,colData) importFrom(benchmarkme,get_ram) importFrom(cowplot,plot_grid) +importFrom(dplyr,group_by) +importFrom(dplyr,left_join) +importFrom(dplyr,mutate) +importFrom(dplyr,select) +importFrom(dplyr,summarize) importFrom(edgeR,calcNormFactors) importFrom(edgeR,filterByExpr) importFrom(fields,image.plot) @@ -125,6 +131,7 @@ importFrom(methods,new) importFrom(png,readPNG) importFrom(rlang,arg_match) importFrom(rtracklayer,import) +importFrom(scater,isOutlier) importFrom(scater,plotReducedDim) importFrom(scuttle,aggregateAcrossCells) importFrom(sessioninfo,session_info) diff --git a/R/metrics_qc.R b/R/metrics_qc.R index f734f6ad..e2bd56f2 100644 --- a/R/metrics_qc.R +++ b/R/metrics_qc.R @@ -12,6 +12,9 @@ #' with added quiality control information added to the colData. #' #' @export +#' @importFrom dplyr group_by summarize left_join select mutate +#' @importFrom SummarizedExperiment colData +#' @importFrom scater isOutlier #' #' @examples #' if (enough_ram()) { @@ -39,10 +42,7 @@ #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") #' } -#' #' -#' @importFrom dplyr group_by summarize left_join select mutate -#' @importFrom SummarizedExperiment colData -#' @importFrom scater isOutlier +#' metrics_qc <- function(spe) { stopifnot("in_tissue" %in% colnames(colData(spe))) stopifnot("sum_umi" %in% colnames(colData(spe))) diff --git a/man/metrics_qc.Rd b/man/metrics_qc.Rd index 4f201a95..db964436 100644 --- a/man/metrics_qc.Rd +++ b/man/metrics_qc.Rd @@ -46,8 +46,5 @@ if (enough_ram()) { vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") } -#' - @importFrom dplyr group_by summarize left_join select mutate - @importFrom SummarizedExperiment colData - @importFrom scater isOutlier + } From b809a20471de4819a53b9f297fcf2ba383001cf8 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 15:38:45 -0400 Subject: [PATCH 139/259] Rename function to add_qc_metrics() --- R/{metrics_qc.R => add_qc_metrics.R} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename R/{metrics_qc.R => add_qc_metrics.R} (98%) diff --git a/R/metrics_qc.R b/R/add_qc_metrics.R similarity index 98% rename from R/metrics_qc.R rename to R/add_qc_metrics.R index e2bd56f2..df7cf2f0 100644 --- a/R/metrics_qc.R +++ b/R/add_qc_metrics.R @@ -26,7 +26,7 @@ #' spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE #' #' ## adds QC metrics to colData of the spe -#' spe_qc <- metrics_qc(spe_qc) +#' spe_qc <- add_qc_metrics()(spe_qc) #' colData(spe_qc) #' #' ## visualize edge spots @@ -43,7 +43,7 @@ #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") #' } #' -metrics_qc <- function(spe) { +add_qc_metrics() <- function(spe) { stopifnot("in_tissue" %in% colnames(colData(spe))) stopifnot("sum_umi" %in% colnames(colData(spe))) stopifnot("sum_gene" %in% colnames(colData(spe))) From d73d19eba9c612a59faf32fac3286327da0bcff4 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 15:44:26 -0400 Subject: [PATCH 140/259] Update function name add_qc_metrics in docs --- NAMESPACE | 2 +- R/add_qc_metrics.R | 4 ++-- man/{metrics_qc.Rd => add_qc_metrics.Rd} | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) rename man/{metrics_qc.Rd => add_qc_metrics.Rd} (91%) diff --git a/NAMESPACE b/NAMESPACE index 4a9ab05e..4eba582c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ export(add10xVisiumAnalysis) export(add_images) export(add_key) +export(add_qc_metrics) export(annotate_registered_clusters) export(check_modeling_results) export(check_sce) @@ -25,7 +26,6 @@ export(layer_matrix_plot) export(layer_stat_cor) export(layer_stat_cor_plot) export(locate_images) -export(metrics_qc) export(read10xVisiumAnalysis) export(read10xVisiumWrapper) export(registration_block_cor) diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index df7cf2f0..01067f87 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -26,7 +26,7 @@ #' spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE #' #' ## adds QC metrics to colData of the spe -#' spe_qc <- add_qc_metrics()(spe_qc) +#' spe_qc <- add_qc_metrics(spe_qc) #' colData(spe_qc) #' #' ## visualize edge spots @@ -43,7 +43,7 @@ #' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") #' } #' -add_qc_metrics() <- function(spe) { +add_qc_metrics <- function(spe) { stopifnot("in_tissue" %in% colnames(colData(spe))) stopifnot("sum_umi" %in% colnames(colData(spe))) stopifnot("sum_gene" %in% colnames(colData(spe))) diff --git a/man/metrics_qc.Rd b/man/add_qc_metrics.Rd similarity index 91% rename from man/metrics_qc.Rd rename to man/add_qc_metrics.Rd index db964436..b1d5dc5d 100644 --- a/man/metrics_qc.Rd +++ b/man/add_qc_metrics.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/metrics_qc.R -\name{metrics_qc} -\alias{metrics_qc} +% Please edit documentation in R/add_qc_metrics.R +\name{add_qc_metrics} +\alias{add_qc_metrics} \title{Quality Control for Spatial Data} \usage{ -metrics_qc(spe) +add_qc_metrics(spe) } \arguments{ \item{spe}{a \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment}} @@ -30,7 +30,7 @@ if (enough_ram()) { spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE ## adds QC metrics to colData of the spe - spe_qc <- metrics_qc(spe_qc) + spe_qc <- add_qc_metrics(spe_qc) colData(spe_qc) ## visualize edge spots From 535ceea33ce5e04872610aef3963f0fc53a1877c Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 17 May 2024 15:45:35 -0400 Subject: [PATCH 141/259] Update add_qc_metrics name in test --- tests/testthat/{test-metrics_qc.R => test-add_qc_metrics.R} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename tests/testthat/{test-metrics_qc.R => test-add_qc_metrics.R} (76%) diff --git a/tests/testthat/test-metrics_qc.R b/tests/testthat/test-add_qc_metrics.R similarity index 76% rename from tests/testthat/test-metrics_qc.R rename to tests/testthat/test-add_qc_metrics.R index e8473813..9985bbb6 100644 --- a/tests/testthat/test-metrics_qc.R +++ b/tests/testthat/test-add_qc_metrics.R @@ -1,10 +1,10 @@ test_that( - "metrics_qc returns modified spe", + "add_qc_metrics returns modified spe", { if (!exists("spe")) spe <- fetch_data("spe") # run metrics spe - spe_qc <- metrics_qc(spe) + spe_qc <- add_qc_metrics(spe) expect_equal(ncol(spe), ncol(spe_qc)) ## same number of spots expect_equal(ncol(colData(spe)) + 8, ncol(colData(spe_qc))) ## add 8 QC cols to colData } From a3cbd4022573a27b676fcce57bfa473d333912fb Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 24 May 2024 00:51:37 -0400 Subject: [PATCH 142/259] Update README with some videos + link to blog posts + fix citation info displayed. --- README.Rmd | 10 ++ README.md | 77 +++++++++----- inst/app/www/README.md | 229 +++++++++++++++++++++++++++++++---------- 3 files changed, 231 insertions(+), 85 deletions(-) diff --git a/README.Rmd b/README.Rmd index 27248ae7..573bd17d 100644 --- a/README.Rmd +++ b/README.Rmd @@ -70,6 +70,16 @@ spatialLIBD::run_app() * [Main shiny application website](http://spatial.libd.org/spatialLIBD/) (note that the link must have a trailing slash `/` for it to work) * [Shinyapps](https://libd.shinyapps.io/spatialLIBD/) This version has less RAM memory but is typically deployed using the latest version of `spatialLIBD`. +## Introductory material + +If you prefer to watch a video overview of the `HumanPilot` project, check the following journal club presentation of the main results. + + + +You might also be interested in the explainer video and [companion blog post](https://lcolladotor.github.io/2024/05/23/humanpilot-first-spatially-resolved-transcriptomics-study-using-visium/) as well as [the original Feb 29, 2020 blog post](https://lcolladotor.github.io/2020/02/29/diving-together-into-the-unknown-world-of-spatial-transcriptomics/) from when we first made this project public. + + + ## R/Bioconductor package The `spatialLIBD` package contains functions for: diff --git a/README.md b/README.md index b15cfbdc..23a0513e 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,23 @@ spatialLIBD::run_app() less RAM memory but is typically deployed using the latest version of `spatialLIBD`. +## Introductory material + +If you prefer to watch a video overview of the `HumanPilot` project, +check the following journal club presentation of the main results. + + + +You might also be interested in the explainer video and [companion blog +post](https://lcolladotor.github.io/2024/05/23/humanpilot-first-spatially-resolved-transcriptomics-study-using-visium/) +as well as [the original Feb 29, 2020 blog +post](https://lcolladotor.github.io/2020/02/29/diving-together-into-the-unknown-world-of-spatial-transcriptomics/) +from when we first made this project public. + + + ## R/Bioconductor package The `spatialLIBD` package contains functions for: @@ -198,10 +215,16 @@ spe #> altExpNames(0): #> spatialCoords names(2) : pxl_col_in_fullres pxl_row_in_fullres #> imgData names(4): sample_id image_id data scaleFactor +``` + +``` r ## Note the memory size lobstr::obj_size(spe) #> 2.04 GB +``` + +``` r ## Remake the logo image with histology information vis_clus( @@ -222,20 +245,20 @@ You can access all the raw data through Furthermore, below you can find the links to the raw data we received from 10x Genomics. -| SampleID | h5_filtered | h5_raw | image_full | image_hi | image_lo | loupe | HTML_report | -|---------:|:------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------| -| 151507 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151507.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151507/151507_web_summary.html) | -| 151508 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151508.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151508/151508_web_summary.html) | -| 151509 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151509.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151509/151509_web_summary.html) | -| 151510 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151510.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151510/151510_web_summary.html) | -| 151669 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151669.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151669/151669_web_summary.html) | -| 151670 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151670.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151670/151670_web_summary.html) | -| 151671 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151671.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151671/151671_web_summary.html) | -| 151672 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151672.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151672/151672_web_summary.html) | -| 151673 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151673.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151673/151673_web_summary.html) | -| 151674 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151674.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151674/151674_web_summary.html) | -| 151675 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151675.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151675/151675_web_summary.html) | -| 151676 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151676.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151676/151676_web_summary.html) | +| SampleID | h5_filtered | h5_raw | image_full | image_hi | image_lo | loupe | HTML_report | +|---:|:---|:---|:---|:---|:---|:---|:---| +| 151507 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151507.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151507/151507_web_summary.html) | +| 151508 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151508.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151508/151508_web_summary.html) | +| 151509 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151509.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151509/151509_web_summary.html) | +| 151510 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151510.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151510/151510_web_summary.html) | +| 151669 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151669.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151669/151669_web_summary.html) | +| 151670 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151670.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151670/151670_web_summary.html) | +| 151671 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151671.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151671/151671_web_summary.html) | +| 151672 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151672.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151672/151672_web_summary.html) | +| 151673 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151673.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151673/151673_web_summary.html) | +| 151674 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151674.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151674/151674_web_summary.html) | +| 151675 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151675.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151675/151675_web_summary.html) | +| 151676 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151676.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151676/151676_web_summary.html) | ## Citation @@ -289,22 +312,21 @@ print(citation("spatialLIBD"), bibtex = TRUE) #> B, Grant-Peters M, Divecha HR, Tippani M, Sriworarat C, Nguyen AB, #> Ravichandran P, Tran MN, Seyedian A, Consortium P, Hyde TM, Kleinman #> JE, Battle A, Page SC, Ryten M, Hicks SC, Martinowich K, -#> Collado-Torres L, Maynard KR (2023). "Integrated single cell and -#> unsupervised spatial transcriptomic analysis defines molecular -#> anatomy of the human dorsolateral prefrontal cortex." _bioRxiv_. -#> doi:10.1101/2023.02.15.528722 -#> , -#> . +#> Collado-Torres L, Maynard KR (2024). "A data-driven single-cell and +#> spatial transcriptomic map of the human prefrontal cortex." +#> _Science_. doi:10.1126/science.adh1938 +#> , +#> . #> #> A BibTeX entry for LaTeX users is #> #> @Article{, -#> title = {Integrated single cell and unsupervised spatial transcriptomic analysis defines molecular anatomy of the human dorsolateral prefrontal cortex}, +#> title = {A data-driven single-cell and spatial transcriptomic map of the human prefrontal cortex}, #> author = {Louise A. Huuki-Myers and Abby Spangler and Nicholas J. Eagles and Kelsey D. Montgomergy and Sang Ho Kwon and Boyi Guo and Melissa Grant-Peters and Heena R. Divecha and Madhavi Tippani and Chaichontat Sriworarat and Annie B. Nguyen and Prashanthi Ravichandran and Matthew N. Tran and Arta Seyedian and PsychENCODE Consortium and Thomas M. Hyde and Joel E. Kleinman and Alexis Battle and Stephanie C. Page and Mina Ryten and Stephanie C. Hicks and Keri Martinowich and Leonardo Collado-Torres and Kristen R. Maynard}, -#> year = {2023}, -#> journal = {bioRxiv}, -#> doi = {10.1101/2023.02.15.528722}, -#> url = {https://www.biorxiv.org/content/10.1101/2023.02.15.528722v1}, +#> year = {2024}, +#> journal = {Science}, +#> doi = {10.1126/science.adh1938}, +#> url = {https://doi.org/10.1126/science.adh1938}, #> } #> #> Kwon SH, Parthiban S, Tippani M, Divecha HR, Eagles NJ, Lobana JS, @@ -349,7 +371,7 @@ By contributing to this project, you agree to abide by its terms. *[rcmdcheck](https://CRAN.R-project.org/package=rcmdcheck)* customized to use [Bioconductor’s docker containers](https://www.bioconductor.org/help/docker/) and - *[BiocCheck](https://bioconductor.org/packages/3.17/BiocCheck)*. + *[BiocCheck](https://bioconductor.org/packages/3.19/BiocCheck)*. - Code coverage assessment is possible thanks to [codecov](https://codecov.io/gh) and *[covr](https://CRAN.R-project.org/package=covr)*. @@ -366,7 +388,7 @@ By contributing to this project, you agree to abide by its terms. For more details, check the `dev` directory. This package was developed using -*[biocthis](https://bioconductor.org/packages/3.17/biocthis)*. +*[biocthis](https://bioconductor.org/packages/3.19/biocthis)*. @@ -379,6 +401,5 @@ This package was developed using window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); - gtag('config', 'G-QKT3SV9EFL'); diff --git a/inst/app/www/README.md b/inst/app/www/README.md index 5a4d943a..adb3c1b8 100644 --- a/inst/app/www/README.md +++ b/inst/app/www/README.md @@ -25,29 +25,31 @@ coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/b status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) +[![GitHub +pulls](https://img.shields.io/github/issues-pr/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/pulls) [![DOI](https://zenodo.org/badge/225913568.svg)](https://zenodo.org/badge/latestdoi/225913568) Welcome to the `spatialLIBD` project! It is composed of: -- a [shiny](https://shiny.rstudio.com/) web application that we are - hosting at - [spatial.libd.org/spatialLIBD/](http://spatial.libd.org/spatialLIBD/) - that can handle a - [limited](https://github.com/LieberInstitute/spatialLIBD/issues/2) - set of concurrent users, -- a Bioconductor package at - [bioconductor.org/packages/spatialLIBD](http://bioconductor.org/packages/spatialLIBD) - (or from [here](http://research.libd.org/spatialLIBD/)) that lets - you analyze the data and run a local version of our web application - (with our data or yours), -- and a [research article](https://doi.org/10.1038/s41593-020-00787-0) - with the scientific knowledge we drew from this dataset. The - analysis code for our project is available - [here](https://github.com/LieberInstitute/HumanPilot/) and the high - quality figures for the manuscript are available through - [Figshare](https://doi.org/10.6084/m9.figshare.13623902.v1). +- a [shiny](https://shiny.rstudio.com/) web application that we are + hosting at + [spatial.libd.org/spatialLIBD/](http://spatial.libd.org/spatialLIBD/) + that can handle a + [limited](https://github.com/LieberInstitute/spatialLIBD/issues/2) set + of concurrent users, +- a Bioconductor package at + [bioconductor.org/packages/spatialLIBD](http://bioconductor.org/packages/spatialLIBD) + (or from [here](http://research.libd.org/spatialLIBD/)) that lets you + analyze the data and run a local version of our web application (with + our data or yours), +- and a [research article](https://doi.org/10.1038/s41593-020-00787-0) + with the scientific knowledge we drew from this dataset. The analysis + code for our project is available + [here](https://github.com/LieberInstitute/HumanPilot/) and the high + quality figures for the manuscript are available through + [Figshare](https://doi.org/10.6084/m9.figshare.13623902.v1). The web application allows you to browse the LIBD human dorsolateral pre-frontal cortex (DLPFC) spatial transcriptomics data generated with @@ -115,19 +117,35 @@ spatialLIBD::run_app() less RAM memory but is typically deployed using the latest version of `spatialLIBD`. +## Introductory material + +If you prefer to watch a video overview of the `HumanPilot` project, +check the following journal club presentation of the main results. + + + +You might also be interested in the explainer video and [companion blog +post](https://lcolladotor.github.io/2024/05/23/humanpilot-first-spatially-resolved-transcriptomics-study-using-visium/) +as well as [the original Feb 29, 2020 blog +post](https://lcolladotor.github.io/2020/02/29/diving-together-into-the-unknown-world-of-spatial-transcriptomics/) +from when we first made this project public. + + + ## R/Bioconductor package The `spatialLIBD` package contains functions for: -- Accessing the spatial transcriptomics data from the LIBD Human Pilot - project ([code on - GitHub](https://github.com/LieberInstitute/HumanPilot)) generated - with the Visium platform from 10x Genomics. The data is retrieved - from [Bioconductor](http://bioconductor.org/)’s `ExperimentHub`. -- Visualizing the spot-level spatial gene expression data and - clusters. -- Inspecting the data interactively either on your computer or through - [spatial.libd.org/spatialLIBD/](http://spatial.libd.org/spatialLIBD/). +- Accessing the spatial transcriptomics data from the LIBD Human Pilot + project ([code on + GitHub](https://github.com/LieberInstitute/HumanPilot)) generated with + the Visium platform from 10x Genomics. The data is retrieved from + [Bioconductor](http://bioconductor.org/)’s `ExperimentHub`. +- Visualizing the spot-level spatial gene expression data and clusters. +- Inspecting the data interactively either on your computer or through + [spatial.libd.org/spatialLIBD/](http://spatial.libd.org/spatialLIBD/). For more details, please check the [documentation website](http://lieberinstitute.github.io/spatialLIBD) or the @@ -190,18 +208,23 @@ spe #> rowData names(9): source type ... gene_search is_top_hvg #> colnames(47681): AAACAACGAATAGTTC-1 AAACAAGTATCTCCCA-1 ... #> TTGTTTCCATACAACT-1 TTGTTTGTGTAAATTC-1 -#> colData names(66): sample_id Cluster ... spatialLIBD ManualAnnotation +#> colData names(69): sample_id Cluster ... array_row array_col #> reducedDimNames(6): PCA TSNE_perplexity50 ... TSNE_perplexity80 #> UMAP_neighbors15 #> mainExpName: NULL #> altExpNames(0): -#> spatialData names(3) : in_tissue array_row array_col #> spatialCoords names(2) : pxl_col_in_fullres pxl_row_in_fullres #> imgData names(4): sample_id image_id data scaleFactor +``` + +``` r ## Note the memory size -lobstr::obj_size(spe) +lobstr::obj_size(spe) #> 2.04 GB +``` + +``` r ## Remake the logo image with histology information vis_clus( @@ -222,20 +245,20 @@ You can access all the raw data through Furthermore, below you can find the links to the raw data we received from 10x Genomics. -| SampleID | h5\_filtered | h5\_raw | image\_full | image\_hi | image\_lo | loupe | HTML\_report | -|---------:|:------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------| -| 151507 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151507.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151507/151507_web_summary.html) | -| 151508 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151508.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151508/151508_web_summary.html) | -| 151509 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151509.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151509/151509_web_summary.html) | -| 151510 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151510.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151510/151510_web_summary.html) | -| 151669 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151669.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151669/151669_web_summary.html) | -| 151670 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151670.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151670/151670_web_summary.html) | -| 151671 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151671.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151671/151671_web_summary.html) | -| 151672 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151672.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151672/151672_web_summary.html) | -| 151673 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151673.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151673/151673_web_summary.html) | -| 151674 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151674.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151674/151674_web_summary.html) | -| 151675 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151675.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151675/151675_web_summary.html) | -| 151676 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151676.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151676/151676_web_summary.html) | +| SampleID | h5_filtered | h5_raw | image_full | image_hi | image_lo | loupe | HTML_report | +|---:|:---|:---|:---|:---|:---|:---|:---| +| 151507 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151507_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151507_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151507.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151507/151507_web_summary.html) | +| 151508 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151508_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151508_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151508.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151508/151508_web_summary.html) | +| 151509 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151509_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151509_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151509.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151509/151509_web_summary.html) | +| 151510 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151510_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151510_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151510.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151510/151510_web_summary.html) | +| 151669 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151669_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151669_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151669.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151669/151669_web_summary.html) | +| 151670 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151670_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151670_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151670.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151670/151670_web_summary.html) | +| 151671 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151671_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151671_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151671.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151671/151671_web_summary.html) | +| 151672 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151672_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151672_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151672.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151672/151672_web_summary.html) | +| 151673 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151673_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151673_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151673.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151673/151673_web_summary.html) | +| 151674 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151674_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151674_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151674.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151674/151674_web_summary.html) | +| 151675 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151675_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151675_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151675.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151675/151675_web_summary.html) | +| 151676 | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_filtered_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/h5/151676_raw_feature_bc_matrix.h5) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_full_image.tif) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_hires_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/images/151676_tissue_lowres_image.png) | [AWS](https://spatial-dlpfc.s3.us-east-2.amazonaws.com/loupe/151676.cloupe) | [GitHub](https://github.com/LieberInstitute/HumanPilot/blob/master/10X/151676/151676_web_summary.html) | ## Citation @@ -245,13 +268,14 @@ Please run this yourself to check for any updates on how to cite ``` r print(citation("spatialLIBD"), bibtex = TRUE) +#> To cite package 'spatialLIBD' in publications use: #> -#> Pardo B, Spangler A, Weber LM, Hicks SC, Jaffe AE, Martinowich K, -#> Maynard KR, Collado-Torres L (2022). "spatialLIBD: an R/Bioconductor -#> package to visualize spatially-resolved transcriptomics data." -#> _BMC Genomics_. doi: 10.1186/s12864-022-08601-w (URL: -#> https://doi.org/10.1186/s12864-022-08601-w), https://doi.org/10.1186/s12864-022-08601-w>. +#> Pardo B, Spangler A, Weber LM, Hicks SC, Jaffe AE, Martinowich K, +#> Maynard KR, Collado-Torres L (2022). "spatialLIBD: an R/Bioconductor +#> package to visualize spatially-resolved transcriptomics data." _BMC +#> Genomics_. doi:10.1186/s12864-022-08601-w +#> , +#> . #> #> A BibTeX entry for LaTeX users is #> @@ -264,14 +288,14 @@ print(citation("spatialLIBD"), bibtex = TRUE) #> url = {https://doi.org/10.1186/s12864-022-08601-w}, #> } #> -#> Maynard KR, Collado-Torres L, Weber LM, Uytingco C, Barry BK, Williams -#> SR, II JLC, Tran MN, Besich Z, Tippani M, Chew J, Yin Y, Kleinman JE, -#> Hyde TM, Rao N, Hicks SC, Martinowich K, Jaffe AE (2021). -#> "Transcriptome-scale spatial gene expression in the human dorsolateral -#> prefrontal cortex." _Nature Neuroscience_. doi: -#> 10.1038/s41593-020-00787-0 (URL: -#> https://doi.org/10.1038/s41593-020-00787-0), https://www.nature.com/articles/s41593-020-00787-0>. +#> Maynard KR, Collado-Torres L, Weber LM, Uytingco C, Barry BK, +#> Williams SR, II JLC, Tran MN, Besich Z, Tippani M, Chew J, Yin Y, +#> Kleinman JE, Hyde TM, Rao N, Hicks SC, Martinowich K, Jaffe AE +#> (2021). "Transcriptome-scale spatial gene expression in the human +#> dorsolateral prefrontal cortex." _Nature Neuroscience_. +#> doi:10.1038/s41593-020-00787-0 +#> , +#> . #> #> A BibTeX entry for LaTeX users is #> @@ -283,8 +307,99 @@ print(citation("spatialLIBD"), bibtex = TRUE) #> doi = {10.1038/s41593-020-00787-0}, #> url = {https://www.nature.com/articles/s41593-020-00787-0}, #> } +#> +#> Huuki-Myers LA, Spangler A, Eagles NJ, Montgomergy KD, Kwon SH, Guo +#> B, Grant-Peters M, Divecha HR, Tippani M, Sriworarat C, Nguyen AB, +#> Ravichandran P, Tran MN, Seyedian A, Consortium P, Hyde TM, Kleinman +#> JE, Battle A, Page SC, Ryten M, Hicks SC, Martinowich K, +#> Collado-Torres L, Maynard KR (2024). "A data-driven single-cell and +#> spatial transcriptomic map of the human prefrontal cortex." +#> _Science_. doi:10.1126/science.adh1938 +#> , +#> . +#> +#> A BibTeX entry for LaTeX users is +#> +#> @Article{, +#> title = {A data-driven single-cell and spatial transcriptomic map of the human prefrontal cortex}, +#> author = {Louise A. Huuki-Myers and Abby Spangler and Nicholas J. Eagles and Kelsey D. Montgomergy and Sang Ho Kwon and Boyi Guo and Melissa Grant-Peters and Heena R. Divecha and Madhavi Tippani and Chaichontat Sriworarat and Annie B. Nguyen and Prashanthi Ravichandran and Matthew N. Tran and Arta Seyedian and PsychENCODE Consortium and Thomas M. Hyde and Joel E. Kleinman and Alexis Battle and Stephanie C. Page and Mina Ryten and Stephanie C. Hicks and Keri Martinowich and Leonardo Collado-Torres and Kristen R. Maynard}, +#> year = {2024}, +#> journal = {Science}, +#> doi = {10.1126/science.adh1938}, +#> url = {https://doi.org/10.1126/science.adh1938}, +#> } +#> +#> Kwon SH, Parthiban S, Tippani M, Divecha HR, Eagles NJ, Lobana JS, +#> Williams SR, Mark M, Bharadwaj RA, Kleinman JE, Hyde TM, Page SC, +#> Hicks SC, Martinowich K, Maynard KR, Collado-Torres L (2023). +#> "Influence of Alzheimer’s disease related neuropathology on local +#> microenvironment gene expression in the human inferior temporal +#> cortex." _bioRxiv_. doi:10.1101/2023.04.20.537710 +#> , +#> . +#> +#> A BibTeX entry for LaTeX users is +#> +#> @Article{, +#> title = {Influence of Alzheimer’s disease related neuropathology on local microenvironment gene expression in the human inferior temporal cortex}, +#> author = {Sang Ho Kwon and Sowmya Parthiban and Madhavi Tippani and Heena R. Divecha and Nicholas J. Eagles and Jashandeep S. Lobana and Stephen R. Williams and Michelle Mark and Rahul A. Bharadwaj and Joel E. Kleinman and Thomas M. Hyde and Stephanie C. Page and Stephanie C. Hicks and Keri Martinowich and Kristen R. Maynard and Leonardo Collado-Torres}, +#> year = {2023}, +#> journal = {bioRxiv}, +#> doi = {10.1101/2023.04.20.537710}, +#> url = {https://www.biorxiv.org/content/10.1101/2023.04.20.537710v1}, +#> } ``` Please note that the `spatialLIBD` was only made possible thanks to many other R and bioinformatics software authors, which are cited either in the vignettes and/or the paper(s) describing this package. + +## Code of Conduct + +Please note that the spatialLIBD project is released with a [Contributor +Code of +Conduct](https://contributor-covenant.org/version/2/0/CODE_OF_CONDUCT.html). +By contributing to this project, you agree to abide by its terms. + +## Development tools + +- Continuous code testing is possible thanks to [GitHub + actions](https://www.tidyverse.org/blog/2020/04/usethis-1-6-0/) + through *[usethis](https://CRAN.R-project.org/package=usethis)*, + *[remotes](https://CRAN.R-project.org/package=remotes)*, + *[sysreqs](https://github.com/r-hub/sysreqs)* and + *[rcmdcheck](https://CRAN.R-project.org/package=rcmdcheck)* customized + to use [Bioconductor’s docker + containers](https://www.bioconductor.org/help/docker/) and + *[BiocCheck](https://bioconductor.org/packages/3.19/BiocCheck)*. +- Code coverage assessment is possible thanks to + [codecov](https://codecov.io/gh) and + *[covr](https://CRAN.R-project.org/package=covr)*. +- The [documentation + website](http://lieberinstitute.github.io/spatialLIBD) is + automatically updated thanks to + *[pkgdown](https://CRAN.R-project.org/package=pkgdown)*. +- The code is styled automatically thanks to + *[styler](https://CRAN.R-project.org/package=styler)*. +- The documentation is formatted thanks to + *[devtools](https://CRAN.R-project.org/package=devtools)* and + *[roxygen2](https://CRAN.R-project.org/package=roxygen2)*. + +For more details, check the `dev` directory. + +This package was developed using +*[biocthis](https://bioconductor.org/packages/3.19/biocthis)*. + + + +
+ +
+ + + From f9d7c4b9450f1f272f5202371a89a4d5412a660c Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 24 May 2024 00:52:02 -0400 Subject: [PATCH 143/259] v1.17.1 --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 59d21beb..b3daacc4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.0 -Date: 2024-04-19 +Version: 1.17.1 +Date: 2024-05-24 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From cb1591ecd26f529a31b603c029baa82db8171989 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 24 May 2024 00:53:41 -0400 Subject: [PATCH 144/259] Check on R 4.4 and bioc 3.19 on GHA --- .github/workflows/check-bioc.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index 2b37d332..1ce169dc 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -52,9 +52,9 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-latest, r: '4.3', bioc: '3.18', cont: "bioconductor/bioconductor_docker:RELEASE_3_18", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } - - { os: macOS-latest, r: '4.3', bioc: '3.18'} - - { os: windows-latest, r: '4.3', bioc: '3.18'} + - { os: ubuntu-latest, r: '4.4', bioc: '3.19', cont: "bioconductor/bioconductor_docker:RELEASE_3_19", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } + - { os: macOS-latest, r: '4.4', bioc: '3.19'} + - { os: windows-latest, r: '4.4', bioc: '3.19'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent env: @@ -105,16 +105,16 @@ jobs: uses: actions/cache@v3 with: path: ${{ env.R_LIBS_USER }} - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4- - name: Cache R packages on Linux if: "!contains(github.event.head_commit.message, '/nocache') && runner.os == 'Linux' " uses: actions/cache@v3 with: path: /home/runner/work/_temp/Library - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4- # - name: Install Linux system dependencies # if: runner.os == 'Linux' @@ -221,7 +221,7 @@ jobs: rcmdcheck::rcmdcheck( args = c("--no-manual", "--no-vignettes", "--timings"), build_args = c("--no-manual", "--keep-empty-dirs", "--no-resave-data"), - error_on = "error", + error_on = "warning", check_dir = "check" ) shell: Rscript {0} @@ -253,7 +253,7 @@ jobs: - name: Test coverage if: github.ref == 'refs/heads/devel' && env.run_covr == 'true' && runner.os == 'Linux' run: | - covr::codecov() + covr::codecov(coverage = covr::package_coverage(type = "all")) shell: Rscript {0} - name: Install package @@ -286,7 +286,7 @@ jobs: if: failure() uses: actions/upload-artifact@master with: - name: ${{ runner.os }}-biocversion-RELEASE_3_18-r-4.3-results + name: ${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4-results path: check From 45b22bcf2a9c2b701e4ea7bf296921a36a998dad Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 24 May 2024 01:59:28 -0400 Subject: [PATCH 145/259] ignore macOS build for now due to upstream issue with SparseArray --- .github/workflows/check-bioc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index 1ce169dc..9f88c52b 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -53,7 +53,7 @@ jobs: matrix: config: - { os: ubuntu-latest, r: '4.4', bioc: '3.19', cont: "bioconductor/bioconductor_docker:RELEASE_3_19", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } - - { os: macOS-latest, r: '4.4', bioc: '3.19'} + # - { os: macOS-latest, r: '4.4', bioc: '3.19'} - { os: windows-latest, r: '4.4', bioc: '3.19'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent From e9d6e3a4219da2765dbb08d4fd1994dfdca0084e Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 24 May 2024 13:23:49 -0400 Subject: [PATCH 146/259] Update citation info for Visium_SPG_AD --- README.md | 12 ++++++------ inst/CITATION | 6 +++--- inst/app/www/README.md | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 23a0513e..c4c49cd2 100644 --- a/README.md +++ b/README.md @@ -334,9 +334,9 @@ print(citation("spatialLIBD"), bibtex = TRUE) #> Hicks SC, Martinowich K, Maynard KR, Collado-Torres L (2023). #> "Influence of Alzheimer’s disease related neuropathology on local #> microenvironment gene expression in the human inferior temporal -#> cortex." _bioRxiv_. doi:10.1101/2023.04.20.537710 -#> , -#> . +#> cortex." _GEN Biotechnology_. doi:10.1089/genbio.2023.0019 +#> , +#> . #> #> A BibTeX entry for LaTeX users is #> @@ -344,9 +344,9 @@ print(citation("spatialLIBD"), bibtex = TRUE) #> title = {Influence of Alzheimer’s disease related neuropathology on local microenvironment gene expression in the human inferior temporal cortex}, #> author = {Sang Ho Kwon and Sowmya Parthiban and Madhavi Tippani and Heena R. Divecha and Nicholas J. Eagles and Jashandeep S. Lobana and Stephen R. Williams and Michelle Mark and Rahul A. Bharadwaj and Joel E. Kleinman and Thomas M. Hyde and Stephanie C. Page and Stephanie C. Hicks and Keri Martinowich and Kristen R. Maynard and Leonardo Collado-Torres}, #> year = {2023}, -#> journal = {bioRxiv}, -#> doi = {10.1101/2023.04.20.537710}, -#> url = {https://www.biorxiv.org/content/10.1101/2023.04.20.537710v1}, +#> journal = {GEN Biotechnology}, +#> doi = {10.1089/genbio.2023.0019}, +#> url = {https://doi.org/10.1089/genbio.2023.0019}, #> } ``` diff --git a/inst/CITATION b/inst/CITATION index bc6d454d..e10fdcf2 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -98,8 +98,8 @@ c( as.person("Leonardo Collado-Torres") ), year = 2023, - journal = "bioRxiv", - doi = "10.1101/2023.04.20.537710", - url = "https://www.biorxiv.org/content/10.1101/2023.04.20.537710v1" + journal = "GEN Biotechnology", + doi = "10.1089/genbio.2023.0019", + url = "https://doi.org/10.1089/genbio.2023.0019" ) ) diff --git a/inst/app/www/README.md b/inst/app/www/README.md index adb3c1b8..8c3e846b 100644 --- a/inst/app/www/README.md +++ b/inst/app/www/README.md @@ -344,9 +344,9 @@ print(citation("spatialLIBD"), bibtex = TRUE) #> title = {Influence of Alzheimer’s disease related neuropathology on local microenvironment gene expression in the human inferior temporal cortex}, #> author = {Sang Ho Kwon and Sowmya Parthiban and Madhavi Tippani and Heena R. Divecha and Nicholas J. Eagles and Jashandeep S. Lobana and Stephen R. Williams and Michelle Mark and Rahul A. Bharadwaj and Joel E. Kleinman and Thomas M. Hyde and Stephanie C. Page and Stephanie C. Hicks and Keri Martinowich and Kristen R. Maynard and Leonardo Collado-Torres}, #> year = {2023}, -#> journal = {bioRxiv}, -#> doi = {10.1101/2023.04.20.537710}, -#> url = {https://www.biorxiv.org/content/10.1101/2023.04.20.537710v1}, +#> journal = {GEN Biotechnology}, +#> doi = {10.1089/genbio.2023.0019}, +#> url = {https://doi.org/10.1089/genbio.2023.0019}, #> } ``` From e0947a28ead1828714d037be977fbdd5a48005d5 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 24 May 2024 13:36:03 -0400 Subject: [PATCH 147/259] v1.17.2 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index b3daacc4..a0ebcbcf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.1 +Version: 1.17.2 Date: 2024-05-24 Authors@R: c( From 943f2f756e95a75edcd6ca692005fbaefc53c68a Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 31 May 2024 16:25:54 -0400 Subject: [PATCH 148/259] fix sscran typo --- R/add_qc_metrics.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index 01067f87..699fe0f8 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -86,7 +86,7 @@ add_qc_metrics <- function(spe) { ## low_n_features spe$scran_low_n_features <- NA spe$scran_low_n_features[which(spe$in_tissue)] <- qcfilter$low_n_features - spe$sscran_low_n_features <- factor(spe$scran_low_n_features, + spe$scran_low_n_features <- factor(spe$scran_low_n_features, levels = c("TRUE", "FALSE") ) From 018bde0278aa17fdfe13f4370f71079a0ea4f184 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 6 Jun 2024 13:55:09 -0400 Subject: [PATCH 149/259] Add a check and test for legitimate spatial coordinates --- R/vis_gene.R | 8 ++++++++ tests/testthat/test-vis_gene.R | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/R/vis_gene.R b/R/vis_gene.R index 594940af..1165cb18 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -192,6 +192,14 @@ vis_gene <- stop(sprintf("'%s' is not an assay in 'spe'", assayname), call. = FALSE) } + # Check validity of spatial coordinates + if (!setequal(c("pxl_col_in_fullres", "pxl_row_in_fullres"), colnames(spatialCoords(spe)))) { + stop( + "Abnormal spatial coordinates: should have 'pxl_row_in_fullres' and 'pxl_col_in_fullres' columns.", + call. = FALSE + ) + } + spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/tests/testthat/test-vis_gene.R b/tests/testthat/test-vis_gene.R index 27a8dfdd..dbe850e8 100644 --- a/tests/testthat/test-vis_gene.R +++ b/tests/testthat/test-vis_gene.R @@ -51,5 +51,12 @@ test_that( class(vis_gene(spe, geneid = c("sum_umi", rownames(spe)[1]))), c("gg", "ggplot") ) + + # Bad spatialCoords + colnames(spatialCoords(spe)) = c('a', 'b') + expect_error( + { p <- vis_gene(spe, geneid = "sum_umi") }, + "^Abnormal spatial coordinates" + ) } ) From 397de084ffb9f09492908e38adacfd59a58110b7 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 6 Jun 2024 14:25:13 -0400 Subject: [PATCH 150/259] Add and document an 'is_stitched' parameter; add checks and tests related to colData columns it will operate on --- R/vis_gene.R | 31 +++++++++++++++++++++++++++++++ man/vis_gene.Rd | 8 ++++++++ tests/testthat/test-vis_gene.R | 18 ++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/R/vis_gene.R b/R/vis_gene.R index 1165cb18..c74b4f7e 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -36,6 +36,12 @@ #' the proportion of continuous variables with positive values for each spot is #' computed. For more details, check the multi gene vignette at #' . +#' @param is_stitched A \code{logical(1)} vector: If true, expects a +#' \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +#' ; in +#' particular, expects a logical colData column \code{exclude_overlapping} +#' specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} +#' when TRUE. #' #' @return A [ggplot2][ggplot2::ggplot] object. #' @export @@ -172,6 +178,7 @@ vis_gene <- auto_crop = TRUE, na_color = "#CCCCCC40", multi_gene_method = c("z_score", "pca", "sparsity"), + is_stitched = FALSE, ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' @@ -201,6 +208,30 @@ vis_gene <- } spe_sub <- spe[, spe$sample_id == sampleid] + + if (is_stitched) { + # State assumptions about columns expected to be in the colData + expected_cols <- c("array_row", "array_col", "exclude_overlapping") + if (!all(expected_cols %in% colnames(colData(spe)))) { + stop( + sprintf( + 'Missing at least one of the following colData columns: "%s"', + paste(expected_cols, collapse = '", "') + ) + ) + } + + # Drop excluded spots; verify some spots are not excluded + subset_cols = !spe$exclude_overlapping + if (length(which(subset_cols)) == 0) { + stop( + "spe$exclude_overlapping must include some FALSE values to plot", + call. = FALSE + ) + } + spe_sub <- spe_sub[, subset_cols] + } + d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) # Verify legitimacy of names in geneid diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index 644c8afe..0c46ef8c 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -20,6 +20,7 @@ vis_gene( auto_crop = TRUE, na_color = "#CCCCCC40", multi_gene_method = c("z_score", "pca", "sparsity"), + is_stitched = FALSE, ... ) } @@ -92,6 +93,13 @@ the proportion of continuous variables with positive values for each spot is computed. For more details, check the multi gene vignette at \url{https://research.libd.org/spatialLIBD/articles/multi_gene_plots.html}.} +\item{is_stitched}{A \code{logical(1)} vector: If true, expects a +\code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +\url{http://research.libd.org/visiumStitched/reference/build_spe.html}; in +particular, expects a logical colData column \code{exclude_overlapping} +specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} +when TRUE.} + \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} } diff --git a/tests/testthat/test-vis_gene.R b/tests/testthat/test-vis_gene.R index dbe850e8..abdefad2 100644 --- a/tests/testthat/test-vis_gene.R +++ b/tests/testthat/test-vis_gene.R @@ -46,12 +46,30 @@ test_that( "Could not find the 'geneid'\\(s\\) aaa" ) + # Missing exclude_overlapping + expect_error( + { + p <- vis_gene(spe, geneid = "sum_umi", is_stitched = TRUE) + }, + "^Missing at least one of the following colData" + ) + + # Can't exclude all spots + spe$exclude_overlapping = TRUE + expect_error( + { + p <- vis_gene(spe, geneid = "sum_umi", is_stitched = TRUE) + }, + "^spe\\$exclude_overlapping must include some FALSE values to plot$" + ) + # Trivially check success with legitimate input expect_equal( class(vis_gene(spe, geneid = c("sum_umi", rownames(spe)[1]))), c("gg", "ggplot") ) + # Bad spatialCoords colnames(spatialCoords(spe)) = c('a', 'b') expect_error( From 15060fb7046938dbb0d363e148fcbfb2b6c8c10b Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 6 Jun 2024 15:15:06 -0400 Subject: [PATCH 151/259] Small fixes from interactively testing --- R/vis_gene.R | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index c74b4f7e..2c241897 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -212,7 +212,7 @@ vis_gene <- if (is_stitched) { # State assumptions about columns expected to be in the colData expected_cols <- c("array_row", "array_col", "exclude_overlapping") - if (!all(expected_cols %in% colnames(colData(spe)))) { + if (!all(expected_cols %in% colnames(colData(spe_sub)))) { stop( sprintf( 'Missing at least one of the following colData columns: "%s"', @@ -222,7 +222,7 @@ vis_gene <- } # Drop excluded spots; verify some spots are not excluded - subset_cols = !spe$exclude_overlapping + subset_cols = !spe_sub$exclude_overlapping if (length(which(subset_cols)) == 0) { stop( "spe$exclude_overlapping must include some FALSE values to plot", @@ -230,6 +230,33 @@ vis_gene <- ) } spe_sub <- spe_sub[, subset_cols] + + # Compute an appropriate spot size for this sample + + # Determine some pixel values for the horizontal bounds of the spots + MIN_COL <- min(spatialCoords(spe_sub)[, "pxl_row_in_fullres"]) + MAX_COL <- max(spatialCoords(spe_sub)[, "pxl_row_in_fullres"]) + + # The distance between spots (in pixels) is double the average distance + # between array columns + INTER_SPOT_DIST_PX <- 2 * (MAX_COL - MIN_COL) / + (max(spe_sub$array_col) - min(spe_sub$array_col)) + + # Find the appropriate spot size for this donor. This can vary because + # ggplot downscales a plot to fit desired output dimensions (in this + # case presumably a square region on a PDF), and stitched images can vary + # in aspect ratio. Also, lowres images always have a larger image + # dimension of 1200, no matter how many spots fit in either dimension. + small_image_data <- imgData(spe_sub)[ + imgData(spe_sub)$image_id == image_id, + ] + + # The coefficient of 100 was determined empirically + point_size <- point_size * 100 * INTER_SPOT_DIST_PX * + small_image_data$scaleFactor / max(dim(small_image_data$data[[1]])) + + # Frame limits are poorly defined for stitched data + auto_crop = FALSE } d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) From 1f8a9287d71b81fa23a3dae906ef475260e9a9ab Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 6 Jun 2024 15:21:07 -0400 Subject: [PATCH 152/259] Add a check for NAs --- R/vis_gene.R | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/R/vis_gene.R b/R/vis_gene.R index 2c241897..cf2379c4 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -217,10 +217,15 @@ vis_gene <- sprintf( 'Missing at least one of the following colData columns: "%s"', paste(expected_cols, collapse = '", "') - ) + ), + call. = FALSE ) } + if(any(is.na(spe_sub$exclude_overlapping))) { + stop("spe$exclude_overlapping must not have NAs", call. = FALSE) + } + # Drop excluded spots; verify some spots are not excluded subset_cols = !spe_sub$exclude_overlapping if (length(which(subset_cols)) == 0) { From b6458a5df8ba926b261d1a2982c5f405f122b288 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 7 Jun 2024 11:14:01 -0400 Subject: [PATCH 153/259] Export processing of stitched data into its own function, since it will be used by both vis_gene() and vis_clus(), and involves many lines of code --- NAMESPACE | 1 + R/prep_stitched_data.R | 75 +++++++++++++++++++++++++++++++++++++++ R/vis_gene.R | 53 +++------------------------ man/prep_stitched_data.Rd | 37 +++++++++++++++++++ 4 files changed, 117 insertions(+), 49 deletions(-) create mode 100644 R/prep_stitched_data.R create mode 100644 man/prep_stitched_data.Rd diff --git a/NAMESPACE b/NAMESPACE index d18236fa..8b8698aa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -48,6 +48,7 @@ export(vis_grid_gene) import(ExperimentHub) import(MatrixGenerics) import(SingleCellExperiment) +import(SpatialExperiment) import(ggplot2) import(grid) import(paletteer) diff --git a/R/prep_stitched_data.R b/R/prep_stitched_data.R new file mode 100644 index 00000000..1b46a44f --- /dev/null +++ b/R/prep_stitched_data.R @@ -0,0 +1,75 @@ +#' Prepare stitched data for plotting +#' +#' Given a \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +#' , drop +#' exluded spots (specified by \code{spe$exclude_overlapping}) and compute an +#' appropriate spot size for plotting with \code{vis_gene()} or +#' \code{vis_clus()}, assuming the plot will be written to a PDF of default +#' dimensions (i.e. \code{width = 7} and \code{height = 7}). +#' +#' @param spe A \code{SpatialExperiment} built with +#' \code{visiumStitched::build_spe()}, containing a logical +#' \code{spe$exclude_overlapping} column specifying which spots to display in +#' plots +#' @inheritParams vis_clus +#' +#' @return A list with names \code{spe} and \code{point_size} containing a +#' filtered, ready-to-plot \code{SpatialExperiment} and an appopriate spot size +#' (passed to \code{vis_gene()} or \code{vis_clus()}), respectively +#' +#' @import SpatialExperiment +#' @author Nicholas J. Eagles +#' @keywords internal +prep_stitched_data = function(spe, point_size, image_id) { + # State assumptions about columns expected to be in the colData + expected_cols <- c("array_row", "array_col", "exclude_overlapping") + if (!all(expected_cols %in% colnames(colData(spe)))) { + stop( + sprintf( + 'Missing at least one of the following colData columns: "%s"', + paste(expected_cols, collapse = '", "') + ), + call. = FALSE + ) + } + + if(any(is.na(spe$exclude_overlapping))) { + stop("spe$exclude_overlapping must not have NAs", call. = FALSE) + } + + # Drop excluded spots; verify some spots are not excluded + subset_cols = !spe$exclude_overlapping + if (length(which(subset_cols)) == 0) { + stop( + "spe$exclude_overlapping must include some FALSE values to plot", + call. = FALSE + ) + } + spe <- spe[, subset_cols] + + # Compute an appropriate spot size for this sample + + # Determine some pixel values for the horizontal bounds of the spots + MIN_COL <- min(spatialCoords(spe)[, "pxl_row_in_fullres"]) + MAX_COL <- max(spatialCoords(spe)[, "pxl_row_in_fullres"]) + + # The distance between spots (in pixels) is double the average distance + # between array columns + INTER_SPOT_DIST_PX <- 2 * (MAX_COL - MIN_COL) / + (max(spe$array_col) - min(spe$array_col)) + + # Find the appropriate spot size for this donor. This can vary because + # ggplot downscales a plot to fit desired output dimensions (in this + # case presumably a square region on a PDF), and stitched images can vary + # in aspect ratio. Also, lowres images always have a larger image + # dimension of 1200, no matter how many spots fit in either dimension. + small_image_data <- imgData(spe)[ + imgData(spe)$image_id == image_id, + ] + + # The coefficient of 100 was determined empirically + point_size <- point_size * 100 * INTER_SPOT_DIST_PX * + small_image_data$scaleFactor / max(dim(small_image_data$data[[1]])) + + return(list(spe = spe, point_size = point_size)) +} diff --git a/R/vis_gene.R b/R/vis_gene.R index cf2379c4..7f6e992d 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -210,55 +210,10 @@ vis_gene <- spe_sub <- spe[, spe$sample_id == sampleid] if (is_stitched) { - # State assumptions about columns expected to be in the colData - expected_cols <- c("array_row", "array_col", "exclude_overlapping") - if (!all(expected_cols %in% colnames(colData(spe_sub)))) { - stop( - sprintf( - 'Missing at least one of the following colData columns: "%s"', - paste(expected_cols, collapse = '", "') - ), - call. = FALSE - ) - } - - if(any(is.na(spe_sub$exclude_overlapping))) { - stop("spe$exclude_overlapping must not have NAs", call. = FALSE) - } - - # Drop excluded spots; verify some spots are not excluded - subset_cols = !spe_sub$exclude_overlapping - if (length(which(subset_cols)) == 0) { - stop( - "spe$exclude_overlapping must include some FALSE values to plot", - call. = FALSE - ) - } - spe_sub <- spe_sub[, subset_cols] - - # Compute an appropriate spot size for this sample - - # Determine some pixel values for the horizontal bounds of the spots - MIN_COL <- min(spatialCoords(spe_sub)[, "pxl_row_in_fullres"]) - MAX_COL <- max(spatialCoords(spe_sub)[, "pxl_row_in_fullres"]) - - # The distance between spots (in pixels) is double the average distance - # between array columns - INTER_SPOT_DIST_PX <- 2 * (MAX_COL - MIN_COL) / - (max(spe_sub$array_col) - min(spe_sub$array_col)) - - # Find the appropriate spot size for this donor. This can vary because - # ggplot downscales a plot to fit desired output dimensions (in this - # case presumably a square region on a PDF), and stitched images can vary - # in aspect ratio. Also, lowres images always have a larger image - # dimension of 1200, no matter how many spots fit in either dimension. - small_image_data <- imgData(spe_sub)[ - imgData(spe_sub)$image_id == image_id, - ] - - # The coefficient of 100 was determined empirically - point_size <- point_size * 100 * INTER_SPOT_DIST_PX * - small_image_data$scaleFactor / max(dim(small_image_data$data[[1]])) + # Drop excluded spots and calculate an appropriate point size + temp = prep_stitched_data(spe_sub, point_size, image_id) + spe_sub = temp$spe + point_size = temp$point_size # Frame limits are poorly defined for stitched data auto_crop = FALSE diff --git a/man/prep_stitched_data.Rd b/man/prep_stitched_data.Rd new file mode 100644 index 00000000..3266806f --- /dev/null +++ b/man/prep_stitched_data.Rd @@ -0,0 +1,37 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/prep_stitched_data.R +\name{prep_stitched_data} +\alias{prep_stitched_data} +\title{Prepare stitched data for plotting} +\usage{ +prep_stitched_data(spe, point_size, image_id) +} +\arguments{ +\item{spe}{A \code{SpatialExperiment} built with +\code{visiumStitched::build_spe()}, containing a logical +\code{spe$exclude_overlapping} column specifying which spots to display in +plots} + +\item{point_size}{A \code{numeric(1)} specifying the size of the points. Defaults +to \code{1.25}. Some colors look better if you use \code{2} for instance.} + +\item{image_id}{A \code{character(1)} with the name of the image ID you want to +use in the background.} +} +\value{ +A list with names \code{spe} and \code{point_size} containing a +filtered, ready-to-plot \code{SpatialExperiment} and an appopriate spot size +(passed to \code{vis_gene()} or \code{vis_clus()}), respectively +} +\description{ +Given a \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +\url{http://research.libd.org/visiumStitched/reference/build_spe.html}, drop +exluded spots (specified by \code{spe$exclude_overlapping}) and compute an +appropriate spot size for plotting with \code{vis_gene()} or +\code{vis_clus()}, assuming the plot will be written to a PDF of default +dimensions (i.e. \code{width = 7} and \code{height = 7}). +} +\author{ +Nicholas J. Eagles +} +\keyword{internal} From d4e826e0c7fbbca2133da56002b46d00c53e7bc2 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 7 Jun 2024 11:24:54 -0400 Subject: [PATCH 154/259] Move tests originally performed in vis_gene() to the prep_stitched_data() tests, where applicable --- tests/testthat/test-prep_stitched_data.R | 30 ++++++++++++++++++++++++ tests/testthat/test-vis_gene.R | 17 -------------- 2 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 tests/testthat/test-prep_stitched_data.R diff --git a/tests/testthat/test-prep_stitched_data.R b/tests/testthat/test-prep_stitched_data.R new file mode 100644 index 00000000..1c527b78 --- /dev/null +++ b/tests/testthat/test-prep_stitched_data.R @@ -0,0 +1,30 @@ +test_that( + "prep_stitched_data", + { + if (!exists("spe")) spe <- fetch_data("spe") + + # Missing exclude_overlapping + expect_error( + { + temp <- prep_stitched_data( + spe, point_size = 2, image_id = "lowres" + ) + }, + "^Missing at least one of the following colData" + ) + + # Can't exclude all spots + spe$exclude_overlapping = TRUE + expect_error( + { + temp <- prep_stitched_data( + spe, point_size = 2, image_id = "lowres" + ) + }, + "^spe\\$exclude_overlapping must include some FALSE values to plot$" + ) + + # Note bad image_id is not tested, since this function is only used + # internally after checks for legitimate image_id are performed + } +) diff --git a/tests/testthat/test-vis_gene.R b/tests/testthat/test-vis_gene.R index abdefad2..f882f344 100644 --- a/tests/testthat/test-vis_gene.R +++ b/tests/testthat/test-vis_gene.R @@ -46,23 +46,6 @@ test_that( "Could not find the 'geneid'\\(s\\) aaa" ) - # Missing exclude_overlapping - expect_error( - { - p <- vis_gene(spe, geneid = "sum_umi", is_stitched = TRUE) - }, - "^Missing at least one of the following colData" - ) - - # Can't exclude all spots - spe$exclude_overlapping = TRUE - expect_error( - { - p <- vis_gene(spe, geneid = "sum_umi", is_stitched = TRUE) - }, - "^spe\\$exclude_overlapping must include some FALSE values to plot$" - ) - # Trivially check success with legitimate input expect_equal( class(vis_gene(spe, geneid = c("sum_umi", rownames(spe)[1]))), From d23f5b60a126b598f1670c81990294c1ec293af9 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 7 Jun 2024 11:30:26 -0400 Subject: [PATCH 155/259] Further check legitimacy of prep_stitched_data() output --- tests/testthat/test-prep_stitched_data.R | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/testthat/test-prep_stitched_data.R b/tests/testthat/test-prep_stitched_data.R index 1c527b78..f4206547 100644 --- a/tests/testthat/test-prep_stitched_data.R +++ b/tests/testthat/test-prep_stitched_data.R @@ -24,6 +24,14 @@ test_that( "^spe\\$exclude_overlapping must include some FALSE values to plot$" ) + # Output should be a list with the correct names, and the + # SpatialExperiment should have no excluded spots + spe$exclude_overlapping[1:100] = FALSE + temp <- prep_stitched_data(spe, point_size = 2, image_id = "lowres") + expect_equal(class(temp), 'list') + expect_equal(names(temp), c('spe', 'point_size')) + expect_equal(all(temp$spe$exclude_overlapping), FALSE) + # Note bad image_id is not tested, since this function is only used # internally after checks for legitimate image_id are performed } From 5c5c94ef0dcb2f643d91cfe3602edf200822a75c Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 7 Jun 2024 11:36:38 -0400 Subject: [PATCH 156/259] Add a check for legitimate spatialCoords in vis_clus() --- R/vis_clus.R | 8 ++++++++ tests/testthat/test-vis_clus.R | 13 +++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/testthat/test-vis_clus.R diff --git a/R/vis_clus.R b/R/vis_clus.R index 5e1cfc1a..9012263e 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -130,6 +130,14 @@ vis_clus <- function(spe, ) } + # Check validity of spatial coordinates + if (!setequal(c("pxl_col_in_fullres", "pxl_row_in_fullres"), colnames(spatialCoords(spe)))) { + stop( + "Abnormal spatial coordinates: should have 'pxl_row_in_fullres' and 'pxl_col_in_fullres' columns.", + call. = FALSE + ) + } + spe_sub <- spe[, spe$sample_id == sampleid] d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/tests/testthat/test-vis_clus.R b/tests/testthat/test-vis_clus.R new file mode 100644 index 00000000..4870342b --- /dev/null +++ b/tests/testthat/test-vis_clus.R @@ -0,0 +1,13 @@ +test_that( + "vis_clus", + { + if (!exists("spe")) spe <- fetch_data("spe") + + # Bad spatialCoords + colnames(spatialCoords(spe)) = c('a', 'b') + expect_error( + { p <- vis_clus(spe, clustervar = "sample_id") }, + "^Abnormal spatial coordinates" + ) + } +) From 813bcac6c67054fae1248c565ec43e65d18456b6 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 7 Jun 2024 11:44:12 -0400 Subject: [PATCH 157/259] Add support for plotting stitched data with vis_clus() --- R/vis_clus.R | 18 ++++++++++++++++++ R/vis_gene.R | 6 ------ man/vis_clus.Rd | 8 ++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/R/vis_clus.R b/R/vis_clus.R index 9012263e..c7534f34 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -29,6 +29,12 @@ #' alpha blending already, which will make non-NA values pop up more and the NA #' values will show with a lighter color. This behavior is lost when `alpha` is #' set to a non-`NA` value. +#' @param is_stitched A \code{logical(1)} vector: If true, expects a +#' \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +#' ; in +#' particular, expects a logical colData column \code{exclude_overlapping} +#' specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} +#' when TRUE. #' @param ... Passed to [paste0()][base::paste] for making the title of the #' plot following the `sampleid`. #' @@ -116,6 +122,7 @@ vis_clus <- function(spe, point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + is_stitched = FALSE, ...) { # Verify existence and legitimacy of 'sampleid' if ( @@ -139,6 +146,17 @@ vis_clus <- function(spe, } spe_sub <- spe[, spe$sample_id == sampleid] + + if (is_stitched) { + # Drop excluded spots and calculate an appropriate point size + temp = prep_stitched_data(spe_sub, point_size, image_id) + spe_sub = temp$spe + point_size = temp$point_size + + # Frame limits are poorly defined for stitched data + auto_crop = FALSE + } + d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) vis_clus_p( diff --git a/R/vis_gene.R b/R/vis_gene.R index 7f6e992d..510932ec 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -36,12 +36,6 @@ #' the proportion of continuous variables with positive values for each spot is #' computed. For more details, check the multi gene vignette at #' . -#' @param is_stitched A \code{logical(1)} vector: If true, expects a -#' \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} -#' ; in -#' particular, expects a logical colData column \code{exclude_overlapping} -#' specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} -#' when TRUE. #' #' @return A [ggplot2][ggplot2::ggplot] object. #' @export diff --git a/man/vis_clus.Rd b/man/vis_clus.Rd index 3354bfb4..6ad8c28c 100644 --- a/man/vis_clus.Rd +++ b/man/vis_clus.Rd @@ -16,6 +16,7 @@ vis_clus( point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + is_stitched = FALSE, ... ) } @@ -59,6 +60,13 @@ alpha blending already, which will make non-NA values pop up more and the NA values will show with a lighter color. This behavior is lost when \code{alpha} is set to a non-\code{NA} value.} +\item{is_stitched}{A \code{logical(1)} vector: If true, expects a +\code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +\url{http://research.libd.org/visiumStitched/reference/build_spe.html}; in +particular, expects a logical colData column \code{exclude_overlapping} +specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} +when TRUE.} + \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} } From e13ed4dd0c71ce2ac6f2aa3b30ab39292869ce02 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Mon, 10 Jun 2024 14:17:31 -0400 Subject: [PATCH 158/259] Update QC col in test --- tests/testthat/test-add_qc_metrics.R | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-add_qc_metrics.R b/tests/testthat/test-add_qc_metrics.R index 9985bbb6..39d39a0a 100644 --- a/tests/testthat/test-add_qc_metrics.R +++ b/tests/testthat/test-add_qc_metrics.R @@ -6,6 +6,9 @@ test_that( # run metrics spe spe_qc <- add_qc_metrics(spe) expect_equal(ncol(spe), ncol(spe_qc)) ## same number of spots - expect_equal(ncol(colData(spe)) + 8, ncol(colData(spe_qc))) ## add 8 QC cols to colData + expect_equal(ncol(colData(spe)) + 7, ncol(colData(spe_qc))) ## add 7 QC cols to colData + # [1] "scran_discard" "scran_low_lib_size" "scran_low_n_features" + # [4] "scran_high_subsets_Mito_percent" "edge_spot" "edge_distance" + # [7] "scran_low_lib_size_edge" } ) From 3b6fbc587b5019a1a703d7cb0b5aed429ee373c0 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Tue, 11 Jun 2024 10:10:03 -0400 Subject: [PATCH 159/259] Add metadata and a script to generate it for the Visium LS data --- inst/extdata/metadata_Visium_LS.csv | 3 + inst/scripts/make-metadata_Visium_LS.R | 184 +++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 inst/extdata/metadata_Visium_LS.csv create mode 100644 inst/scripts/make-metadata_Visium_LS.R diff --git a/inst/extdata/metadata_Visium_LS.csv b/inst/extdata/metadata_Visium_LS.csv new file mode 100644 index 00000000..b8a150ea --- /dev/null +++ b/inst/extdata/metadata_Visium_LS.csv @@ -0,0 +1,3 @@ +Title,Description,BiocVersion,Genome,SourceType,SourceUrl,SourceVersion,Species,TaxonomyId,Coordinate_1_based,DataProvider,Maintainer,RDataClass,DispatchClass,RDataPath,Tags +Visium_LS_spe,SpatialExperiment object at the spot-level for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.,3.19,GRCh38,GTF,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,SpatialExperiment,Rds,spatialLIBD/spatialLIBD_files/Visium_LS_spe.rds,VisiumLS_Visium_stitched_spatialLIBD +Visium_LS_spaceranger,Spaceranger outputs for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/Visium_LS_spaceranger.zip,VisiumLS_Visium_stitched_spatialLIBD diff --git a/inst/scripts/make-metadata_Visium_LS.R b/inst/scripts/make-metadata_Visium_LS.R new file mode 100644 index 00000000..29a06420 --- /dev/null +++ b/inst/scripts/make-metadata_Visium_LS.R @@ -0,0 +1,184 @@ +library(here) +library(sessioninfo) +library(tidyverse) + +outdir <- "spatialLIBD_files" +pkgname <- "spatialLIBD" + +meta = tibble( + Title = c("Visium_LS_spe", "Visium_LS_spaceranger"), + Description = c( + "SpatialExperiment object at the spot-level for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "Spaceranger outputs for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment." + ), + BiocVersion = "3.19", + Genome = "GRCh38", + SourceType = c("GTF", "Zip"), + SourceUrl = "https://bioconductor.org/packages/spatialLIBD", + SourceVersion = "June 11 2024", + Species = "Homo sapiens", + TaxonomyId = 9606, + Coordinate_1_based = TRUE, + DataProvider = "LIBD", + Maintainer = "Leonardo Collado-Torres ", + RDataClass = c("SpatialExperiment", "list"), + DispatchClass = c("Rds", "Zip"), + RDataPath = file.path( + pkgname, + outdir, + c("Visium_LS_spe.rds", "Visium_LS_spaceranger.zip") + ), + Tags = "VisiumLS_Visium_stitched_spatialLIBD" +) + +write_csv(meta, here("inst", "extdata", "metadata_Visium_LS.csv")) + +## Check interactively +if (FALSE) { + AnnotationHubData::makeAnnotationHubMetadata( + here(), fileName = "metadata_Visium_LS.csv" + ) +} + +## Reproducibility information +print("Reproducibility information:") +Sys.time() +proc.time() +options(width = 120) +session_info() + +# ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +# setting value +# version R version 4.4.0 Patched (2024-05-22 r86590) +# os Rocky Linux 9.2 (Blue Onyx) +# system x86_64, linux-gnu +# ui X11 +# language (EN) +# collate en_US.UTF-8 +# ctype en_US.UTF-8 +# tz US/Eastern +# date 2024-06-11 +# pandoc 3.1.13 @ /jhpce/shared/community/core/conda_R/4.4/bin/pandoc + +# ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +# package * version date (UTC) lib source +# abind 1.4-5 2016-07-21 [2] CRAN (R 4.4.0) +# AnnotationDbi 1.66.0 2024-05-01 [2] Bioconductor 3.19 (R 4.4.0) +# AnnotationForge 1.46.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# AnnotationHub 3.12.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# AnnotationHubData 1.34.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.0) +# Biobase 2.64.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# BiocBaseUtils 1.6.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# BiocCheck 1.40.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# BiocFileCache 2.12.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# BiocGenerics 0.50.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# BiocIO 1.14.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# BiocManager 1.30.23 2024-05-04 [2] CRAN (R 4.4.0) +# BiocParallel 1.38.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# BiocVersion 3.19.1 2024-04-17 [2] Bioconductor 3.19 (R 4.4.0) +# biocViews 1.72.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# biomaRt 2.60.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# Biostrings 2.72.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# bit 4.0.5 2022-11-15 [2] CRAN (R 4.4.0) +# bit64 4.0.5 2020-08-30 [2] CRAN (R 4.4.0) +# bitops 1.0-7 2021-04-24 [2] CRAN (R 4.4.0) +# blob 1.2.4 2023-03-17 [2] CRAN (R 4.4.0) +# cachem 1.1.0 2024-05-16 [2] CRAN (R 4.4.0) +# cli 3.6.2 2023-12-11 [2] CRAN (R 4.4.0) +# codetools 0.2-20 2024-03-31 [3] CRAN (R 4.4.0) +# colorspace 2.1-0 2023-01-23 [2] CRAN (R 4.4.0) +# crayon 1.5.2 2022-09-29 [2] CRAN (R 4.4.0) +# curl 5.2.1 2024-03-01 [2] CRAN (R 4.4.0) +# DBI 1.2.2 2024-02-16 [2] CRAN (R 4.4.0) +# dbplyr 2.5.0 2024-03-19 [2] CRAN (R 4.4.0) +# DelayedArray 0.30.1 2024-05-07 [2] Bioconductor 3.19 (R 4.4.0) +# digest 0.6.35 2024-03-11 [2] CRAN (R 4.4.0) +# dplyr * 1.1.4 2023-11-17 [2] CRAN (R 4.4.0) +# fansi 1.0.6 2023-12-08 [2] CRAN (R 4.4.0) +# fastmap 1.2.0 2024-05-15 [2] CRAN (R 4.4.0) +# filelock 1.0.3 2023-12-11 [2] CRAN (R 4.4.0) +# forcats * 1.0.0 2023-01-29 [2] CRAN (R 4.4.0) +# formatR 1.14 2023-01-17 [2] CRAN (R 4.4.0) +# futile.logger * 1.4.3 2016-07-10 [2] CRAN (R 4.4.0) +# futile.options 1.0.1 2018-04-20 [2] CRAN (R 4.4.0) +# generics 0.1.3 2022-07-05 [2] CRAN (R 4.4.0) +# GenomeInfoDb 1.40.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# GenomeInfoDbData 1.2.12 2024-05-23 [2] Bioconductor +# GenomicAlignments 1.40.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# GenomicFeatures 1.56.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# GenomicRanges 1.56.0 2024-05-01 [2] Bioconductor 3.19 (R 4.4.0) +# ggplot2 * 3.5.1 2024-04-23 [2] CRAN (R 4.4.0) +# glue 1.7.0 2024-01-09 [2] CRAN (R 4.4.0) +# graph 1.82.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# gtable 0.3.5 2024-04-22 [2] CRAN (R 4.4.0) +# here * 1.0.1 2020-12-13 [2] CRAN (R 4.4.0) +# hms 1.1.3 2023-03-21 [2] CRAN (R 4.4.0) +# httr 1.4.7 2023-08-15 [2] CRAN (R 4.4.0) +# httr2 1.0.1 2024-04-01 [2] CRAN (R 4.4.0) +# IRanges 2.38.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# jsonlite 1.8.8 2023-12-04 [2] CRAN (R 4.4.0) +# KEGGREST 1.44.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# knitr 1.46 2024-04-06 [2] CRAN (R 4.4.0) +# lambda.r 1.2.4 2019-09-18 [2] CRAN (R 4.4.0) +# lattice 0.22-6 2024-03-20 [3] CRAN (R 4.4.0) +# lifecycle 1.0.4 2023-11-07 [2] CRAN (R 4.4.0) +# lubridate * 1.9.3 2023-09-27 [2] CRAN (R 4.4.0) +# magrittr 2.0.3 2022-03-30 [2] CRAN (R 4.4.0) +# Matrix 1.7-0 2024-04-26 [3] CRAN (R 4.4.0) +# MatrixGenerics 1.16.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# matrixStats 1.3.0 2024-04-11 [2] CRAN (R 4.4.0) +# memoise 2.0.1 2021-11-26 [2] CRAN (R 4.4.0) +# munsell 0.5.1 2024-04-01 [2] CRAN (R 4.4.0) +# OrganismDbi 1.46.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# pillar 1.9.0 2023-03-22 [2] CRAN (R 4.4.0) +# pkgconfig 2.0.3 2019-09-22 [2] CRAN (R 4.4.0) +# png 0.1-8 2022-11-29 [2] CRAN (R 4.4.0) +# prettyunits 1.2.0 2023-09-24 [2] CRAN (R 4.4.0) +# progress 1.2.3 2023-12-06 [2] CRAN (R 4.4.0) +# purrr * 1.0.2 2023-08-10 [2] CRAN (R 4.4.0) +# R6 2.5.1 2021-08-19 [2] CRAN (R 4.4.0) +# rappdirs 0.3.3 2021-01-31 [2] CRAN (R 4.4.0) +# RBGL 1.80.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# RCurl 1.98-1.14 2024-01-09 [2] CRAN (R 4.4.0) +# readr * 2.1.5 2024-01-10 [2] CRAN (R 4.4.0) +# restfulr 0.0.15 2022-06-16 [2] CRAN (R 4.4.0) +# rjson 0.2.21 2022-01-09 [2] CRAN (R 4.4.0) +# rlang 1.1.3 2024-01-10 [2] CRAN (R 4.4.0) +# rprojroot 2.0.4 2023-11-05 [2] CRAN (R 4.4.0) +# Rsamtools 2.20.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# RSQLite 2.3.6 2024-03-31 [2] CRAN (R 4.4.0) +# rtracklayer 1.64.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# RUnit 0.4.33 2024-02-22 [2] CRAN (R 4.4.0) +# S4Arrays 1.4.1 2024-05-20 [2] Bioconductor 3.19 (R 4.4.0) +# S4Vectors 0.42.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# scales 1.3.0 2023-11-28 [2] CRAN (R 4.4.0) +# sessioninfo * 1.2.2 2021-12-06 [2] CRAN (R 4.4.0) +# SparseArray 1.4.5 2024-05-20 [2] Bioconductor 3.19 (R 4.4.0) +# stringdist 0.9.12 2023-11-28 [2] CRAN (R 4.4.0) +# stringi 1.8.4 2024-05-06 [2] CRAN (R 4.4.0) +# stringr * 1.5.1 2023-11-14 [2] CRAN (R 4.4.0) +# SummarizedExperiment 1.34.0 2024-05-01 [2] Bioconductor 3.19 (R 4.4.0) +# tibble * 3.2.1 2023-03-20 [2] CRAN (R 4.4.0) +# tidyr * 1.3.1 2024-01-24 [2] CRAN (R 4.4.0) +# tidyselect 1.2.1 2024-03-11 [2] CRAN (R 4.4.0) +# tidyverse * 2.0.0 2023-02-22 [2] CRAN (R 4.4.0) +# timechange 0.3.0 2024-01-18 [2] CRAN (R 4.4.0) +# txdbmaker 1.0.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# tzdb 0.4.0 2023-05-12 [2] CRAN (R 4.4.0) +# UCSC.utils 1.0.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# utf8 1.2.4 2023-10-22 [2] CRAN (R 4.4.0) +# vctrs 0.6.5 2023-12-01 [2] CRAN (R 4.4.0) +# vroom 1.6.5 2023-12-05 [2] CRAN (R 4.4.0) +# withr 3.0.0 2024-01-16 [2] CRAN (R 4.4.0) +# xfun 0.44 2024-05-15 [2] CRAN (R 4.4.0) +# XML 3.99-0.16.1 2024-01-22 [2] CRAN (R 4.4.0) +# xml2 1.3.6 2023-12-04 [2] CRAN (R 4.4.0) +# XVector 0.44.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) +# yaml 2.3.8 2023-12-11 [2] CRAN (R 4.4.0) +# zlibbioc 1.50.0 2024-04-30 [2] Bioconductor 3.19 (R 4.4.0) + +# [1] /users/neagles/R/4.4 +# [2] /jhpce/shared/community/core/conda_R/4.4/R/lib64/R/site-library +# [3] /jhpce/shared/community/core/conda_R/4.4/R/lib64/R/library + +# ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── From 0b68372ee92da99a88ba6780db4ca16b119354d3 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 20 Jun 2024 11:34:04 -0400 Subject: [PATCH 160/259] Add ImageJ outputs to the ExperimentHub metadata for the Visium LS data --- inst/extdata/metadata_Visium_LS.csv | 1 + inst/scripts/make-metadata_Visium_LS.R | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/inst/extdata/metadata_Visium_LS.csv b/inst/extdata/metadata_Visium_LS.csv index b8a150ea..5b868cf7 100644 --- a/inst/extdata/metadata_Visium_LS.csv +++ b/inst/extdata/metadata_Visium_LS.csv @@ -1,3 +1,4 @@ Title,Description,BiocVersion,Genome,SourceType,SourceUrl,SourceVersion,Species,TaxonomyId,Coordinate_1_based,DataProvider,Maintainer,RDataClass,DispatchClass,RDataPath,Tags Visium_LS_spe,SpatialExperiment object at the spot-level for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.,3.19,GRCh38,GTF,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,SpatialExperiment,Rds,spatialLIBD/spatialLIBD_files/Visium_LS_spe.rds,VisiumLS_Visium_stitched_spatialLIBD Visium_LS_spaceranger,Spaceranger outputs for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/Visium_LS_spaceranger.zip,VisiumLS_Visium_stitched_spatialLIBD +Visium_LS_ImageJ_out,Stitched PNG image and XML file from aligning lateral septum human brain (LS) spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/Visium_LS_imagej_out.zip,VisiumLS_Visium_stitched_spatialLIBD diff --git a/inst/scripts/make-metadata_Visium_LS.R b/inst/scripts/make-metadata_Visium_LS.R index 29a06420..8771569e 100644 --- a/inst/scripts/make-metadata_Visium_LS.R +++ b/inst/scripts/make-metadata_Visium_LS.R @@ -6,14 +6,15 @@ outdir <- "spatialLIBD_files" pkgname <- "spatialLIBD" meta = tibble( - Title = c("Visium_LS_spe", "Visium_LS_spaceranger"), + Title = c("Visium_LS_spe", "Visium_LS_spaceranger", "Visium_LS_ImageJ_out"), Description = c( "SpatialExperiment object at the spot-level for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", - "Spaceranger outputs for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment." + "Spaceranger outputs for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.", + "Stitched PNG image and XML file from aligning lateral septum human brain (LS) spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package." ), BiocVersion = "3.19", Genome = "GRCh38", - SourceType = c("GTF", "Zip"), + SourceType = c("GTF", "Zip", "Zip"), SourceUrl = "https://bioconductor.org/packages/spatialLIBD", SourceVersion = "June 11 2024", Species = "Homo sapiens", @@ -21,12 +22,15 @@ meta = tibble( Coordinate_1_based = TRUE, DataProvider = "LIBD", Maintainer = "Leonardo Collado-Torres ", - RDataClass = c("SpatialExperiment", "list"), - DispatchClass = c("Rds", "Zip"), + RDataClass = c("SpatialExperiment", "list", "list"), + DispatchClass = c("Rds", "Zip", "Zip"), RDataPath = file.path( pkgname, outdir, - c("Visium_LS_spe.rds", "Visium_LS_spaceranger.zip") + c( + "Visium_LS_spe.rds", "Visium_LS_spaceranger.zip", + "Visium_LS_imagej_out.zip" + ) ), Tags = "VisiumLS_Visium_stitched_spatialLIBD" ) From 2006346e04bfe097437f30388139894c3f6fa86b Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 26 Jun 2024 09:23:16 -0400 Subject: [PATCH 161/259] Fix scran_high_Mito_percent argument name --- R/add_qc_metrics.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index 699fe0f8..5008e304 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -91,11 +91,11 @@ add_qc_metrics <- function(spe) { ) ## high mito percent - spe$scran_high_subsets_Mito_percent <- NA - spe$scran_high_subsets_Mito_percent[which(spe$in_tissue)] <- + spe$scran_high_Mito_percent <- NA + spe$scran_high_Mito_percent[which(spe$in_tissue)] <- qcfilter$high_subsets_Mito_percent - spe$scran_high_subsets_Mito_percent <- - factor(spe$scran_high_subsets_Mito_percent, levels = c("TRUE", "FALSE")) + spe$scran_high_Mito_percent <- + factor(spe$scran_high_Mito_percent, levels = c("TRUE", "FALSE")) ## Find edge spots # define variables From 88a7fb2c0567f9456f8819bbaf8aaf614f01f8f4 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 11:39:41 -0400 Subject: [PATCH 162/259] Reviewed code from https://github.com/LieberInstitute/spatialLIBD/pull/82 Co-authored-by: Nick Eagles --- R/prep_stitched_data.R | 7 +++---- R/vis_clus.R | 12 ++++++------ tests/testthat/test-vis_clus.R | 6 ++++-- tests/testthat/test-vis_gene.R | 6 ++++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/R/prep_stitched_data.R b/R/prep_stitched_data.R index 1b46a44f..2de6c7b2 100644 --- a/R/prep_stitched_data.R +++ b/R/prep_stitched_data.R @@ -2,7 +2,7 @@ #' #' Given a \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} #' , drop -#' exluded spots (specified by \code{spe$exclude_overlapping}) and compute an +#' excluded spots (specified by \code{spe$exclude_overlapping}) and compute an #' appropriate spot size for plotting with \code{vis_gene()} or #' \code{vis_clus()}, assuming the plot will be written to a PDF of default #' dimensions (i.e. \code{width = 7} and \code{height = 7}). @@ -14,10 +14,9 @@ #' @inheritParams vis_clus #' #' @return A list with names \code{spe} and \code{point_size} containing a -#' filtered, ready-to-plot \code{SpatialExperiment} and an appopriate spot size +#' filtered, ready-to-plot \code{SpatialExperiment} and an appropriate spot size #' (passed to \code{vis_gene()} or \code{vis_clus()}), respectively #' -#' @import SpatialExperiment #' @author Nicholas J. Eagles #' @keywords internal prep_stitched_data = function(spe, point_size, image_id) { @@ -70,6 +69,6 @@ prep_stitched_data = function(spe, point_size, image_id) { # The coefficient of 100 was determined empirically point_size <- point_size * 100 * INTER_SPOT_DIST_PX * small_image_data$scaleFactor / max(dim(small_image_data$data[[1]])) - + return(list(spe = spe, point_size = point_size)) } diff --git a/R/vis_clus.R b/R/vis_clus.R index c7534f34..239605b5 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -29,12 +29,12 @@ #' alpha blending already, which will make non-NA values pop up more and the NA #' values will show with a lighter color. This behavior is lost when `alpha` is #' set to a non-`NA` value. -#' @param is_stitched A \code{logical(1)} vector: If true, expects a -#' \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +#' @param is_stitched A \code{logical(1)} vector: If `TRUE`, expects a +#' [SpatialExperiment-class][SpatialExperiment::SpatialExperiment-class] built +#' with `visiumStitched::build_spe()`. #' ; in -#' particular, expects a logical colData column \code{exclude_overlapping} -#' specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} -#' when TRUE. +#' particular, expects a logical colData column `exclude_overlapping` +#' specifying which spots to exclude from the plot. Sets `auto_crop = FALSE`. #' @param ... Passed to [paste0()][base::paste] for making the title of the #' plot following the `sampleid`. #' @@ -152,7 +152,7 @@ vis_clus <- function(spe, temp = prep_stitched_data(spe_sub, point_size, image_id) spe_sub = temp$spe point_size = temp$point_size - + # Frame limits are poorly defined for stitched data auto_crop = FALSE } diff --git a/tests/testthat/test-vis_clus.R b/tests/testthat/test-vis_clus.R index 4870342b..a1d67525 100644 --- a/tests/testthat/test-vis_clus.R +++ b/tests/testthat/test-vis_clus.R @@ -4,10 +4,12 @@ test_that( if (!exists("spe")) spe <- fetch_data("spe") # Bad spatialCoords - colnames(spatialCoords(spe)) = c('a', 'b') + spe_temp <- spe + colnames(spatialCoords(spe_temp)) = c('a', 'b') expect_error( - { p <- vis_clus(spe, clustervar = "sample_id") }, + { p <- vis_clus(spe_temp, clustervar = "sample_id") }, "^Abnormal spatial coordinates" ) + rm(spe_temp) } ) diff --git a/tests/testthat/test-vis_gene.R b/tests/testthat/test-vis_gene.R index f882f344..352bfe1b 100644 --- a/tests/testthat/test-vis_gene.R +++ b/tests/testthat/test-vis_gene.R @@ -54,10 +54,12 @@ test_that( # Bad spatialCoords - colnames(spatialCoords(spe)) = c('a', 'b') + spe_temp <- spe + colnames(spatialCoords(spe_temp)) = c('a', 'b') expect_error( - { p <- vis_gene(spe, geneid = "sum_umi") }, + { p <- vis_gene(spe_temp, geneid = "sum_umi") }, "^Abnormal spatial coordinates" ) + rm(spe_temp) } ) From 5926a32c37f6dbd200a81ee0cbe71a2241e69abc Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 11:40:24 -0400 Subject: [PATCH 163/259] Re-run devtools::document() Co-authored-by: Nick Eagles --- NAMESPACE | 1 - man/prep_stitched_data.Rd | 4 ++-- man/vis_clus.Rd | 8 ++++---- man/vis_gene.Rd | 8 ++++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 8b8698aa..d18236fa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -48,7 +48,6 @@ export(vis_grid_gene) import(ExperimentHub) import(MatrixGenerics) import(SingleCellExperiment) -import(SpatialExperiment) import(ggplot2) import(grid) import(paletteer) diff --git a/man/prep_stitched_data.Rd b/man/prep_stitched_data.Rd index 3266806f..e87c0140 100644 --- a/man/prep_stitched_data.Rd +++ b/man/prep_stitched_data.Rd @@ -20,13 +20,13 @@ use in the background.} } \value{ A list with names \code{spe} and \code{point_size} containing a -filtered, ready-to-plot \code{SpatialExperiment} and an appopriate spot size +filtered, ready-to-plot \code{SpatialExperiment} and an appropriate spot size (passed to \code{vis_gene()} or \code{vis_clus()}), respectively } \description{ Given a \code{SpatialExperiment} built with \code{visiumStitched::build_spe()} \url{http://research.libd.org/visiumStitched/reference/build_spe.html}, drop -exluded spots (specified by \code{spe$exclude_overlapping}) and compute an +excluded spots (specified by \code{spe$exclude_overlapping}) and compute an appropriate spot size for plotting with \code{vis_gene()} or \code{vis_clus()}, assuming the plot will be written to a PDF of default dimensions (i.e. \code{width = 7} and \code{height = 7}). diff --git a/man/vis_clus.Rd b/man/vis_clus.Rd index 6ad8c28c..10729e46 100644 --- a/man/vis_clus.Rd +++ b/man/vis_clus.Rd @@ -60,12 +60,12 @@ alpha blending already, which will make non-NA values pop up more and the NA values will show with a lighter color. This behavior is lost when \code{alpha} is set to a non-\code{NA} value.} -\item{is_stitched}{A \code{logical(1)} vector: If true, expects a -\code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +\item{is_stitched}{A \code{logical(1)} vector: If \code{TRUE}, expects a +\link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} built +with \code{visiumStitched::build_spe()}. \url{http://research.libd.org/visiumStitched/reference/build_spe.html}; in particular, expects a logical colData column \code{exclude_overlapping} -specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} -when TRUE.} +specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE}.} \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index 0c46ef8c..2a6f94e6 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -93,12 +93,12 @@ the proportion of continuous variables with positive values for each spot is computed. For more details, check the multi gene vignette at \url{https://research.libd.org/spatialLIBD/articles/multi_gene_plots.html}.} -\item{is_stitched}{A \code{logical(1)} vector: If true, expects a -\code{SpatialExperiment} built with \code{visiumStitched::build_spe()} +\item{is_stitched}{A \code{logical(1)} vector: If \code{TRUE}, expects a +\link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} built +with \code{visiumStitched::build_spe()}. \url{http://research.libd.org/visiumStitched/reference/build_spe.html}; in particular, expects a logical colData column \code{exclude_overlapping} -specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE} -when TRUE.} +specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE}.} \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} From 3b8794d977709ba2ce9a37b0c5f3d3f84da1219b Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 11:41:28 -0400 Subject: [PATCH 164/259] Auto-styled --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 ++-- R/annotate_registered_clusters.R | 16 ++-- R/check_sce.R | 69 +++++++++-------- R/check_spe.R | 15 ++-- R/fetch_data.R | 41 +++++----- R/frame_limits.R | 21 +++-- R/gene_set_enrichment.R | 11 ++- R/gene_set_enrichment_plot.R | 23 +++--- R/geom_spatial.R | 17 ++--- R/img_edit.R | 37 +++++---- R/img_update.R | 13 ++-- R/img_update_all.R | 11 ++- R/layer_boxplot.R | 27 ++++--- R/layer_matrix_plot.R | 27 ++++--- R/layer_stat_cor.R | 11 ++- R/layer_stat_cor_plot.R | 11 ++- R/prep_stitched_data.R | 6 +- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 +++-- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 ++-- R/registration_stats_anova.R | 17 ++--- R/registration_stats_enrichment.R | 15 ++-- R/registration_stats_pairwise.R | 15 ++-- R/registration_wrapper.R | 19 ++--- R/run_app.R | 97 ++++++++++++------------ R/sig_genes_extract.R | 11 +-- R/sig_genes_extract_all.R | 7 +- R/vis_clus.R | 59 +++++++------- R/vis_clus_p.R | 25 +++--- R/vis_gene.R | 45 +++++------ R/vis_gene_p.R | 35 +++++---- R/vis_grid_clus.R | 33 ++++---- R/vis_grid_gene.R | 37 +++++---- inst/scripts/make-metadata_Visium_LS.R | 5 +- tests/testthat/test-prep_stitched_data.R | 14 ++-- tests/testthat/test-vis_clus.R | 6 +- tests/testthat/test-vis_gene.R | 6 +- 39 files changed, 429 insertions(+), 437 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index dbe49f86..de4f5fee 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,9 +29,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function( - spe, - visium_analysis) { +add10xVisiumAnalysis <- function(spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index e7b09e5c..bfdddbe5 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,13 +43,12 @@ #' )) #' } add_images <- - function( - spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function(spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index 13e1d5ab..c2a9ec43 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,10 +48,9 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function( - cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function(cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -87,11 +86,10 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function( - remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function(remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 1d625342..0d17423b 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,41 +24,40 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function( - sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function(sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index d0344daa..47de3c0a 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,14 +25,13 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function( - spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function(spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index 3426ae6d..cc715e4a 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,26 +84,27 @@ #' #> 172.28 MB #' } fetch_data <- - function(type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function( + type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index 320cc643..b22b5c8a 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,17 +37,16 @@ #' } #' frame_limits <- - function( - spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function(spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index e6b6a63d..1accea28 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,12 +58,11 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function( - gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function(gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index c155e672..4ccbfcbc 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,18 +84,17 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function( - enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function(enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 965db758..64f00cc3 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,15 +58,14 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function( - mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function(mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index 93aceee3..ec6fae90 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,25 +58,24 @@ #' plot(x) #' } img_edit <- - function( - spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function(spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index fdfe5b83..db6dfcb1 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,13 +41,12 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function( - spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 314b9b0d..31c368c9 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,12 +22,11 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function( - spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 6a671a5e..345d5499 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,20 +114,19 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function( - i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function(i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index 4a44fd18..f1530fb1 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,20 +55,19 @@ #' cex = 2 #' ) layer_matrix_plot <- - function( - matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function(matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index f484c912..0ccf0bf2 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,12 +49,11 @@ #' top_n = 10 #' )) layer_stat_cor <- - function( - stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function(stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 0d2653b8..c0f4e924 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,12 +72,11 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function( - cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function(cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/prep_stitched_data.R b/R/prep_stitched_data.R index 2de6c7b2..1485d924 100644 --- a/R/prep_stitched_data.R +++ b/R/prep_stitched_data.R @@ -19,7 +19,7 @@ #' #' @author Nicholas J. Eagles #' @keywords internal -prep_stitched_data = function(spe, point_size, image_id) { +prep_stitched_data <- function(spe, point_size, image_id) { # State assumptions about columns expected to be in the colData expected_cols <- c("array_row", "array_col", "exclude_overlapping") if (!all(expected_cols %in% colnames(colData(spe)))) { @@ -32,12 +32,12 @@ prep_stitched_data = function(spe, point_size, image_id) { ) } - if(any(is.na(spe$exclude_overlapping))) { + if (any(is.na(spe$exclude_overlapping))) { stop("spe$exclude_overlapping must not have NAs", call. = FALSE) } # Drop excluded spots; verify some spots are not excluded - subset_cols = !spe$exclude_overlapping + subset_cols <- !spe$exclude_overlapping if (length(which(subset_cols)) == 0) { stop( "spe$exclude_overlapping must include some FALSE values to plot", diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 70bc49ac..ef76f1d0 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,8 +24,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index d9f31fc2..501a744d 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,17 +44,16 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 6921dbb9..3f36260c 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,10 +24,9 @@ #' head(registration_mod) #' registration_model <- - function( - sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function(sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 2d859e4e..5f3c5dd2 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,12 +51,13 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index d1d0b135..c899459d 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,15 +50,14 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index cd3ee182..d186547e 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,13 +34,14 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index 09bb3ff9..afb9771a 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,13 +32,14 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function(sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 38a1c297..49896d78 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,15 +50,16 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index 93701444..b7beae48 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -186,55 +186,54 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app #' } -run_app <- function( - spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - ...) { +run_app <- function(spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index fac5f65b..b21902c1 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,11 +59,12 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index 0d68b880..d2c3c01f 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,9 +27,10 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index 239605b5..2dae1971 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -99,31 +99,32 @@ #' ) #' print(p4) #' } -vis_clus <- function(spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { +vis_clus <- function( + spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { # Verify existence and legitimacy of 'sampleid' if ( !("sample_id" %in% colnames(colData(spe))) || @@ -149,12 +150,12 @@ vis_clus <- function(spe, if (is_stitched) { # Drop excluded spots and calculate an appropriate point size - temp = prep_stitched_data(spe_sub, point_size, image_id) - spe_sub = temp$spe - point_size = temp$point_size + temp <- prep_stitched_data(spe_sub, point_size, image_id) + spe_sub <- temp$spe + point_size <- temp$point_size # Frame limits are poorly defined for stitched data - auto_crop = FALSE + auto_crop <- FALSE } d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index d2b37cec..a91ce369 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,19 +42,18 @@ #' rm(spe_sub) #' } vis_clus_p <- - function( - spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function(spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 510932ec..6a28af3f 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -158,22 +158,23 @@ #' print(p8) #' } vis_gene <- - function(spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - is_stitched = FALSE, - ...) { + function( + spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + is_stitched = FALSE, + ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' if ( @@ -205,14 +206,14 @@ vis_gene <- if (is_stitched) { # Drop excluded spots and calculate an appropriate point size - temp = prep_stitched_data(spe_sub, point_size, image_id) - spe_sub = temp$spe - point_size = temp$point_size - + temp <- prep_stitched_data(spe_sub, point_size, image_id) + spe_sub <- temp$spe + point_size <- temp$point_size + # Frame limits are poorly defined for stitched data - auto_crop = FALSE + auto_crop <- FALSE } - + d <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) # Verify legitimacy of names in geneid diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 9bc3dc0a..e659d477 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,24 +48,23 @@ #' rm(spe_sub) #' } vis_gene_p <- - function( - spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function(spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 74b4d3ce..6c61cece 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,23 +47,22 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function( - spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index 2504cce5..e21b5bf1 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,25 +35,24 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function( - spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - ...) { + function(spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/inst/scripts/make-metadata_Visium_LS.R b/inst/scripts/make-metadata_Visium_LS.R index 8771569e..9fefe846 100644 --- a/inst/scripts/make-metadata_Visium_LS.R +++ b/inst/scripts/make-metadata_Visium_LS.R @@ -5,7 +5,7 @@ library(tidyverse) outdir <- "spatialLIBD_files" pkgname <- "spatialLIBD" -meta = tibble( +meta <- tibble( Title = c("Visium_LS_spe", "Visium_LS_spaceranger", "Visium_LS_ImageJ_out"), Description = c( "SpatialExperiment object at the spot-level for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", @@ -40,7 +40,8 @@ write_csv(meta, here("inst", "extdata", "metadata_Visium_LS.csv")) ## Check interactively if (FALSE) { AnnotationHubData::makeAnnotationHubMetadata( - here(), fileName = "metadata_Visium_LS.csv" + here(), + fileName = "metadata_Visium_LS.csv" ) } diff --git a/tests/testthat/test-prep_stitched_data.R b/tests/testthat/test-prep_stitched_data.R index f4206547..3866042d 100644 --- a/tests/testthat/test-prep_stitched_data.R +++ b/tests/testthat/test-prep_stitched_data.R @@ -7,18 +7,20 @@ test_that( expect_error( { temp <- prep_stitched_data( - spe, point_size = 2, image_id = "lowres" + spe, + point_size = 2, image_id = "lowres" ) }, "^Missing at least one of the following colData" ) # Can't exclude all spots - spe$exclude_overlapping = TRUE + spe$exclude_overlapping <- TRUE expect_error( { temp <- prep_stitched_data( - spe, point_size = 2, image_id = "lowres" + spe, + point_size = 2, image_id = "lowres" ) }, "^spe\\$exclude_overlapping must include some FALSE values to plot$" @@ -26,10 +28,10 @@ test_that( # Output should be a list with the correct names, and the # SpatialExperiment should have no excluded spots - spe$exclude_overlapping[1:100] = FALSE + spe$exclude_overlapping[1:100] <- FALSE temp <- prep_stitched_data(spe, point_size = 2, image_id = "lowres") - expect_equal(class(temp), 'list') - expect_equal(names(temp), c('spe', 'point_size')) + expect_equal(class(temp), "list") + expect_equal(names(temp), c("spe", "point_size")) expect_equal(all(temp$spe$exclude_overlapping), FALSE) # Note bad image_id is not tested, since this function is only used diff --git a/tests/testthat/test-vis_clus.R b/tests/testthat/test-vis_clus.R index a1d67525..ab011efb 100644 --- a/tests/testthat/test-vis_clus.R +++ b/tests/testthat/test-vis_clus.R @@ -5,9 +5,11 @@ test_that( # Bad spatialCoords spe_temp <- spe - colnames(spatialCoords(spe_temp)) = c('a', 'b') + colnames(spatialCoords(spe_temp)) <- c("a", "b") expect_error( - { p <- vis_clus(spe_temp, clustervar = "sample_id") }, + { + p <- vis_clus(spe_temp, clustervar = "sample_id") + }, "^Abnormal spatial coordinates" ) rm(spe_temp) diff --git a/tests/testthat/test-vis_gene.R b/tests/testthat/test-vis_gene.R index 352bfe1b..b4a171c1 100644 --- a/tests/testthat/test-vis_gene.R +++ b/tests/testthat/test-vis_gene.R @@ -55,9 +55,11 @@ test_that( # Bad spatialCoords spe_temp <- spe - colnames(spatialCoords(spe_temp)) = c('a', 'b') + colnames(spatialCoords(spe_temp)) <- c("a", "b") expect_error( - { p <- vis_gene(spe_temp, geneid = "sum_umi") }, + { + p <- vis_gene(spe_temp, geneid = "sum_umi") + }, "^Abnormal spatial coordinates" ) rm(spe_temp) From 08061cb779d45586404a58284b4dcfb25f975e12 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 12:08:52 -0400 Subject: [PATCH 165/259] Add Visium_LS data prepared by Nick Eagles. Resolve #81 Co-authored-by: Nick Eagles --- R/fetch_data.R | 68 ++++++++++++++++++++++++++++++++--------------- man/fetch_data.Rd | 3 ++- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index cc715e4a..8f859e5b 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,27 +84,29 @@ #' #> 172.28 MB #' } fetch_data <- - function( - type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function(type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results", + "Visium_LS_spe", + "Visium_LS_spaceranger", + "Visium_LS_ImageJ_out" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL @@ -259,6 +261,30 @@ fetch_data <- file_name <- "Visium_IF_AD_modeling_results.Rdata" url <- "https://www.dropbox.com/s/5plupu8bj5m0kfh/Visium_IF_AD_modeling_results.Rdata?dl=1" + } else if (type == "Visium_LS_spe") { + tag <- "VisiumLS_Visium_stitched_spatialLIBD" + hub_title <- type + + ## While EH is not set-up + file_name <- "Visium_LS_spe.rds" + url <- + "https://www.dropbox.com/scl/fi/9re464y6qaojx3r94nq5u/Visium_LS_spe.rds?rlkey=nq6a82u23xuu9hohr86oodwdi&dl=1" + } else if (type == "Visium_LS_spaceranger") { + tag <- "VisiumLS_Visium_stitched_spatialLIBD" + hub_title <- type + + ## While EH is not set-up + file_name <- "Visium_LS_spaceranger.zip" + url <- + "https://www.dropbox.com/scl/fi/5jdoaukvhq3v7lk19228y/Visium_LS_spaceranger.zip?rlkey=bdgjc6mgy1ierdad6h6v5g29c&dl=1" + } else if (type == "Visium_LS_ImageJ_out") { + tag <- "VisiumLS_Visium_stitched_spatialLIBD" + hub_title <- type + + ## While EH is not set-up + file_name <- "Visium_LS_imagej_out.zip" + url <- + "https://www.dropbox.com/scl/fi/bevo52e96f2kdwllf8dkk/Visium_LS_imagej_out.zip?rlkey=ptwal8f5zxakzejwd0oqw0lhj&dl=1" } file_path <- file.path(destdir, file_name) diff --git a/man/fetch_data.Rd b/man/fetch_data.Rd index b77f5aa9..ac411d47 100644 --- a/man/fetch_data.Rd +++ b/man/fetch_data.Rd @@ -11,7 +11,8 @@ fetch_data( "spatialDLPFC_Visium_SPG", "spatialDLPFC_snRNAseq", "Visium_SPG_AD_Visium_wholegenome_spe", "Visium_SPG_AD_Visium_targeted_spe", "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results"), + "Visium_SPG_AD_Visium_wholegenome_modeling_results", "Visium_LS_spe", + "Visium_LS_spaceranger", "Visium_LS_ImageJ_out"), destdir = tempdir(), eh = ExperimentHub::ExperimentHub(), bfc = BiocFileCache::BiocFileCache() From 35aa1193022cd2e30b464f4c956f2b15fec32f13 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 13:01:18 -0400 Subject: [PATCH 166/259] Edit run_app() and app_server() to make them compatible with visiumStitched SPE objects Co-authored-by: Nick Eagles --- R/app_server.R | 33 ++++++++++++++++++++++++--------- R/run_app.R | 41 +++++++++++++++++++++++++++++++++++++++++ R/vis_grid_clus.R | 2 ++ R/vis_grid_gene.R | 2 ++ 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index af18dbb7..ca416d98 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -25,6 +25,7 @@ app_server <- function(input, output, session) { modeling_results <- golem::get_golem_options("modeling_results") sig_genes <- golem::get_golem_options("sig_genes") default_cluster <- golem::get_golem_options("default_cluster") + is_stitched <- golem::get_golem_options("is_stitched") # List the first level callModules here @@ -171,6 +172,7 @@ app_server <- function(input, output, session) { alpha = input$alphalevel, point_size = input$pointsize, auto_crop = input$auto_crop, + is_stitched = is_stitched, ... = paste(" with", input$cluster) ) if (!input$side_by_side_histology) { @@ -211,6 +213,7 @@ app_server <- function(input, output, session) { sample_order = isolate(input$grid_samples), point_size = isolate(input$pointsize), auto_crop = isolate(input$auto_crop), + is_stitched = is_stitched, ... = paste(" with", isolate(input$cluster)) ) cowplot::plot_grid( @@ -232,7 +235,8 @@ app_server <- function(input, output, session) { image_id = input$imageid, alpha = input$alphalevel, point_size = input$pointsize, - auto_crop = input$auto_crop + auto_crop = input$auto_crop, + is_stitched = is_stitched ) if (!input$side_by_side_gene) { return(p) @@ -270,7 +274,8 @@ app_server <- function(input, output, session) { alpha = isolate(input$alphalevel), point_size = isolate(input$pointsize), sample_order = isolate(input$gene_grid_samples), - auto_crop = isolate(input$auto_crop) + auto_crop = isolate(input$auto_crop), + is_stitched = is_stitched ) cowplot::plot_grid( plotlist = plots, @@ -608,8 +613,17 @@ app_server <- function(input, output, session) { ## From vis_gene() in global.R spe_sub <- spe[, spe$sample_id == sampleid] + + point_size <- input$pointsize + if (is_stitched) { + # Drop excluded spots and calculate an appropriate point size + temp <- prep_stitched_data(spe_sub, point_size, input$imageid) + spe_sub <- temp$spe + point_size <- temp$point_size + } + d <- - as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], + as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE ) # Grab any continuous colData columns @@ -692,7 +706,7 @@ app_server <- function(input, output, session) { title = plot_title, image_id = input$imageid, alpha = input$alphalevel, - point_size = input$pointsize, + point_size = point_size, auto_crop = input$auto_crop ) @@ -706,11 +720,11 @@ app_server <- function(input, output, session) { cont_colors = cont_colors(), image_id = input$imageid, alpha = input$alphalevel, - point_size = input$pointsize, + point_size = point_size, auto_crop = input$auto_crop ) + geom_point( shape = 21, - size = input$pointsize, + size = point_size, stroke = 0, alpha = input$alphalevel ) @@ -728,7 +742,7 @@ app_server <- function(input, output, session) { ) + geom_point( shape = 21, - size = input$pointsize, + size = point_size, stroke = 0 ) + scale_fill_manual(values = get_colors(colors, colData(spe)[[clustervar]][spe$sample_id == sampleid])) + @@ -756,7 +770,7 @@ app_server <- function(input, output, session) { ) + geom_point( shape = 21, - size = input$pointsize, + size = point_size, stroke = 0 ) } else { @@ -951,7 +965,8 @@ app_server <- function(input, output, session) { image_id = input$imageid, alpha = input$alphalevel, point_size = input$pointsize, - auto_crop = input$auto_crop + auto_crop = input$auto_crop, + is_stitched = is_stitched ) + geom_point( shape = 21, diff --git a/R/run_app.R b/R/run_app.R index b7beae48..8e7dfaf0 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -40,6 +40,7 @@ #' automatically cropping the images. Set this to `FALSE` if your images do not #' follow the Visium grid size expectations, which are key for enabling #' auto-cropping. +#' @inheritParams vis_clus #' @param ... Other arguments passed to the list of golem options for running #' the application. #' @@ -185,6 +186,43 @@ #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k09_position_noWM #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 #' ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app +#' +#' +#' ## Example for an object with multiple capture areas stitched together with +#' ## . +#' spe_stitched <- fetch_data("Visium_LS_spe") +#' +#' ## Inspect this object +#' spe_stitched +#' +#' ## Notice the use of "exclude_overlapping" +#' table(spe_stitched$exclude_overlapping, useNA = "ifany") +#' +#' ## Drop NAs +#' spe_stitched <- spe_stitched[, !is.na(spe_stitched$exclude_overlapping)] +#' +#' ## Make it compatible with spatialLIBD::run_app() +#' spe_stitched <- add_key(spe_stitched) +#' spe_stitched$sum_umi <- colSums(logcounts(spe_stitched)) +#' spe_stitched$sum_gene <- colSums(logcounts(spe_stitched) > 0) +#' rowData(spe_stitched)$gene_name <- rowData(spe_stitched)$symbol +#' rowData(spe_stitched)$gene_id <- rownames(spe_stitched) +#' rowData(spe_stitched)$gene_search <- paste0(rowData(spe_stitched)$gene_name, "; ", rowData(spe_stitched)$gene_id) +#' is_mito <- seq_len(1000) +#' spe_stitched$expr_chrM <- colSums(logcounts(spe_stitched)[is_mito, , drop = FALSE]) +#' spe_stitched$expr_chrM_ratio <- spe_stitched$expr_chrM / spe_stitched$sum_umi +#' ## Add a variable for saving the manual annotations +#' spe_stitched$ManualAnnotation <- "NA" +#' +#' ## Run the app with this stitched data +#' run_app(spe = spe_stitched, +#' sce_layer = NULL, modeling_results = NULL, sig_genes = NULL, +#' title = "visiumStitched example data", +#' spe_discrete_vars = c("capture_area", "scran_quick_cluster", "ManualAnnotation"), +#' spe_continuous_vars = c("sum_umi", "sum_gene", "expr_chrM", "expr_chrM_ratio"), +#' default_cluster = "scran_quick_cluster", +#' is_stitched = TRUE +#' ) #' } run_app <- function(spe = fetch_data(type = "spe"), sce_layer = fetch_data(type = "sce_layer"), @@ -233,10 +271,12 @@ run_app <- function(spe = fetch_data(type = "spe"), ), default_cluster = "spatialLIBD", auto_crop_default = TRUE, + is_stitched = FALSE, ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) + if (is_stitched) auto_crop_default <- FALSE spe <- check_spe(spe, @@ -281,6 +321,7 @@ run_app <- function(spe = fetch_data(type = "spe"), spe_continuous_vars = spe_continuous_vars, default_cluster = default_cluster, auto_crop_default = auto_crop_default, + is_stitched = is_stitched, ... ) ) diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index 6c61cece..b3c5086a 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -62,6 +62,7 @@ vis_grid_clus <- point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + is_stitched = FALSE, ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) @@ -81,6 +82,7 @@ vis_grid_clus <- point_size = point_size, auto_crop = auto_crop, na_color = na_color, + is_stitched = is_stitched, ... ) }) diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index e21b5bf1..8ddddbfb 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -52,6 +52,7 @@ vis_grid_gene <- point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + is_stitched = FALSE, ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) @@ -70,6 +71,7 @@ vis_grid_gene <- point_size = point_size, auto_crop = auto_crop, na_color = na_color, + is_stitched = is_stitched, ... ) }) From 8c25a4ca9dfe2eae84dcc0644dd95685d003ba7e Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 13:04:18 -0400 Subject: [PATCH 167/259] Update News file announcing the recent updates related to visiumStitched Co-authored-by: Nick Eagles --- NEWS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS.md b/NEWS.md index 2da9df7f..eac9b512 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.17.3 + +NEW FEATURES + +* Added support for `SpatialExperiment` objects created with +`visiumStitched::build_spe()` + that +stitch together multiple Visium capture areas. Developed by @Nick-Eagles. + # spatialLIBD 1.15.2 SIGNIFICANT USER-VISIBLE CHANGES From d6b6809ba58e3103bdb340eb8de24227d6892f82 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 13:04:51 -0400 Subject: [PATCH 168/259] Auto-style + re-render docs --- R/fetch_data.R | 47 ++++++++++---------- R/run_app.R | 102 ++++++++++++++++++++++--------------------- R/vis_grid_clus.R | 35 +++++++-------- R/vis_grid_gene.R | 39 +++++++++-------- man/run_app.Rd | 46 +++++++++++++++++++ man/vis_grid_clus.Rd | 8 ++++ man/vis_grid_gene.Rd | 8 ++++ 7 files changed, 176 insertions(+), 109 deletions(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index 8f859e5b..94b4bea8 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,29 +84,30 @@ #' #> 172.28 MB #' } fetch_data <- - function(type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results", - "Visium_LS_spe", - "Visium_LS_spaceranger", - "Visium_LS_ImageJ_out" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function( + type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results", + "Visium_LS_spe", + "Visium_LS_spaceranger", + "Visium_LS_ImageJ_out" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/run_app.R b/R/run_app.R index 8e7dfaf0..4352ce03 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -215,7 +215,8 @@ #' spe_stitched$ManualAnnotation <- "NA" #' #' ## Run the app with this stitched data -#' run_app(spe = spe_stitched, +#' run_app( +#' spe = spe_stitched, #' sce_layer = NULL, modeling_results = NULL, sig_genes = NULL, #' title = "visiumStitched example data", #' spe_discrete_vars = c("capture_area", "scran_quick_cluster", "ManualAnnotation"), @@ -224,55 +225,56 @@ #' is_stitched = TRUE #' ) #' } -run_app <- function(spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - is_stitched = FALSE, - ...) { +run_app <- function( + spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + is_stitched = FALSE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index b3c5086a..c84dbac4 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,23 +47,24 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function(spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { + function( + spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index 8ddddbfb..bf32dd7a 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,25 +35,26 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function(spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { + function( + spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/man/run_app.Rd b/man/run_app.Rd index 5b1d6c6a..5c8f19f0 100644 --- a/man/run_app.Rd +++ b/man/run_app.Rd @@ -24,6 +24,7 @@ run_app( "expr_chrM_ratio"), default_cluster = "spatialLIBD", auto_crop_default = TRUE, + is_stitched = FALSE, ... ) } @@ -75,6 +76,13 @@ automatically cropping the images. Set this to \code{FALSE} if your images do no follow the Visium grid size expectations, which are key for enabling auto-cropping.} +\item{is_stitched}{A \code{logical(1)} vector: If \code{TRUE}, expects a +\link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} built +with \code{visiumStitched::build_spe()}. +\url{http://research.libd.org/visiumStitched/reference/build_spe.html}; in +particular, expects a logical colData column \code{exclude_overlapping} +specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE}.} + \item{...}{Other arguments passed to the list of golem options for running the application.} } @@ -233,5 +241,43 @@ if (enough_ram(9e9)) { ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k09_position_noWM ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/deploy_app_k16 ## * https://github.com/LieberInstitute/spatialDLPFC/tree/main/code/analysis_IF/03_spatialLIBD_app + + +## Example for an object with multiple capture areas stitched together with +## . +spe_stitched <- fetch_data("Visium_LS_spe") + +## Inspect this object +spe_stitched + +## Notice the use of "exclude_overlapping" +table(spe_stitched$exclude_overlapping, useNA = "ifany") + +## Drop NAs +spe_stitched <- spe_stitched[, !is.na(spe_stitched$exclude_overlapping)] + +## Make it compatible with spatialLIBD::run_app() +spe_stitched <- add_key(spe_stitched) +spe_stitched$sum_umi <- colSums(logcounts(spe_stitched)) +spe_stitched$sum_gene <- colSums(logcounts(spe_stitched) > 0) +rowData(spe_stitched)$gene_name <- rowData(spe_stitched)$symbol +rowData(spe_stitched)$gene_id <- rownames(spe_stitched) +rowData(spe_stitched)$gene_search <- paste0(rowData(spe_stitched)$gene_name, "; ", rowData(spe_stitched)$gene_id) +is_mito <- seq_len(1000) +spe_stitched$expr_chrM <- colSums(logcounts(spe_stitched)[is_mito, , drop = FALSE]) +spe_stitched$expr_chrM_ratio <- spe_stitched$expr_chrM / spe_stitched$sum_umi +## Add a variable for saving the manual annotations +spe_stitched$ManualAnnotation <- "NA" + +## Run the app with this stitched data +run_app( + spe = spe_stitched, + sce_layer = NULL, modeling_results = NULL, sig_genes = NULL, + title = "visiumStitched example data", + spe_discrete_vars = c("capture_area", "scran_quick_cluster", "ManualAnnotation"), + spe_continuous_vars = c("sum_umi", "sum_gene", "expr_chrM", "expr_chrM_ratio"), + default_cluster = "scran_quick_cluster", + is_stitched = TRUE +) } } diff --git a/man/vis_grid_clus.Rd b/man/vis_grid_clus.Rd index c9410866..19dd2c3a 100644 --- a/man/vis_grid_clus.Rd +++ b/man/vis_grid_clus.Rd @@ -20,6 +20,7 @@ vis_grid_clus( point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + is_stitched = FALSE, ... ) } @@ -76,6 +77,13 @@ alpha blending already, which will make non-NA values pop up more and the NA values will show with a lighter color. This behavior is lost when \code{alpha} is set to a non-\code{NA} value.} +\item{is_stitched}{A \code{logical(1)} vector: If \code{TRUE}, expects a +\link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} built +with \code{visiumStitched::build_spe()}. +\url{http://research.libd.org/visiumStitched/reference/build_spe.html}; in +particular, expects a logical colData column \code{exclude_overlapping} +specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE}.} + \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} } diff --git a/man/vis_grid_gene.Rd b/man/vis_grid_gene.Rd index 0ed8c520..a102cbbe 100644 --- a/man/vis_grid_gene.Rd +++ b/man/vis_grid_gene.Rd @@ -23,6 +23,7 @@ vis_grid_gene( point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", + is_stitched = FALSE, ... ) } @@ -93,6 +94,13 @@ alpha blending already, which will make non-NA values pop up more and the NA values will show with a lighter color. This behavior is lost when \code{alpha} is set to a non-\code{NA} value.} +\item{is_stitched}{A \code{logical(1)} vector: If \code{TRUE}, expects a +\link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} built +with \code{visiumStitched::build_spe()}. +\url{http://research.libd.org/visiumStitched/reference/build_spe.html}; in +particular, expects a logical colData column \code{exclude_overlapping} +specifying which spots to exclude from the plot. Sets \code{auto_crop = FALSE}.} + \item{...}{Passed to \link[base:paste]{paste0()} for making the title of the plot following the \code{sampleid}.} } From a40956fc489a7e5afb4fc7eda0de81e36773d367 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 2 Jul 2024 13:07:05 -0400 Subject: [PATCH 169/259] v1.17.3 -- add initial support for visiumStitched::build_spe() objects. TODO: * Re-make example data with read10xVisiumWrapper() * Add post-stitched reduced dims + spatial clusters * Clean up example code at run_app() * Change default cluster to the spatial clusters, instead of the scran_quick_clusters. Co-authored-by: Nick Eagles --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a0ebcbcf..c8db0a99 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.2 -Date: 2024-05-24 +Version: 1.17.3 +Date: 2024-07-02 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From 3b78be48940b3a58791d2c07684a331607b25d3f Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 3 Jul 2024 16:45:45 -0400 Subject: [PATCH 170/259] Update docs after having updated the LS data on Dropbox. Aka, the stitched LS object is now compatible out of the box with spatialLIBD::run_app() --- DESCRIPTION | 2 +- R/run_app.R | 16 ---------------- man/run_app.Rd | 16 ---------------- 3 files changed, 1 insertion(+), 33 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c8db0a99..55eed6e3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -79,7 +79,7 @@ Imports: statmod, MatrixGenerics, rlang -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Roxygen: list(markdown = TRUE) URL: https://github.com/LieberInstitute/spatialLIBD BugReports: https://support.bioconductor.org/tag/spatialLIBD diff --git a/R/run_app.R b/R/run_app.R index 4352ce03..851045a3 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -198,22 +198,6 @@ #' ## Notice the use of "exclude_overlapping" #' table(spe_stitched$exclude_overlapping, useNA = "ifany") #' -#' ## Drop NAs -#' spe_stitched <- spe_stitched[, !is.na(spe_stitched$exclude_overlapping)] -#' -#' ## Make it compatible with spatialLIBD::run_app() -#' spe_stitched <- add_key(spe_stitched) -#' spe_stitched$sum_umi <- colSums(logcounts(spe_stitched)) -#' spe_stitched$sum_gene <- colSums(logcounts(spe_stitched) > 0) -#' rowData(spe_stitched)$gene_name <- rowData(spe_stitched)$symbol -#' rowData(spe_stitched)$gene_id <- rownames(spe_stitched) -#' rowData(spe_stitched)$gene_search <- paste0(rowData(spe_stitched)$gene_name, "; ", rowData(spe_stitched)$gene_id) -#' is_mito <- seq_len(1000) -#' spe_stitched$expr_chrM <- colSums(logcounts(spe_stitched)[is_mito, , drop = FALSE]) -#' spe_stitched$expr_chrM_ratio <- spe_stitched$expr_chrM / spe_stitched$sum_umi -#' ## Add a variable for saving the manual annotations -#' spe_stitched$ManualAnnotation <- "NA" -#' #' ## Run the app with this stitched data #' run_app( #' spe = spe_stitched, diff --git a/man/run_app.Rd b/man/run_app.Rd index 5c8f19f0..0eb0295d 100644 --- a/man/run_app.Rd +++ b/man/run_app.Rd @@ -253,22 +253,6 @@ spe_stitched ## Notice the use of "exclude_overlapping" table(spe_stitched$exclude_overlapping, useNA = "ifany") -## Drop NAs -spe_stitched <- spe_stitched[, !is.na(spe_stitched$exclude_overlapping)] - -## Make it compatible with spatialLIBD::run_app() -spe_stitched <- add_key(spe_stitched) -spe_stitched$sum_umi <- colSums(logcounts(spe_stitched)) -spe_stitched$sum_gene <- colSums(logcounts(spe_stitched) > 0) -rowData(spe_stitched)$gene_name <- rowData(spe_stitched)$symbol -rowData(spe_stitched)$gene_id <- rownames(spe_stitched) -rowData(spe_stitched)$gene_search <- paste0(rowData(spe_stitched)$gene_name, "; ", rowData(spe_stitched)$gene_id) -is_mito <- seq_len(1000) -spe_stitched$expr_chrM <- colSums(logcounts(spe_stitched)[is_mito, , drop = FALSE]) -spe_stitched$expr_chrM_ratio <- spe_stitched$expr_chrM / spe_stitched$sum_umi -## Add a variable for saving the manual annotations -spe_stitched$ManualAnnotation <- "NA" - ## Run the app with this stitched data run_app( spe = spe_stitched, From 30a8b3a02ec90b95746b2ee4734377d9bec5c159 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 3 Jul 2024 16:46:22 -0400 Subject: [PATCH 171/259] v1.17.4 -- bump version now that LS stitched data is compatible with run_app() --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 55eed6e3..f372bd07 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.3 -Date: 2024-07-02 +Version: 1.17.4 +Date: 2024-07-03 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From 83ffe53441221b76fba5f0c3b88419603fefe863 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 10 Jul 2024 10:00:15 -0400 Subject: [PATCH 172/259] Improved the documentation for add_qc_metrics() Co-authored-by: Nick Eagles Co-authored-by: Cynthia SC Co-authored-by: Louise Huuki --- NAMESPACE | 2 +- R/add_qc_metrics.R | 113 ++++++++++++++++++++++++++++++++---------- man/add_qc_metrics.Rd | 85 +++++++++++++++++++++++-------- 3 files changed, 150 insertions(+), 50 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 4eba582c..42d8758a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -131,9 +131,9 @@ importFrom(methods,new) importFrom(png,readPNG) importFrom(rlang,arg_match) importFrom(rtracklayer,import) -importFrom(scater,isOutlier) importFrom(scater,plotReducedDim) importFrom(scuttle,aggregateAcrossCells) +importFrom(scuttle,isOutlier) importFrom(sessioninfo,session_info) importFrom(shiny,shinyApp) importFrom(shinyWidgets,pickerInput) diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index 5008e304..eff62ab5 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -3,60 +3,119 @@ #' This function identify spots in a #' [SpatialExperiment-class][SpatialExperiment::SpatialExperiment-class] (SPE) #' with outlier quality control values: low `sum_umi` or `sum_gene`, or high -#' `expr_chrM_ratio`, utilizing `scran::isOutlier()`. Also identifies in-tissue +#' `expr_chrM_ratio`, utilizing [scuttle::isOutlier][scuttle::isOutlier]. Also identifies in-tissue #' edge spots and distance to the edge for each spot. #' +#' The initial version of this function lives at +#' . +#' #' @param spe a [SpatialExperiment][SpatialExperiment::SpatialExperiment-class] +#' object that has `sum_umi`, `sum_gene`, `expr_chrM_ratio`, and `in_tissue` +#' variables in the `colData(spe)`. Note that these are automatically created +#' when you build your `spe` object with `spatialLIBD::read10xVisiumWrapper()`. +#' @param overwrite a `logical(1)` specifying whether to overwrite the 7 +#' `colData(spe)` columns that this function creates. If set to `FALSE` and any +#' of them are present, the function will return an error. #' #' @return A [SpatialExperiment][SpatialExperiment::SpatialExperiment-class] -#' with added quiality control information added to the colData. +#' with added quality control information added to the `colData()`. +#' \describe{ +#' \item{`scran_low_lib_size`}{shows spots that have a low library size.} +#' \item{`scran_low_n_features`}{spots with a low number of expressed genes.} +#' \item{`scran_high_Mito_percent`}{spots with a high percent of mitochondrial gene expression.} +#' \item{`scran_discard`}{spots belonging to either `scran_low_lib_size`, +#' `scran_low_n_feature`, or `scran_high_Mito_percent`.} +#' \item{`edge_spot`}{spots that are automatically detected as the edge spots +#' of the `in_tissue` section.} +#' \item{`edge_distance`}{closest distance in number of spots to either the +#' vertical or horizontal edge.} +#' \item{`scran_low_lib_size_edge`}{spots that have a low library size and +#' are an edge spot.} +#' } #' #' @export #' @importFrom dplyr group_by summarize left_join select mutate #' @importFrom SummarizedExperiment colData -#' @importFrom scater isOutlier +#' @importFrom scuttle isOutlier +#' @author Louise A. Huuki-Myers #' #' @examples -#' if (enough_ram()) { -#' ## Obtain the necessary data -#' if (!exists("spe")) spe <- fetch_data("spe") +#' ## Obtain the necessary data +#' spe_pre_qc <- fetch_data("spatialDLPFC_Visium_example_subset") #' -#' ## fake out tissue spots in example data (TODO add pre-qc data) -#' spe_qc <- spe -#' spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE +#' ## For now, we fake out tissue spots in example data +#' spe_qc <- spe_pre_qc +#' spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE #' -#' ## adds QC metrics to colData of the spe -#' spe_qc <- add_qc_metrics(spe_qc) -#' colData(spe_qc) +#' ## adds QC metrics to colData of the spe +#' spe_qc <- add_qc_metrics(spe_qc, overwrite = TRUE) +#' vars <- colnames(colData(spe_qc)) +#' vars[grep("^(scran|edge)", vars)] #' -#' ## visualize edge spots -#' vis_clus(spe_qc, sampleid = "151507", clustervar = "edge_spot") -#' vis_gene(spe_qc, sampleid = "151507", geneid = "edge_distance", minCount = -1) +#' ## visualize edge spots +#' vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "edge_spot") +#' vis_gene(spe_qc, sampleid = "Br6432_ant", geneid = "edge_distance", minCount = -1) #' -#' ## visualize scran QC flags +#' ## Visualize scran QC flags #' -#' vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") +#' ## Check the spots with low library size as detected by scran::isOutlier() +#' vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "scran_low_lib_size") #' -#' # scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") +#' ## Violin plot of library size with low library size highlighted in a +#' ## different color. +#' scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") #' -#' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") -#' vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") -#' } -#' -add_qc_metrics <- function(spe) { +#' ## Check any spots that scran::isOutlier() flagged +#' vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "scran_discard") +#' +#' ## Low library spots that are on the edge of the tissue +#' vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "scran_low_lib_size_edge") +#' +#' ## Use `low_library_size` (or other variables) and `edge_distance` as you +#' ## please. +#' spe_qc$our_low_lib_edge <- factor( +#' spe_qc$scran_low_lib_size == "TRUE" & +#' spe_qc$edge_distance < 5, +#' levels = c("TRUE", "FALSE") +#' ) +#' vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") +#' + +add_qc_metrics <- function(spe, overwrite = FALSE) { stopifnot("in_tissue" %in% colnames(colData(spe))) stopifnot("sum_umi" %in% colnames(colData(spe))) stopifnot("sum_gene" %in% colnames(colData(spe))) stopifnot("expr_chrM_ratio" %in% colnames(colData(spe))) + + if (!overwrite) { + new_vars <- c( + 'scran_discard', + 'scran_low_lib_size', + 'scran_low_n_features', + 'scran_high_Mito_percent', + 'edge_spot', + 'edge_distance', + 'scran_low_lib_size_edge' + ) + present <- new_vars %in% colnames(colData(spe)) + if (any(present)) { + stop( + paste(new_vars[present], collapse = ", "), + " are all present in the colData(spe). If you want to overwrite them use add_qc_metric(overwrite = TRUE).", + call. = FALSE + ) + } + } + spe$in_tissue <- as.logical(spe$in_tissue) spe_in <- spe[, spe$in_tissue] ## QC in-tissue spots - + # define variables low_lib_size <- low_n_features <- in_tissue <- sample_id <- NULL - + qc_df <- data.frame( log2sum = log2(spe_in$sum_umi), log2detected = log2(spe_in$sum_gene), @@ -98,10 +157,10 @@ add_qc_metrics <- function(spe) { factor(spe$scran_high_Mito_percent, levels = c("TRUE", "FALSE")) ## Find edge spots - # define variables + # define variables array_row <- array_col <- edge_row <- edge_col <- row_distance <- NULL col_distance <- high_subsets_Mito_percent <- NULL - + spot_coords <- colData(spe_in) |> as.data.frame() |> select(in_tissue, sample_id, array_row, array_col) |> diff --git a/man/add_qc_metrics.Rd b/man/add_qc_metrics.Rd index b1d5dc5d..0526e5de 100644 --- a/man/add_qc_metrics.Rd +++ b/man/add_qc_metrics.Rd @@ -4,47 +4,88 @@ \alias{add_qc_metrics} \title{Quality Control for Spatial Data} \usage{ -add_qc_metrics(spe) +add_qc_metrics(spe, overwrite = FALSE) } \arguments{ -\item{spe}{a \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment}} +\item{spe}{a \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment} +object that has \code{sum_umi}, \code{sum_gene}, \code{expr_chrM_ratio}, and \code{in_tissue} +variables in the \code{colData(spe)}. Note that these are automatically created +when you build your \code{spe} object with \code{spatialLIBD::read10xVisiumWrapper()}.} + +\item{overwrite}{a \code{logical(1)} specifying whether to overwrite the 7 +\code{colData(spe)} columns that this function creates. If set to \code{FALSE} and any +of them are present, the function will return an error.} } \value{ A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment} -with added quiality control information added to the colData. +with added quality control information added to the \code{colData()}. +\describe{ +\item{\code{scran_low_lib_size}}{shows spots that have a low library size.} +\item{\code{scran_low_n_features}}{spots with a low number of expressed genes.} +\item{\code{scran_high_Mito_percent}}{spots with a high percent of mitochondrial gene expression.} +\item{\code{scran_discard}}{spots belonging to either \code{scran_low_lib_size}, +\code{scran_low_n_feature}, or \code{scran_high_Mito_percent}.} +\item{\code{edge_spot}}{spots that are automatically detected as the edge spots +of the \code{in_tissue} section.} +\item{\code{edge_distance}}{closest distance in number of spots to either the +vertical or horizontal edge.} +\item{\code{scran_low_lib_size_edge}}{spots that have a low library size and +are an edge spot.} +} } \description{ This function identify spots in a \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} (SPE) with outlier quality control values: low \code{sum_umi} or \code{sum_gene}, or high -\code{expr_chrM_ratio}, utilizing \code{scran::isOutlier()}. Also identifies in-tissue +\code{expr_chrM_ratio}, utilizing \link[scuttle:isOutlier]{scuttle::isOutlier}. Also identifies in-tissue edge spots and distance to the edge for each spot. } +\details{ +The initial version of this function lives at +\url{https://github.com/LieberInstitute/Visium_SPG_AD/blob/master/code/07_spot_qc/01_qc_metrics_and_segmentation.R}. +} \examples{ -if (enough_ram()) { - ## Obtain the necessary data - if (!exists("spe")) spe <- fetch_data("spe") +## Obtain the necessary data +spe_pre_qc <- fetch_data("spatialDLPFC_Visium_example_subset") - ## fake out tissue spots in example data (TODO add pre-qc data) - spe_qc <- spe - spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE +## For now, we fake out tissue spots in example data +spe_qc <- spe_pre_qc +spe_qc$in_tissue[spe_qc$array_col < 10] <- FALSE - ## adds QC metrics to colData of the spe - spe_qc <- add_qc_metrics(spe_qc) - colData(spe_qc) +## adds QC metrics to colData of the spe +spe_qc <- add_qc_metrics(spe_qc, overwrite = TRUE) +vars <- colnames(colData(spe_qc)) +vars[grep("^(scran|edge)", vars)] - ## visualize edge spots - vis_clus(spe_qc, sampleid = "151507", clustervar = "edge_spot") - vis_gene(spe_qc, sampleid = "151507", geneid = "edge_distance", minCount = -1) +## visualize edge spots +vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "edge_spot") +vis_gene(spe_qc, sampleid = "Br6432_ant", geneid = "edge_distance", minCount = -1) - ## visualize scran QC flags +## Visualize scran QC flags - vis_clus(spe_qc, sample_id = "151507", clustervar = "scran_low_lib_size") +## Check the spots with low library size as detected by scran::isOutlier() +vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "scran_low_lib_size") - # scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") +## Violin plot of library size with low library size highlighted in a +## different color. +scater::plotColData(spe_qc[, spe_qc$in_tissue], x = "sample_id", y = "sum_umi", colour_by = "scran_low_lib_size") - vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_discard") - vis_clus(spe_qc, sampleid = "151507", clustervar = "scran_low_lib_size_edge") -} +## Check any spots that scran::isOutlier() flagged +vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "scran_discard") +## Low library spots that are on the edge of the tissue +vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "scran_low_lib_size_edge") + +## Use `low_library_size` (or other variables) and `edge_distance` as you +## please. +spe_qc$our_low_lib_edge <- factor( + spe_qc$scran_low_lib_size == "TRUE" & + spe_qc$edge_distance < 5, + levels = c("TRUE", "FALSE") +) +vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") + +} +\author{ +Louise A. Huuki-Myers } From 15a98b084170a64772b896dad399e61e906fe22a Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 10 Jul 2024 10:02:25 -0400 Subject: [PATCH 173/259] Code auto-styled --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 ++-- R/add_qc_metrics.R | 15 ++--- R/annotate_registered_clusters.R | 16 +++-- R/check_sce.R | 69 +++++++++---------- R/check_spe.R | 15 +++-- R/fetch_data.R | 47 +++++++------ R/frame_limits.R | 21 +++--- R/gene_set_enrichment.R | 11 ++-- R/gene_set_enrichment_plot.R | 23 +++---- R/geom_spatial.R | 17 ++--- R/img_edit.R | 37 ++++++----- R/img_update.R | 13 ++-- R/img_update_all.R | 11 ++-- R/layer_boxplot.R | 27 ++++---- R/layer_matrix_plot.R | 27 ++++---- R/layer_stat_cor.R | 11 ++-- R/layer_stat_cor_plot.R | 11 ++-- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 21 +++--- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 ++-- R/registration_stats_anova.R | 17 ++--- R/registration_stats_enrichment.R | 15 ++--- R/registration_stats_pairwise.R | 15 ++--- R/registration_wrapper.R | 19 +++--- R/run_app.R | 99 ++++++++++++++-------------- R/sig_genes_extract.R | 11 ++-- R/sig_genes_extract_all.R | 7 +- R/vis_clus.R | 51 +++++++------- R/vis_clus_p.R | 25 +++---- R/vis_gene.R | 33 +++++----- R/vis_gene_p.R | 35 +++++----- R/vis_grid_clus.R | 35 +++++----- R/vis_grid_gene.R | 39 ++++++----- tests/testthat/test-add_qc_metrics.R | 8 +-- 36 files changed, 426 insertions(+), 418 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index de4f5fee..dbe49f86 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,8 +29,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function(spe, - visium_analysis) { +add10xVisiumAnalysis <- function( + spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index bfdddbe5..e7b09e5c 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,12 +43,13 @@ #' )) #' } add_images <- - function(spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function( + spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index eff62ab5..27f5a657 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -80,7 +80,6 @@ #' ) #' vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") #' - add_qc_metrics <- function(spe, overwrite = FALSE) { stopifnot("in_tissue" %in% colnames(colData(spe))) stopifnot("sum_umi" %in% colnames(colData(spe))) @@ -90,13 +89,13 @@ add_qc_metrics <- function(spe, overwrite = FALSE) { if (!overwrite) { new_vars <- c( - 'scran_discard', - 'scran_low_lib_size', - 'scran_low_n_features', - 'scran_high_Mito_percent', - 'edge_spot', - 'edge_distance', - 'scran_low_lib_size_edge' + "scran_discard", + "scran_low_lib_size", + "scran_low_n_features", + "scran_high_Mito_percent", + "edge_spot", + "edge_distance", + "scran_low_lib_size_edge" ) present <- new_vars %in% colnames(colData(spe)) if (any(present)) { diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index c2a9ec43..13e1d5ab 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,9 +48,10 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function(cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function( + cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -86,10 +87,11 @@ annotate_registered_clusters <- } annotate_registered_cluster <- - function(remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function( + remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/check_sce.R b/R/check_sce.R index 0d17423b..1d625342 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,40 +24,41 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function(sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function( + sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index 47de3c0a..d0344daa 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,13 +25,14 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function(spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function( + spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index 94b4bea8..8f859e5b 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,30 +84,29 @@ #' #> 172.28 MB #' } fetch_data <- - function( - type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results", - "Visium_LS_spe", - "Visium_LS_spaceranger", - "Visium_LS_ImageJ_out" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function(type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results", + "Visium_LS_spe", + "Visium_LS_spaceranger", + "Visium_LS_ImageJ_out" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index b22b5c8a..320cc643 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,16 +37,17 @@ #' } #' frame_limits <- - function(spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function( + spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index 1accea28..e6b6a63d 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,11 +58,12 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function(gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function( + gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index 4ccbfcbc..c155e672 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,17 +84,18 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function(enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function( + enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 64f00cc3..965db758 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,14 +58,15 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function(mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function( + mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/img_edit.R b/R/img_edit.R index ec6fae90..93aceee3 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,24 +58,25 @@ #' plot(x) #' } img_edit <- - function(spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function( + spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index db6dfcb1..fdfe5b83 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,12 +41,13 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function(spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 31c368c9..314b9b0d 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,11 +22,12 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function(spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function( + spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 345d5499..6a671a5e 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,19 +114,20 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function(i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function( + i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index f1530fb1..4a44fd18 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,19 +55,20 @@ #' cex = 2 #' ) layer_matrix_plot <- - function(matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function( + matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index 0ccf0bf2..f484c912 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -49,11 +49,12 @@ #' top_n = 10 #' )) layer_stat_cor <- - function(stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function( + stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index c0f4e924..0d2653b8 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,11 +72,12 @@ #' top_n = 10 #' ), max = 0.25) layer_stat_cor_plot <- - function(cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { + function( + cor_stats_layer, + max = 0.81, + min = -max, + layerHeights = NULL, + cex = 1.2) { ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R theSeq <- seq(min, max, by = 0.01) my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index ef76f1d0..70bc49ac 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,9 +24,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 501a744d..d9f31fc2 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,16 +44,17 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { diff --git a/R/registration_model.R b/R/registration_model.R index 3f36260c..6921dbb9 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,9 +24,10 @@ #' head(registration_mod) #' registration_model <- - function(sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function( + sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 5f3c5dd2..2d859e4e 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,13 +51,12 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index c899459d..d1d0b135 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,14 +50,15 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index d186547e..cd3ee182 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,14 +34,13 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index afb9771a..09bb3ff9 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,14 +32,13 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function( - sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function(sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 49896d78..38a1c297 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -50,16 +50,15 @@ #' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" #' ) registration_wrapper <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index 851045a3..2389d541 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -209,56 +209,55 @@ #' is_stitched = TRUE #' ) #' } -run_app <- function( - spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - is_stitched = FALSE, - ...) { +run_app <- function(spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + is_stitched = FALSE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index b21902c1..fac5f65b 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -59,12 +59,11 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index d2c3c01f..0d68b880 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,10 +27,9 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function( - n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function(n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/vis_clus.R b/R/vis_clus.R index 2dae1971..1bca16bf 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -99,32 +99,31 @@ #' ) #' print(p4) #' } -vis_clus <- function( - spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { +vis_clus <- function(spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { # Verify existence and legitimacy of 'sampleid' if ( !("sample_id" %in% colnames(colData(spe))) || diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index a91ce369..d2b37cec 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,18 +42,19 @@ #' rm(spe_sub) #' } vis_clus_p <- - function(spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function( + spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index 6a28af3f..38a233aa 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -158,23 +158,22 @@ #' print(p8) #' } vis_gene <- - function( - spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - is_stitched = FALSE, - ...) { + function(spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + is_stitched = FALSE, + ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' if ( diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index e659d477..9bc3dc0a 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -48,23 +48,24 @@ #' rm(spe_sub) #' } vis_gene_p <- - function(spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function( + spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) { + viridisLite::viridis(21) + } else { + c("aquamarine4", "springgreen", "goldenrod", "red") + }, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index c84dbac4..b3c5086a 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,24 +47,23 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function( - spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { + function(spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index bf32dd7a..8ddddbfb 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,26 +35,25 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function( - spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { + function(spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/tests/testthat/test-add_qc_metrics.R b/tests/testthat/test-add_qc_metrics.R index 39d39a0a..7941a551 100644 --- a/tests/testthat/test-add_qc_metrics.R +++ b/tests/testthat/test-add_qc_metrics.R @@ -4,11 +4,11 @@ test_that( if (!exists("spe")) spe <- fetch_data("spe") # run metrics spe - spe_qc <- add_qc_metrics(spe) + spe_qc <- add_qc_metrics(spe, overwrite = TRUE) expect_equal(ncol(spe), ncol(spe_qc)) ## same number of spots expect_equal(ncol(colData(spe)) + 7, ncol(colData(spe_qc))) ## add 7 QC cols to colData - # [1] "scran_discard" "scran_low_lib_size" "scran_low_n_features" - # [4] "scran_high_subsets_Mito_percent" "edge_spot" "edge_distance" - # [7] "scran_low_lib_size_edge" + # [1] "scran_discard" "scran_low_lib_size" "scran_low_n_features" + # [4] "scran_high_subsets_Mito_percent" "edge_spot" "edge_distance" + # [7] "scran_low_lib_size_edge" } ) From 89121fbd9d769e55ca88226c8781a34651e1a42a Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 10 Jul 2024 10:04:21 -0400 Subject: [PATCH 174/259] Update the news to mention `add_qc_metrics()` Co-authored-by: Louise Huuki --- NEWS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS.md b/NEWS.md index eac9b512..328c9750 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.17.5 + +NEW FEATURES + +* Added `add_qc_metrics()` inspired by + +which adds seven new columns to the `colData(spe)` that can be useful when +performing quality control of the data. Developed by @lahuuki. + # spatialLIBD 1.17.3 NEW FEATURES From 03e6f1cbf4355589c4964e60cf085b95fc816ac0 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 10 Jul 2024 10:04:58 -0400 Subject: [PATCH 175/259] v1.17.5 -- added `add_qc_metrics()` --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d67643f5..f052acac 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.4 -Date: 2024-07-03 +Version: 1.17.5 +Date: 2024-07-10 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From 9dcfca1da4ed34ecb8dc4367cf057e449866a310 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 11 Jul 2024 13:55:39 -0400 Subject: [PATCH 176/259] remove one comment from vis_gene_p docs --- R/vis_gene_p.R | 1 - man/vis_gene_p.Rd | 1 - 2 files changed, 2 deletions(-) diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 9bc3dc0a..632b864c 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -33,7 +33,6 @@ #' df <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) #' df$COUNT <- df$expr_chrM_ratio #' -#' ## Use the manual color palette by Lukas M Weber #' ## Don't plot the histology information #' p <- vis_gene_p( #' spe = spe_sub, diff --git a/man/vis_gene_p.Rd b/man/vis_gene_p.Rd index 1c65b9a4..c1115f71 100644 --- a/man/vis_gene_p.Rd +++ b/man/vis_gene_p.Rd @@ -98,7 +98,6 @@ if (enough_ram()) { df <- as.data.frame(cbind(colData(spe_sub), SpatialExperiment::spatialCoords(spe_sub)), optional = TRUE) df$COUNT <- df$expr_chrM_ratio - ## Use the manual color palette by Lukas M Weber ## Don't plot the histology information p <- vis_gene_p( spe = spe_sub, From 5a487d75110348c55431ede2fa9bd5eb72388458 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 11 Jul 2024 14:04:58 -0400 Subject: [PATCH 177/259] Remove some spe objects we won't use later --- R/add_qc_metrics.R | 3 +++ man/add_qc_metrics.Rd | 3 +++ 2 files changed, 6 insertions(+) diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index 27f5a657..cbe38bcc 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -80,6 +80,9 @@ #' ) #' vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") #' +#' ## Clean up +#' rm(spe_qc, spec_pre_qc) +#' add_qc_metrics <- function(spe, overwrite = FALSE) { stopifnot("in_tissue" %in% colnames(colData(spe))) stopifnot("sum_umi" %in% colnames(colData(spe))) diff --git a/man/add_qc_metrics.Rd b/man/add_qc_metrics.Rd index 0526e5de..a02b439d 100644 --- a/man/add_qc_metrics.Rd +++ b/man/add_qc_metrics.Rd @@ -85,6 +85,9 @@ spe_qc$our_low_lib_edge <- factor( ) vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") +## Clean up +rm(spe_qc, spec_pre_qc) + } \author{ Louise A. Huuki-Myers From 8cc5dd0a34c3ace5e48e1cbe2ae400361bc850ed Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 11 Jul 2024 14:12:23 -0400 Subject: [PATCH 178/259] also rm an spe from the test for add_qc_metrics once we are done with it --- tests/testthat/test-add_qc_metrics.R | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testthat/test-add_qc_metrics.R b/tests/testthat/test-add_qc_metrics.R index 7941a551..3d3ee568 100644 --- a/tests/testthat/test-add_qc_metrics.R +++ b/tests/testthat/test-add_qc_metrics.R @@ -10,5 +10,6 @@ test_that( # [1] "scran_discard" "scran_low_lib_size" "scran_low_n_features" # [4] "scran_high_subsets_Mito_percent" "edge_spot" "edge_distance" # [7] "scran_low_lib_size_edge" + rm(spe_qc) } ) From 08c2b2d80a29b1decee578d01f7230b595a9bf5a Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 12 Jul 2024 10:56:10 -0400 Subject: [PATCH 179/259] Resolve #80 Part of this work was done live during today's LIBD rstats club. Although I didn't find the solution to this bug during that time. --- NEWS.md | 11 +++++++++ R/get_colors.R | 18 ++++++++++++++- R/sort_clusters.R | 55 +++++++++++++++++++++++++++++++++++++------- man/get_colors.Rd | 11 +++++++++ man/sort_clusters.Rd | 48 +++++++++++++++++++++++++++++++++----- 5 files changed, 128 insertions(+), 15 deletions(-) diff --git a/NEWS.md b/NEWS.md index 328c9750..0d9e48e1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,14 @@ +# spatialLIBD 1.17.6 + +BUG FIXES + +* Fixed the bug reported by @lahuuki about `vis_grid_clus()` not handling +`logical()` cluster variables. +See . To resolve this, +`sort_clusters()` and `get_colors()` had to change internally. Examples and +documentation for both functions have now been updated to showcase what happens +when you provide a `logical()` vector as an input. + # spatialLIBD 1.17.5 NEW FEATURES diff --git a/R/get_colors.R b/R/get_colors.R index 7d601839..93b53351 100644 --- a/R/get_colors.R +++ b/R/get_colors.R @@ -31,6 +31,17 @@ #' #' ## Example where Polychrome::palette36.colors() gets used #' get_colors(clusters = letters[seq_len(13)]) +#' +#' ## What happens if you have a logical variable with NAs? +#' set.seed(20240712) +#' log_var <- sample(c(TRUE, FALSE, NA), +#' 1000, +#' replace = TRUE, +#' prob = c(0.3, 0.15, 0.55)) +#' log_var_sorted <- sort_clusters(log_var) +#' ## A color does get assigned to 'NA', but will be overwritten by +#' ## 'na_color' passed to `vis_clus_p()` and related functions. +#' get_colors(colors = NULL, clusters = log_var_sorted) get_colors <- function(colors = NULL, clusters) { n_clus <- length(unique(clusters)) @@ -67,7 +78,12 @@ get_colors <- function(colors = NULL, clusters) { "purple" ) } - names(colors) <- seq_len(length(colors)) + ## Subset to the actual number of values if we are working with < 12 + colors <- colors[seq_len(n_clus)] + + ## Set the names of the colors in a way compatible with how names + ## are set in vis_clus_p(). + names(colors) <- levels(factor(clusters)) } else if (all(unique(as.character(clusters)) %in% c(gsub("ayer", "", names(colors)), NA))) { names(colors) <- gsub("ayer", "", names(colors)) } diff --git a/R/sort_clusters.R b/R/sort_clusters.R index 7d906690..f4b8563c 100644 --- a/R/sort_clusters.R +++ b/R/sort_clusters.R @@ -1,15 +1,15 @@ #' Sort clusters by frequency #' -#' This function takes a vector with cluster labels and sorts it by frequency -#' such that the most frequent cluster is the first one and so on. +#' This function takes a vector with cluster labels, recasts it as a `factor()`, +#' and sorts the `factor()` levels by frequency such that the most frequent +#' cluster is the first level and so on. #' #' @param clusters A vector with cluster labels. #' @param map_subset A logical vector of length equal to `clusters` specifying #' which elements of `clusters` to use to determine the ranking of the clusters. #' -#' @return A factor of length equal to `clusters` where the levels are the new -#' ordered clusters and the names of the factor are the original values from -#' `clusters`. +#' @return A `factor()` version of `clusters` where the levels are ordered by +#' frequency. #' #' @export #' @@ -21,9 +21,49 @@ #' ## In this case, it's a character vector #' class(clus) #' -#' ## Sort them and obtain a factor +#' ## We see that we have 10 elements in this vector, which is +#' ## an unnamed character vector +#' clus +#' +#' ## letter 'd' is the most frequent +#' table(clus) +#' +#' ## Sort them and obtain a factor. Notice that it's a named +#' ## factor, and the names correspond to the original values +#' ## in the character vector. #' sort_clusters(clus) +#' +#' ## Since 'd' was the most frequent, it gets assigned to the first level +#' ## in the factor variable. +#' table(sort_clusters(clus)) +#' +#' ## If we skip the first 3 values of clus (which are all 'd'), we can +#' ## change the most frequent cluster. And thus the ordering of the +#' ## factor levels. +#' sort_clusters(clus, map_subset = seq_len(length(clus)) > 3) +#' +#' ## Let's try with a factor variable +#' clus_factor <- factor(clus) +#' ## sort_clusters() returns an identical result in this case +#' stopifnot(identical(sort_clusters(clus), sort_clusters(clus_factor))) +#' +#' ## What happens if you have a logical variable with NAs? +#' set.seed(20240712) +#' log_var <- sample(c(TRUE, FALSE, NA), +#' 1000, +#' replace = TRUE, +#' prob = c(0.3, 0.15, 0.55)) +#' ## Here, the NAs are the most frequent group. +#' table(log_var, useNA = "ifany") +#' +#' ## The NAs are not used for sorting. Since we have more 'TRUE' than 'FALSE' +#' ## then, 'TRUE' becomes the first level. +#' table(sort_clusters(log_var), useNA = "ifany") sort_clusters <- function(clusters, map_subset = NULL) { + if (is.logical(clusters)) { + clusters <- as.character(clusters) + } + if (is.null(map_subset)) { map_subset <- rep(TRUE, length(clusters)) } else { @@ -36,6 +76,5 @@ sort_clusters <- function(clusters, map_subset = NULL) { } map <- rank(length(clusters[map_subset]) - table(clusters[map_subset]), ties.method = "first") - res <- map[clusters] - factor(res) + factor(clusters, levels = names(sort(map))) } diff --git a/man/get_colors.Rd b/man/get_colors.Rd index ec9a4673..82d96a6d 100644 --- a/man/get_colors.Rd +++ b/man/get_colors.Rd @@ -39,4 +39,15 @@ get_colors(clusters = sce_layer$kmeans_k7) ## Example where Polychrome::palette36.colors() gets used get_colors(clusters = letters[seq_len(13)]) + +## What happens if you have a logical variable with NAs? +set.seed(20240712) +log_var <- sample(c(TRUE, FALSE, NA), + 1000, + replace = TRUE, + prob = c(0.3, 0.15, 0.55)) +log_var_sorted <- sort_clusters(log_var) +## A color does get assigned to 'NA', but will be overwritten by +## 'na_color' passed to `vis_clus_p()` and related functions. +get_colors(colors = NULL, clusters = log_var_sorted) } diff --git a/man/sort_clusters.Rd b/man/sort_clusters.Rd index 93d05aa4..66ec783c 100644 --- a/man/sort_clusters.Rd +++ b/man/sort_clusters.Rd @@ -13,13 +13,13 @@ sort_clusters(clusters, map_subset = NULL) which elements of \code{clusters} to use to determine the ranking of the clusters.} } \value{ -A factor of length equal to \code{clusters} where the levels are the new -ordered clusters and the names of the factor are the original values from -\code{clusters}. +A \code{factor()} version of \code{clusters} where the levels are ordered by +frequency. } \description{ -This function takes a vector with cluster labels and sorts it by frequency -such that the most frequent cluster is the first one and so on. +This function takes a vector with cluster labels, recasts it as a \code{factor()}, +and sorts the \code{factor()} levels by frequency such that the most frequent +cluster is the first level and so on. } \examples{ @@ -29,6 +29,42 @@ clus <- letters[unlist(lapply(4:1, function(x) rep(x, x)))] ## In this case, it's a character vector class(clus) -## Sort them and obtain a factor +## We see that we have 10 elements in this vector, which is +## an unnamed character vector +clus + +## letter 'd' is the most frequent +table(clus) + +## Sort them and obtain a factor. Notice that it's a named +## factor, and the names correspond to the original values +## in the character vector. sort_clusters(clus) + +## Since 'd' was the most frequent, it gets assigned to the first level +## in the factor variable. +table(sort_clusters(clus)) + +## If we skip the first 3 values of clus (which are all 'd'), we can +## change the most frequent cluster. And thus the ordering of the +## factor levels. +sort_clusters(clus, map_subset = seq_len(length(clus)) > 3) + +## Let's try with a factor variable +clus_factor <- factor(clus) +## sort_clusters() returns an identical result in this case +stopifnot(identical(sort_clusters(clus), sort_clusters(clus_factor))) + +## What happens if you have a logical variable with NAs? +set.seed(20240712) +log_var <- sample(c(TRUE, FALSE, NA), + 1000, + replace = TRUE, + prob = c(0.3, 0.15, 0.55)) +## Here, the NAs are the most frequent group. +table(log_var, useNA = "ifany") + +## The NAs are not used for sorting. Since we have more 'TRUE' than 'FALSE' +## then, 'TRUE' becomes the first level. +table(sort_clusters(log_var), useNA = "ifany") } From 4c7274f732e17d5a8960d70e1cce04d9a2ef5747 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 12 Jul 2024 10:56:37 -0400 Subject: [PATCH 180/259] v1.17.6 -- related to #80 --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f052acac..625e18e3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.5 -Date: 2024-07-10 +Version: 1.17.6 +Date: 2024-07-12 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From 9280e5c0b650daf23583c7e2a7d957e0515358b3 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 12 Jul 2024 14:34:11 -0400 Subject: [PATCH 181/259] Edited add_qc_metrics() to match recent changes related to #80 Co-authored-by: Louise Huuki --- R/add_qc_metrics.R | 31 +++++++++++++++---------------- man/add_qc_metrics.Rd | 19 ++++++++++++++----- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index cbe38bcc..c1213184 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -54,6 +54,18 @@ #' #' ## visualize edge spots #' vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "edge_spot") +#' +#' ## specify your own colors +#' vis_clus( +#' spe_qc, +#' sampleid = "Br6432_ant", +#' clustervar = "edge_spot", +#' colors = c( +#' "TRUE" = "lightgreen", +#' "FALSE" = "pink", +#' "NA" = "red" +#' ) +#' ) #' vis_gene(spe_qc, sampleid = "Br6432_ant", geneid = "edge_distance", minCount = -1) #' #' ## Visualize scran QC flags @@ -73,11 +85,8 @@ #' #' ## Use `low_library_size` (or other variables) and `edge_distance` as you #' ## please. -#' spe_qc$our_low_lib_edge <- factor( -#' spe_qc$scran_low_lib_size == "TRUE" & -#' spe_qc$edge_distance < 5, -#' levels = c("TRUE", "FALSE") -#' ) +#' spe_qc$our_low_lib_edge <- spe_qc$scran_low_lib_size & spe_qc$edge_distance < 5 +#' #' vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") #' #' ## Clean up @@ -136,27 +145,19 @@ add_qc_metrics <- function(spe, overwrite = FALSE) { ## discard spe$scran_discard <- NA spe$scran_discard[which(spe$in_tissue)] <- qcfilter$discard - spe$scran_discard <- factor(spe$scran_discard, levels = c("TRUE", "FALSE")) ## low_lib_size spe$scran_low_lib_size <- NA spe$scran_low_lib_size[which(spe$in_tissue)] <- qcfilter$low_lib_size - spe$scran_low_lib_size <- factor(spe$scran_low_lib_size, - levels = c("TRUE", "FALSE") - ) + ## low_n_features spe$scran_low_n_features <- NA spe$scran_low_n_features[which(spe$in_tissue)] <- qcfilter$low_n_features - spe$scran_low_n_features <- factor(spe$scran_low_n_features, - levels = c("TRUE", "FALSE") - ) ## high mito percent spe$scran_high_Mito_percent <- NA spe$scran_high_Mito_percent[which(spe$in_tissue)] <- qcfilter$high_subsets_Mito_percent - spe$scran_high_Mito_percent <- - factor(spe$scran_high_Mito_percent, levels = c("TRUE", "FALSE")) ## Find edge spots # define variables @@ -192,14 +193,12 @@ add_qc_metrics <- function(spe, overwrite = FALSE) { ## Add Edge info to spe spe$edge_spot <- NA spe$edge_spot[which(spe$in_tissue)] <- spot_coords$edge_spot - spe$edge_spot <- factor(spe$edge_spot, levels = c("TRUE", "FALSE")) spe$edge_distance <- NA spe$edge_distance[which(spe$in_tissue)] <- spot_coords$edge_distance spe$scran_low_lib_size_edge <- NA spe$scran_low_lib_size_edge[which(spe$in_tissue)] <- qcfilter$low_lib_size & spot_coords$edge_spot - spe$scran_low_lib_size_edge <- factor(spe$scran_low_lib_size_edge, levels = c("TRUE", "FALSE")) return(spe) } diff --git a/man/add_qc_metrics.Rd b/man/add_qc_metrics.Rd index a02b439d..22e91df7 100644 --- a/man/add_qc_metrics.Rd +++ b/man/add_qc_metrics.Rd @@ -59,6 +59,18 @@ vars[grep("^(scran|edge)", vars)] ## visualize edge spots vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "edge_spot") + +## specify your own colors +vis_clus( + spe_qc, + sampleid = "Br6432_ant", + clustervar = "edge_spot", + colors = c( + "TRUE" = "lightgreen", + "FALSE" = "pink", + "NA" = "red" + ) +) vis_gene(spe_qc, sampleid = "Br6432_ant", geneid = "edge_distance", minCount = -1) ## Visualize scran QC flags @@ -78,11 +90,8 @@ vis_clus(spe_qc, sampleid = "Br6432_ant", clustervar = "scran_low_lib_size_edge" ## Use `low_library_size` (or other variables) and `edge_distance` as you ## please. -spe_qc$our_low_lib_edge <- factor( - spe_qc$scran_low_lib_size == "TRUE" & - spe_qc$edge_distance < 5, - levels = c("TRUE", "FALSE") -) +spe_qc$our_low_lib_edge <- spe_qc$scran_low_lib_size & spe_qc$edge_distance < 5 + vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") ## Clean up From e9a7f37b4baa2b0e192ee58da99290b55bafd46b Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Mon, 15 Jul 2024 14:53:28 -0400 Subject: [PATCH 182/259] Improved docs a bit after feedback from @cyntsc --- R/app_ui.R | 4 ++-- R/data.R | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/R/app_ui.R b/R/app_ui.R index e9af3215..3366fdd3 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -779,7 +779,7 @@ app_ui <- function() { helpText( "It should be a CSV file without row names and similar to ", HTML( - 'this example file.' + 'this example file. For more context, check this figure.' ) ) ), @@ -840,7 +840,7 @@ app_ui <- function() { helpText( "It should be a CSV file similar to ", HTML( - 'this example file.' + 'this example file, documented here. For more context, check this figure.' ) ) ), diff --git a/R/data.R b/R/data.R index 6dc68479..789b7483 100644 --- a/R/data.R +++ b/R/data.R @@ -10,9 +10,13 @@ #' Cell cluster t-statistics from Tran et al #' -#' Using the DLPFC snRNA-seq data from Matthew N Tran et al we computed -#' enrichment t-statistics for the cell clusters. This is a subset of them -#' used in examples such as in [layer_stat_cor_plot()]. +#' Using the DLPFC snRNA-seq data from Matthew N Tran et al +#' we computed +#' enrichment t-statistics for the cell clusters. The Tran et al data has been +#' subset to the top 100 DLPFC layer markers found in Maynard, Collado-Torres, +#' et al 2021. This data is used in examples such as in +#' [layer_stat_cor_plot()]. The Tran et al data is from the pre-print version +#' of that project. #' #' @format A matrix with 692 rows and 31 variables where each column is #' a given cell cluster from Tran et al and each row is one gene. The row names From 59b0af4f0491bd66f9b04ed8e30c2a0d2aa38d28 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 16 Jul 2024 17:17:00 -0400 Subject: [PATCH 183/259] Work on docs, trying to debug pkgdown error --- R/add_key.R | 9 +++++++- R/add_qc_metrics.R | 2 +- R/check_sce_layer.R | 5 +++-- R/vis_clus.R | 6 ++++- R/vis_clus_p.R | 4 ++-- R/vis_gene.R | 16 +++++++------- R/vis_gene_p.R | 8 +++---- man/add_images.Rd | 8 +++---- man/add_key.Rd | 9 +++++++- man/add_qc_metrics.Rd | 2 +- man/check_sce_layer.Rd | 5 +++-- man/check_spe.Rd | 8 +++---- man/cluster_export.Rd | 8 +++---- man/cluster_import.Rd | 8 +++---- man/frame_limits.Rd | 8 +++---- man/img_edit.Rd | 8 +++---- man/img_update.Rd | 8 +++---- man/img_update_all.Rd | 8 +++---- man/locate_images.Rd | 8 +++---- ...ts_Human_DLPFC_snRNAseq_Nguyen_topLayer.Rd | 10 ++++++--- man/vis_clus.Rd | 8 +++---- man/vis_clus_p.Rd | 12 +++++----- man/vis_gene.Rd | 22 +++++++++---------- man/vis_gene_p.Rd | 16 +++++++------- man/vis_grid_clus.Rd | 8 +++---- man/vis_grid_gene.Rd | 18 +++++++-------- 26 files changed, 128 insertions(+), 104 deletions(-) diff --git a/R/add_key.R b/R/add_key.R index 648ecc30..ce851b66 100644 --- a/R/add_key.R +++ b/R/add_key.R @@ -21,13 +21,20 @@ #' head(spe$key) #' #' ## We can clean it +#' spe$key_original <- spe$key #' spe$key <- NULL #' #' ## and then add it back -#' head(add_key(spe)$key) +#' spe <- add_key(spe) +#' head(spe$key) #' #' ## Note that the original 'key' order was 'sample_id'_'barcode' and we' #' ## have since changed it to 'barcode'_'sample_id'. +#' +#' ## Below we restore the original 'key' +#' spe$key <- spe$key_original +#' spe$key_original <- NULL +#' head(spe$key) #' } add_key <- function(spe, overwrite = TRUE) { if ("key" %in% colnames(colData(spe))) { diff --git a/R/add_qc_metrics.R b/R/add_qc_metrics.R index c1213184..a5c7ca32 100644 --- a/R/add_qc_metrics.R +++ b/R/add_qc_metrics.R @@ -90,7 +90,7 @@ #' vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") #' #' ## Clean up -#' rm(spe_qc, spec_pre_qc) +#' rm(spe_qc, spe_pre_qc, vars) #' add_qc_metrics <- function(spe, overwrite = FALSE) { stopifnot("in_tissue" %in% colnames(colData(spe))) diff --git a/R/check_sce_layer.R b/R/check_sce_layer.R index e7280113..5ca9b5ae 100644 --- a/R/check_sce_layer.R +++ b/R/check_sce_layer.R @@ -14,10 +14,11 @@ #' #' @examples #' -#' ## Obtain the necessary data +#' ## Obtain example data from the HumanPilot project +#' ## (Maynard, Collado-Torres, et al, 2021) #' if (!exists("sce_layer")) sce_layer <- fetch_data("sce_layer") #' -#' ## Check the object +#' ## Check the pseudo-bulked data #' check_sce_layer(sce_layer) check_sce_layer <- function(sce_layer, variables = "spatialLIBD") { ## Should be a SingleCellExperiment object diff --git a/R/vis_clus.R b/R/vis_clus.R index 1bca16bf..e1e0eaa0 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -4,7 +4,11 @@ #' using (by default) the histology information on the background. To visualize #' gene-level (or any continuous variable) use [vis_gene()]. #' -#' @inheritParams run_app +#' @param spe A +#' [SpatialExperiment-class][SpatialExperiment::SpatialExperiment-class] +#' object. See [fetch_data()] for how to download some example objects or +#' [read10xVisiumWrapper()] to read in `spaceranger --count` output files and +#' build your own `spe` object. #' @param sampleid A `character(1)` specifying which sample to plot from #' `colData(spe)$sample_id` (formerly `colData(spe)$sample_name`). #' @param clustervar A `character(1)` with the name of the `colData(spe)` diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index d2b37cec..f74b95f6 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -6,8 +6,8 @@ #' gene-level (or any continuous variable) use [vis_gene_p()]. #' #' @inheritParams vis_clus -#' @param d A data.frame with the sample-level information. This is typically -#' obtained using `cbind(colData(spe), spatialCoords(spe))`. +#' @param d A `data.frame()` with the sample-level information. This is +#' typically obtained using `cbind(colData(spe), spatialCoords(spe))`. #' @param title The title for the plot. #' #' @return A [ggplot2][ggplot2::ggplot] object. diff --git a/R/vis_gene.R b/R/vis_gene.R index 38a233aa..ed056ba5 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -7,11 +7,11 @@ #' #' @inheritParams vis_clus #' @param geneid A `character()` specifying the gene ID(s) stored in -#' `rowData(spe)$gene_search` or a continuous variable(s) stored in `colData(spe)` -#' to visualize. For each ID, if `rowData(spe)$gene_search` is missing, then -#' `rownames(spe)` is used to search for the gene ID. When a vector of length > 1 -#' is supplied, the continuous variables are combined according to \code{multi_gene_method}, -#' producing a single value for each spot. +#' `rowData(spe)$gene_search` or a continuous variable(s) stored in +#' `colData(spe)` to visualize. For each ID, if `rowData(spe)$gene_search` is +#' missing, then `rownames(spe)` is used to search for the gene ID. When a +#' vector of length > 1 is supplied, the continuous variables are combined +#' according to `multi_gene_method`, producing a single value for each spot. #' @param assayname The name of the `assays(spe)` to use for extracting the #' gene expression data. Defaults to `logcounts`. #' @param minCount A `numeric(1)` specifying the minimum gene expression (or @@ -25,9 +25,9 @@ #' dependent on cell density. #' @param cont_colors A `character()` vector of colors that supersedes the #' `viridis` argument. -#' @param multi_gene_method A \code{character(1)}: either "pca", "sparsity", or -#' "z_score". This parameter controls how multiple continuous variables are -#' combined for visualization, and only applies when \code{geneid} has length +#' @param multi_gene_method A `character(1)`: either `"pca"`, `"sparsity"`, or +#' `"z_score"`. This parameter controls how multiple continuous variables are +#' combined for visualization, and only applies when `geneid` has length #' great than 1. `z_score`: to summarize multiple continuous variables, each is #' normalized to represent a Z-score. The multiple scores are then averaged. #' `pca`: PCA dimension reduction is conducted on the matrix formed by the diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 632b864c..baeee29e 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -3,12 +3,12 @@ #' This function visualizes the gene expression stored in `assays(spe)` or any #' continuous variable stored in `colData(spe)` for one given sample at the #' spot-level using (by default) the histology information on the background. -#' This is the function that does all the plotting behind [vis_gene()]. +#' This is the function that does all the plotting behind [vis_gene()] #' To visualize clusters (or any discrete variable) use [vis_clus_p()]. #' -#' @param d A data.frame with the sample-level information. This is typically -#' obtained using `cbind(colData(spe), spatialCoords(spe))`. -#' The data.frame has to contain +#' @param d A `data.frame()` with the sample-level information. This is +#' typically obtained using `cbind(colData(spe), spatialCoords(spe))`. +#' The `data.frame` has to contain #' a column with the continuous variable data to plot stored under `d$COUNT`. #' @param legend_title A `character(1)` specifying the legend title. #' @inheritParams vis_clus_p diff --git a/man/add_images.Rd b/man/add_images.Rd index dfe964fd..6e85ffb5 100644 --- a/man/add_images.Rd +++ b/man/add_images.Rd @@ -14,11 +14,11 @@ add_images( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{image_dir}{A \code{character(1)} specifying a path to a directory containing image files with the pattern \code{sampleID_pattern.png}.} diff --git a/man/add_key.Rd b/man/add_key.Rd index 699aaf67..b13e780f 100644 --- a/man/add_key.Rd +++ b/man/add_key.Rd @@ -31,12 +31,19 @@ if (enough_ram()) { head(spe$key) ## We can clean it + spe$key_original <- spe$key spe$key <- NULL ## and then add it back - head(add_key(spe)$key) + spe <- add_key(spe) + head(spe$key) ## Note that the original 'key' order was 'sample_id'_'barcode' and we' ## have since changed it to 'barcode'_'sample_id'. + + ## Below we restore the original 'key' + spe$key <- spe$key_original + spe$key_original <- NULL + head(spe$key) } } diff --git a/man/add_qc_metrics.Rd b/man/add_qc_metrics.Rd index 22e91df7..7623b2c2 100644 --- a/man/add_qc_metrics.Rd +++ b/man/add_qc_metrics.Rd @@ -95,7 +95,7 @@ spe_qc$our_low_lib_edge <- spe_qc$scran_low_lib_size & spe_qc$edge_distance < 5 vis_clus(spe_qc, sample_id = "Br6432_ant", clustervar = "our_low_lib_edge") ## Clean up -rm(spe_qc, spec_pre_qc) +rm(spe_qc, spe_pre_qc, vars) } \author{ diff --git a/man/check_sce_layer.Rd b/man/check_sce_layer.Rd index cac2d6c7..d2c9bf32 100644 --- a/man/check_sce_layer.Rd +++ b/man/check_sce_layer.Rd @@ -25,10 +25,11 @@ For more details please check the vignette documentation. } \examples{ -## Obtain the necessary data +## Obtain example data from the HumanPilot project +## (Maynard, Collado-Torres, et al, 2021) if (!exists("sce_layer")) sce_layer <- fetch_data("sce_layer") -## Check the object +## Check the pseudo-bulked data check_sce_layer(sce_layer) } \seealso{ diff --git a/man/check_spe.Rd b/man/check_spe.Rd index ecaa9867..577afeec 100644 --- a/man/check_spe.Rd +++ b/man/check_spe.Rd @@ -10,11 +10,11 @@ check_spe( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{variables}{A \code{character()} vector of variable names expected to be present in \code{colData(spe)}.} diff --git a/man/cluster_export.Rd b/man/cluster_export.Rd index 613e5cdf..238cb5aa 100644 --- a/man/cluster_export.Rd +++ b/man/cluster_export.Rd @@ -12,11 +12,11 @@ cluster_export( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{cluster_var}{A \code{character(1)} with the name of the variable you wish to export.} diff --git a/man/cluster_import.Rd b/man/cluster_import.Rd index 778a73d8..2c7288fa 100644 --- a/man/cluster_import.Rd +++ b/man/cluster_import.Rd @@ -12,11 +12,11 @@ cluster_import( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{cluster_dir}{A \code{character(1)} specifying the output directory, similar to the \code{outs/analysis/clustering} produced by SpaceRanger.} diff --git a/man/frame_limits.Rd b/man/frame_limits.Rd index 8b5cbe77..9274af88 100644 --- a/man/frame_limits.Rd +++ b/man/frame_limits.Rd @@ -13,11 +13,11 @@ frame_limits( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{sampleid}{A \code{character(1)} specifying which sample to plot from \code{colData(spe)$sample_id} (formerly \code{colData(spe)$sample_name}).} diff --git a/man/img_edit.Rd b/man/img_edit.Rd index 699bea07..a2392bce 100644 --- a/man/img_edit.Rd +++ b/man/img_edit.Rd @@ -26,11 +26,11 @@ img_edit( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{sampleid}{A \code{character(1)} specifying which sample to plot from \code{colData(spe)$sample_id} (formerly \code{colData(spe)$sample_name}).} diff --git a/man/img_update.Rd b/man/img_update.Rd index 3d0c1315..b3b1ecdb 100644 --- a/man/img_update.Rd +++ b/man/img_update.Rd @@ -14,11 +14,11 @@ img_update( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{sampleid}{A \code{character(1)} specifying which sample to plot from \code{colData(spe)$sample_id} (formerly \code{colData(spe)$sample_name}).} diff --git a/man/img_update_all.Rd b/man/img_update_all.Rd index 2040e55b..a4d4f36c 100644 --- a/man/img_update_all.Rd +++ b/man/img_update_all.Rd @@ -13,11 +13,11 @@ img_update_all( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{image_id}{A \code{character(1)} with the name of the image ID you want to use in the background.} diff --git a/man/locate_images.Rd b/man/locate_images.Rd index 6041b6c8..58448fb8 100644 --- a/man/locate_images.Rd +++ b/man/locate_images.Rd @@ -7,11 +7,11 @@ locate_images(spe, image_dir, image_pattern) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{image_dir}{A \code{character(1)} specifying a path to a directory containing image files with the pattern \code{sampleID_pattern.png}.} diff --git a/man/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.Rd b/man/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.Rd index 11d2c849..2996d31a 100644 --- a/man/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.Rd +++ b/man/tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer.Rd @@ -19,8 +19,12 @@ and tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer } \description{ -Using the DLPFC snRNA-seq data from Matthew N Tran et al we computed -enrichment t-statistics for the cell clusters. This is a subset of them -used in examples such as in \code{\link[=layer_stat_cor_plot]{layer_stat_cor_plot()}}. +Using the DLPFC snRNA-seq data from Matthew N Tran et al +\url{https://doi.org/10.1016/j.neuron.2021.09.001} we computed +enrichment t-statistics for the cell clusters. The Tran et al data has been +subset to the top 100 DLPFC layer markers found in Maynard, Collado-Torres, +et al 2021. This data is used in examples such as in +\code{\link[=layer_stat_cor_plot]{layer_stat_cor_plot()}}. The Tran et al data is from the pre-print version +of that project. } \keyword{datasets} diff --git a/man/vis_clus.Rd b/man/vis_clus.Rd index 10729e46..34513c66 100644 --- a/man/vis_clus.Rd +++ b/man/vis_clus.Rd @@ -21,11 +21,11 @@ vis_clus( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{sampleid}{A \code{character(1)} specifying which sample to plot from \code{colData(spe)$sample_id} (formerly \code{colData(spe)$sample_name}).} diff --git a/man/vis_clus_p.Rd b/man/vis_clus_p.Rd index 3706e6a2..b8202f1f 100644 --- a/man/vis_clus_p.Rd +++ b/man/vis_clus_p.Rd @@ -20,14 +20,14 @@ vis_clus_p( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} -\item{d}{A data.frame with the sample-level information. This is typically -obtained using \code{cbind(colData(spe), spatialCoords(spe))}.} +\item{d}{A \code{data.frame()} with the sample-level information. This is +typically obtained using \code{cbind(colData(spe), spatialCoords(spe))}.} \item{clustervar}{A \code{character(1)} with the name of the \code{colData(spe)} column that has the cluster values.} diff --git a/man/vis_gene.Rd b/man/vis_gene.Rd index 2a6f94e6..bba4dc60 100644 --- a/man/vis_gene.Rd +++ b/man/vis_gene.Rd @@ -25,21 +25,21 @@ vis_gene( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{sampleid}{A \code{character(1)} specifying which sample to plot from \code{colData(spe)$sample_id} (formerly \code{colData(spe)$sample_name}).} \item{geneid}{A \code{character()} specifying the gene ID(s) stored in -\code{rowData(spe)$gene_search} or a continuous variable(s) stored in \code{colData(spe)} -to visualize. For each ID, if \code{rowData(spe)$gene_search} is missing, then -\code{rownames(spe)} is used to search for the gene ID. When a vector of length > 1 -is supplied, the continuous variables are combined according to \code{multi_gene_method}, -producing a single value for each spot.} +\code{rowData(spe)$gene_search} or a continuous variable(s) stored in +\code{colData(spe)} to visualize. For each ID, if \code{rowData(spe)$gene_search} is +missing, then \code{rownames(spe)} is used to search for the gene ID. When a +vector of length > 1 is supplied, the continuous variables are combined +according to \code{multi_gene_method}, producing a single value for each spot.} \item{spatial}{A \code{logical(1)} indicating whether to include the histology layer from \code{\link[=geom_spatial]{geom_spatial()}}. If you plan to use @@ -81,8 +81,8 @@ alpha blending already, which will make non-NA values pop up more and the NA values will show with a lighter color. This behavior is lost when \code{alpha} is set to a non-\code{NA} value.} -\item{multi_gene_method}{A \code{character(1)}: either "pca", "sparsity", or -"z_score". This parameter controls how multiple continuous variables are +\item{multi_gene_method}{A \code{character(1)}: either \code{"pca"}, \code{"sparsity"}, or +\code{"z_score"}. This parameter controls how multiple continuous variables are combined for visualization, and only applies when \code{geneid} has length great than 1. \code{z_score}: to summarize multiple continuous variables, each is normalized to represent a Z-score. The multiple scores are then averaged. diff --git a/man/vis_gene_p.Rd b/man/vis_gene_p.Rd index c1115f71..d8fb4ea0 100644 --- a/man/vis_gene_p.Rd +++ b/man/vis_gene_p.Rd @@ -26,15 +26,15 @@ vis_gene_p( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} -\item{d}{A data.frame with the sample-level information. This is typically -obtained using \code{cbind(colData(spe), spatialCoords(spe))}. -The data.frame has to contain +\item{d}{A \code{data.frame()} with the sample-level information. This is +typically obtained using \code{cbind(colData(spe), spatialCoords(spe))}. +The \code{data.frame} has to contain a column with the continuous variable data to plot stored under \code{d$COUNT}.} \item{sampleid}{A \code{character(1)} specifying which sample to plot from @@ -84,7 +84,7 @@ A \link[ggplot2:ggplot]{ggplot2} object. This function visualizes the gene expression stored in \code{assays(spe)} or any continuous variable stored in \code{colData(spe)} for one given sample at the spot-level using (by default) the histology information on the background. -This is the function that does all the plotting behind \code{\link[=vis_gene]{vis_gene()}}. +This is the function that does all the plotting behind \code{\link[=vis_gene]{vis_gene()}} To visualize clusters (or any discrete variable) use \code{\link[=vis_clus_p]{vis_clus_p()}}. } \examples{ diff --git a/man/vis_grid_clus.Rd b/man/vis_grid_clus.Rd index 19dd2c3a..af943564 100644 --- a/man/vis_grid_clus.Rd +++ b/man/vis_grid_clus.Rd @@ -25,11 +25,11 @@ vis_grid_clus( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{clustervar}{A \code{character(1)} with the name of the \code{colData(spe)} column that has the cluster values.} diff --git a/man/vis_grid_gene.Rd b/man/vis_grid_gene.Rd index a102cbbe..40b7461c 100644 --- a/man/vis_grid_gene.Rd +++ b/man/vis_grid_gene.Rd @@ -28,18 +28,18 @@ vis_grid_gene( ) } \arguments{ -\item{spe}{Defaults to the output of -\code{fetch_data(type = 'spe')}. This is a +\item{spe}{A \link[SpatialExperiment:SpatialExperiment]{SpatialExperiment-class} -object with the spot-level Visium data and information required for -visualizing the histology. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +object. See \code{\link[=fetch_data]{fetch_data()}} for how to download some example objects or +\code{\link[=read10xVisiumWrapper]{read10xVisiumWrapper()}} to read in \code{spaceranger --count} output files and +build your own \code{spe} object.} \item{geneid}{A \code{character()} specifying the gene ID(s) stored in -\code{rowData(spe)$gene_search} or a continuous variable(s) stored in \code{colData(spe)} -to visualize. For each ID, if \code{rowData(spe)$gene_search} is missing, then -\code{rownames(spe)} is used to search for the gene ID. When a vector of length > 1 -is supplied, the continuous variables are combined according to \code{multi_gene_method}, -producing a single value for each spot.} +\code{rowData(spe)$gene_search} or a continuous variable(s) stored in +\code{colData(spe)} to visualize. For each ID, if \code{rowData(spe)$gene_search} is +missing, then \code{rownames(spe)} is used to search for the gene ID. When a +vector of length > 1 is supplied, the continuous variables are combined +according to \code{multi_gene_method}, producing a single value for each spot.} \item{pdf_file}{A \code{character(1)} specifying the path for the resulting PDF.} From 76a282d4bc33e615929185fa7b2e84971c9b47ed Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 16 Jul 2024 18:30:25 -0400 Subject: [PATCH 184/259] Test if using the format of man/vis_gene.Rd in man/vis_gene_p.Rd fixes the issue at https://github.com/r-lib/pkgdown/issues/2727 --- man/vis_gene_p.Rd | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/man/vis_gene_p.Rd b/man/vis_gene_p.Rd index d8fb4ea0..b905af47 100644 --- a/man/vis_gene_p.Rd +++ b/man/vis_gene_p.Rd @@ -13,12 +13,8 @@ vis_gene_p( viridis = TRUE, image_id = "lowres", alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - - c("aquamarine4", "springgreen", "goldenrod", "red") - }, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", + "springgreen", "goldenrod", "red"), point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", @@ -113,7 +109,7 @@ if (enough_ram()) { } } \seealso{ -Other Spatial gene visualization functions: +Other Spatial gene visualization functions: \code{\link{vis_gene}()}, \code{\link{vis_grid_gene}()} } From 6f168a324290b759e9ecc7b3bbbc55ad5f3c1773 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Wed, 17 Jul 2024 09:12:15 -0400 Subject: [PATCH 185/259] Use the same usage definition in vis_gene_p() as in vis_gene(). Try to workaround https://github.com/r-lib/pkgdown/issues/2727 --- R/vis_gene_p.R | 6 +----- man/vis_gene_p.Rd | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index baeee29e..48741fa9 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -56,11 +56,7 @@ vis_gene_p <- viridis = TRUE, image_id = "lowres", alpha = NA, - cont_colors = if (viridis) { - viridisLite::viridis(21) - } else { - c("aquamarine4", "springgreen", "goldenrod", "red") - }, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), point_size = 2, auto_crop = TRUE, na_color = "#CCCCCC40", diff --git a/man/vis_gene_p.Rd b/man/vis_gene_p.Rd index b905af47..ca9d6a29 100644 --- a/man/vis_gene_p.Rd +++ b/man/vis_gene_p.Rd @@ -109,7 +109,7 @@ if (enough_ram()) { } } \seealso{ -Other Spatial gene visualization functions: +Other Spatial gene visualization functions: \code{\link{vis_gene}()}, \code{\link{vis_grid_gene}()} } From a5729c0540d560d337a7dd0ce4a295fb67550486 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 19 Jul 2024 11:32:51 -0400 Subject: [PATCH 186/259] Change from LS_visiumStitched to visiumStitched_brain Co-authored-by: Nick Eagles --- R/fetch_data.R | 22 +++++++++---------- inst/extdata/metadata_Visium_LS.csv | 4 ---- .../extdata/metadata_visiumStitched_brain.csv | 4 ++++ ...R => make-metadata_visiumStitched_brain.R} | 18 +++++++-------- man/fetch_data.Rd | 4 ++-- 5 files changed, 26 insertions(+), 26 deletions(-) delete mode 100644 inst/extdata/metadata_Visium_LS.csv create mode 100644 inst/extdata/metadata_visiumStitched_brain.csv rename inst/scripts/{make-metadata_Visium_LS.R => make-metadata_visiumStitched_brain.R} (89%) diff --git a/R/fetch_data.R b/R/fetch_data.R index 8f859e5b..06e17e09 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -100,9 +100,9 @@ fetch_data <- "Visium_SPG_AD_Visium_targeted_spe", "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", "Visium_SPG_AD_Visium_wholegenome_modeling_results", - "Visium_LS_spe", - "Visium_LS_spaceranger", - "Visium_LS_ImageJ_out" + "visiumStitched_brain_spe", + "visiumStitched_brain_spaceranger", + "visiumStitched_brain_ImageJ_out" ), destdir = tempdir(), eh = ExperimentHub::ExperimentHub(), @@ -266,25 +266,25 @@ fetch_data <- hub_title <- type ## While EH is not set-up - file_name <- "Visium_LS_spe.rds" + file_name <- "visiumStitched_brain_spe.rds" url <- - "https://www.dropbox.com/scl/fi/9re464y6qaojx3r94nq5u/Visium_LS_spe.rds?rlkey=nq6a82u23xuu9hohr86oodwdi&dl=1" - } else if (type == "Visium_LS_spaceranger") { + "https://www.dropbox.com/scl/fi/9re464y6qaojx3r94nq5u/visiumStitched_brain_spe.rds?rlkey=nq6a82u23xuu9hohr86oodwdi&dl=1" + } else if (type == "visiumStitched_brain_spaceranger") { tag <- "VisiumLS_Visium_stitched_spatialLIBD" hub_title <- type ## While EH is not set-up - file_name <- "Visium_LS_spaceranger.zip" + file_name <- "visiumStitched_brain_spaceranger.zip" url <- - "https://www.dropbox.com/scl/fi/5jdoaukvhq3v7lk19228y/Visium_LS_spaceranger.zip?rlkey=bdgjc6mgy1ierdad6h6v5g29c&dl=1" - } else if (type == "Visium_LS_ImageJ_out") { + "https://www.dropbox.com/scl/fi/5jdoaukvhq3v7lk19228y/visiumStitched_brain_spaceranger.zip?rlkey=bdgjc6mgy1ierdad6h6v5g29c&dl=1" + } else if (type == "visiumStitched_brain_ImageJ_out") { tag <- "VisiumLS_Visium_stitched_spatialLIBD" hub_title <- type ## While EH is not set-up - file_name <- "Visium_LS_imagej_out.zip" + file_name <- "visiumStitched_brain_imagej_out.zip" url <- - "https://www.dropbox.com/scl/fi/bevo52e96f2kdwllf8dkk/Visium_LS_imagej_out.zip?rlkey=ptwal8f5zxakzejwd0oqw0lhj&dl=1" + "https://www.dropbox.com/scl/fi/bevo52e96f2kdwllf8dkk/visiumStitched_brain_imagej_out.zip?rlkey=ptwal8f5zxakzejwd0oqw0lhj&dl=1" } file_path <- file.path(destdir, file_name) diff --git a/inst/extdata/metadata_Visium_LS.csv b/inst/extdata/metadata_Visium_LS.csv deleted file mode 100644 index 5b868cf7..00000000 --- a/inst/extdata/metadata_Visium_LS.csv +++ /dev/null @@ -1,4 +0,0 @@ -Title,Description,BiocVersion,Genome,SourceType,SourceUrl,SourceVersion,Species,TaxonomyId,Coordinate_1_based,DataProvider,Maintainer,RDataClass,DispatchClass,RDataPath,Tags -Visium_LS_spe,SpatialExperiment object at the spot-level for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.,3.19,GRCh38,GTF,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,SpatialExperiment,Rds,spatialLIBD/spatialLIBD_files/Visium_LS_spe.rds,VisiumLS_Visium_stitched_spatialLIBD -Visium_LS_spaceranger,Spaceranger outputs for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/Visium_LS_spaceranger.zip,VisiumLS_Visium_stitched_spatialLIBD -Visium_LS_ImageJ_out,Stitched PNG image and XML file from aligning lateral septum human brain (LS) spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/Visium_LS_imagej_out.zip,VisiumLS_Visium_stitched_spatialLIBD diff --git a/inst/extdata/metadata_visiumStitched_brain.csv b/inst/extdata/metadata_visiumStitched_brain.csv new file mode 100644 index 00000000..64af76ef --- /dev/null +++ b/inst/extdata/metadata_visiumStitched_brain.csv @@ -0,0 +1,4 @@ +Title,Description,BiocVersion,Genome,SourceType,SourceUrl,SourceVersion,Species,TaxonomyId,Coordinate_1_based,DataProvider,Maintainer,RDataClass,DispatchClass,RDataPath,Tags +visiumStitched_brain_spe,SpatialExperiment object at the spot-level for the spatially stitched human brain spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.,3.19,GRCh38,GTF,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,SpatialExperiment,Rds,spatialLIBD/spatialLIBD_files/visiumStitched_brain_spe.rds,visiumStitched_brain_spatialLIBD +visiumStitched_brain_spaceranger,Spaceranger outputs for the spatially stitched human brain (spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/visiumStitched_brain_spaceranger.zip,visiumStitched_brain_spatialLIBD +visiumStitched_brain_ImageJ_out,Stitched PNG image and XML file from aligning human brain spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/visiumStitched_brain_imagej_out.zip,visiumStitched_brain_spatialLIBD diff --git a/inst/scripts/make-metadata_Visium_LS.R b/inst/scripts/make-metadata_visiumStitched_brain.R similarity index 89% rename from inst/scripts/make-metadata_Visium_LS.R rename to inst/scripts/make-metadata_visiumStitched_brain.R index 9fefe846..0f18ef34 100644 --- a/inst/scripts/make-metadata_Visium_LS.R +++ b/inst/scripts/make-metadata_visiumStitched_brain.R @@ -6,11 +6,11 @@ outdir <- "spatialLIBD_files" pkgname <- "spatialLIBD" meta <- tibble( - Title = c("Visium_LS_spe", "Visium_LS_spaceranger", "Visium_LS_ImageJ_out"), + Title = c("visiumStitched_brain_spe", "visiumStitched_brain_spaceranger", "visiumStitched_brain_ImageJ_out"), Description = c( - "SpatialExperiment object at the spot-level for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", - "Spaceranger outputs for the spatially stitched lateral septum human brain (LS) spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.", - "Stitched PNG image and XML file from aligning lateral septum human brain (LS) spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package." + "SpatialExperiment object at the spot-level for the spatially stitched human brain spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", + "Spaceranger outputs for the spatially stitched human brain (spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.", + "Stitched PNG image and XML file from aligning human brain spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package." ), BiocVersion = "3.19", Genome = "GRCh38", @@ -28,20 +28,20 @@ meta <- tibble( pkgname, outdir, c( - "Visium_LS_spe.rds", "Visium_LS_spaceranger.zip", - "Visium_LS_imagej_out.zip" + "visiumStitched_brain_spe.rds", "visiumStitched_brain_spaceranger.zip", + "visiumStitched_brain_imagej_out.zip" ) ), - Tags = "VisiumLS_Visium_stitched_spatialLIBD" + Tags = "visiumStitched_brain_spatialLIBD" ) -write_csv(meta, here("inst", "extdata", "metadata_Visium_LS.csv")) +write_csv(meta, here("inst", "extdata", "metadata_visiumStitched_brain.csv")) ## Check interactively if (FALSE) { AnnotationHubData::makeAnnotationHubMetadata( here(), - fileName = "metadata_Visium_LS.csv" + fileName = "metadata_visiumStitched_brain.csv" ) } diff --git a/man/fetch_data.Rd b/man/fetch_data.Rd index ac411d47..8a59b913 100644 --- a/man/fetch_data.Rd +++ b/man/fetch_data.Rd @@ -11,8 +11,8 @@ fetch_data( "spatialDLPFC_Visium_SPG", "spatialDLPFC_snRNAseq", "Visium_SPG_AD_Visium_wholegenome_spe", "Visium_SPG_AD_Visium_targeted_spe", "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results", "Visium_LS_spe", - "Visium_LS_spaceranger", "Visium_LS_ImageJ_out"), + "Visium_SPG_AD_Visium_wholegenome_modeling_results", "visiumStitched_brain_spe", + "visiumStitched_brain_spaceranger", "visiumStitched_brain_ImageJ_out"), destdir = tempdir(), eh = ExperimentHub::ExperimentHub(), bfc = BiocFileCache::BiocFileCache() From f821b3d148513640705309fcd1f8291f4c26a108 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 19 Jul 2024 11:35:19 -0400 Subject: [PATCH 187/259] Also fix the ExperimentHub tabs for visiumStitched_brain data --- R/fetch_data.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index 06e17e09..c9d23894 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -262,7 +262,7 @@ fetch_data <- url <- "https://www.dropbox.com/s/5plupu8bj5m0kfh/Visium_IF_AD_modeling_results.Rdata?dl=1" } else if (type == "Visium_LS_spe") { - tag <- "VisiumLS_Visium_stitched_spatialLIBD" + tag <- "visiumStitched_brain_spatialLIBD" hub_title <- type ## While EH is not set-up @@ -270,7 +270,7 @@ fetch_data <- url <- "https://www.dropbox.com/scl/fi/9re464y6qaojx3r94nq5u/visiumStitched_brain_spe.rds?rlkey=nq6a82u23xuu9hohr86oodwdi&dl=1" } else if (type == "visiumStitched_brain_spaceranger") { - tag <- "VisiumLS_Visium_stitched_spatialLIBD" + tag <- "visiumStitched_brain_spatialLIBD" hub_title <- type ## While EH is not set-up @@ -278,7 +278,7 @@ fetch_data <- url <- "https://www.dropbox.com/scl/fi/5jdoaukvhq3v7lk19228y/visiumStitched_brain_spaceranger.zip?rlkey=bdgjc6mgy1ierdad6h6v5g29c&dl=1" } else if (type == "visiumStitched_brain_ImageJ_out") { - tag <- "VisiumLS_Visium_stitched_spatialLIBD" + tag <- "visiumStitched_brain_spatialLIBD" hub_title <- type ## While EH is not set-up From 0aa362933797fdbd3f715d1f640fca55e19cbc86 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 19 Jul 2024 11:36:10 -0400 Subject: [PATCH 188/259] Missed this one! Good eye @nick-eagles! Co-authored-by: Nick Eagles --- R/fetch_data.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index c9d23894..5af8a3c6 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -261,7 +261,7 @@ fetch_data <- file_name <- "Visium_IF_AD_modeling_results.Rdata" url <- "https://www.dropbox.com/s/5plupu8bj5m0kfh/Visium_IF_AD_modeling_results.Rdata?dl=1" - } else if (type == "Visium_LS_spe") { + } else if (type == "visiumStitched_brain_spe") { tag <- "visiumStitched_brain_spatialLIBD" hub_title <- type From 723cc26af4dcc68475ce6021529ad086856d122f Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 19 Jul 2024 14:42:22 -0400 Subject: [PATCH 189/259] v1.17.7 -- bump version after recent fixes to the visiumStitched_brain data + other pkgdown-related changes --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 625e18e3..231688ee 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.6 -Date: 2024-07-12 +Version: 1.17.7 +Date: 2024-07-19 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From 3a3b96b6fd8f64d59ec862460539893f5a044e58 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 23 Jul 2024 11:44:57 -0400 Subject: [PATCH 190/259] ImageJ -> Fiji updates related to https://github.com/LieberInstitute/visiumStitched/issues/1 --- R/fetch_data.R | 8 ++++---- inst/extdata/metadata_visiumStitched_brain.csv | 2 +- inst/scripts/make-metadata_visiumStitched_brain.R | 6 +++--- man/fetch_data.Rd | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/R/fetch_data.R b/R/fetch_data.R index 5af8a3c6..334c553a 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -102,7 +102,7 @@ fetch_data <- "Visium_SPG_AD_Visium_wholegenome_modeling_results", "visiumStitched_brain_spe", "visiumStitched_brain_spaceranger", - "visiumStitched_brain_ImageJ_out" + "visiumStitched_brain_Fiji_out" ), destdir = tempdir(), eh = ExperimentHub::ExperimentHub(), @@ -277,14 +277,14 @@ fetch_data <- file_name <- "visiumStitched_brain_spaceranger.zip" url <- "https://www.dropbox.com/scl/fi/5jdoaukvhq3v7lk19228y/visiumStitched_brain_spaceranger.zip?rlkey=bdgjc6mgy1ierdad6h6v5g29c&dl=1" - } else if (type == "visiumStitched_brain_ImageJ_out") { + } else if (type == "visiumStitched_brain_Fiji_out") { tag <- "visiumStitched_brain_spatialLIBD" hub_title <- type ## While EH is not set-up - file_name <- "visiumStitched_brain_imagej_out.zip" + file_name <- "visiumStitched_brain_fiji_out.zip" url <- - "https://www.dropbox.com/scl/fi/bevo52e96f2kdwllf8dkk/visiumStitched_brain_imagej_out.zip?rlkey=ptwal8f5zxakzejwd0oqw0lhj&dl=1" + "https://www.dropbox.com/scl/fi/bevo52e96f2kdwllf8dkk/visiumStitched_brain_fiji_out.zip?rlkey=ptwal8f5zxakzejwd0oqw0lhj&dl=1" } file_path <- file.path(destdir, file_name) diff --git a/inst/extdata/metadata_visiumStitched_brain.csv b/inst/extdata/metadata_visiumStitched_brain.csv index 64af76ef..b2f440fa 100644 --- a/inst/extdata/metadata_visiumStitched_brain.csv +++ b/inst/extdata/metadata_visiumStitched_brain.csv @@ -1,4 +1,4 @@ Title,Description,BiocVersion,Genome,SourceType,SourceUrl,SourceVersion,Species,TaxonomyId,Coordinate_1_based,DataProvider,Maintainer,RDataClass,DispatchClass,RDataPath,Tags visiumStitched_brain_spe,SpatialExperiment object at the spot-level for the spatially stitched human brain spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.,3.19,GRCh38,GTF,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,SpatialExperiment,Rds,spatialLIBD/spatialLIBD_files/visiumStitched_brain_spe.rds,visiumStitched_brain_spatialLIBD visiumStitched_brain_spaceranger,Spaceranger outputs for the spatially stitched human brain (spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/visiumStitched_brain_spaceranger.zip,visiumStitched_brain_spatialLIBD -visiumStitched_brain_ImageJ_out,Stitched PNG image and XML file from aligning human brain spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/visiumStitched_brain_imagej_out.zip,visiumStitched_brain_spatialLIBD +visiumStitched_brain_Fiji_out,Stitched PNG image and XML file from aligning human brain spatial transcriptomics data (n = 3) in Fiji. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package.,3.19,GRCh38,Zip,https://bioconductor.org/packages/spatialLIBD,June 11 2024,Homo sapiens,9606,TRUE,LIBD,Leonardo Collado-Torres ,list,Zip,spatialLIBD/spatialLIBD_files/visiumStitched_brain_imagej_out.zip,visiumStitched_brain_spatialLIBD diff --git a/inst/scripts/make-metadata_visiumStitched_brain.R b/inst/scripts/make-metadata_visiumStitched_brain.R index 0f18ef34..249ef1ac 100644 --- a/inst/scripts/make-metadata_visiumStitched_brain.R +++ b/inst/scripts/make-metadata_visiumStitched_brain.R @@ -6,11 +6,11 @@ outdir <- "spatialLIBD_files" pkgname <- "spatialLIBD" meta <- tibble( - Title = c("visiumStitched_brain_spe", "visiumStitched_brain_spaceranger", "visiumStitched_brain_ImageJ_out"), + Title = c("visiumStitched_brain_spe", "visiumStitched_brain_spaceranger", "visiumStitched_brain_Fiji_out"), Description = c( "SpatialExperiment object at the spot-level for the spatially stitched human brain spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package.", "Spaceranger outputs for the spatially stitched human brain (spatial transcriptomics data (n = 3) from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and available through the spatialLIBD Bioconductor package. Can be used with visiumStitched::build_spe() to construct a SpatialExperiment.", - "Stitched PNG image and XML file from aligning human brain spatial transcriptomics data (n = 3) in ImageJ. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package." + "Stitched PNG image and XML file from aligning human brain spatial transcriptomics data (n = 3) in Fiji. Data to align was from the Visium platform from 10x Genomics generated by the Lieber Institute for Brain Development (LIBD) and is available through the spatialLIBD Bioconductor package." ), BiocVersion = "3.19", Genome = "GRCh38", @@ -29,7 +29,7 @@ meta <- tibble( outdir, c( "visiumStitched_brain_spe.rds", "visiumStitched_brain_spaceranger.zip", - "visiumStitched_brain_imagej_out.zip" + "visiumStitched_brain_fiji_out.zip" ) ), Tags = "visiumStitched_brain_spatialLIBD" diff --git a/man/fetch_data.Rd b/man/fetch_data.Rd index 8a59b913..8f40a5b7 100644 --- a/man/fetch_data.Rd +++ b/man/fetch_data.Rd @@ -12,7 +12,7 @@ fetch_data( "Visium_SPG_AD_Visium_wholegenome_spe", "Visium_SPG_AD_Visium_targeted_spe", "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", "Visium_SPG_AD_Visium_wholegenome_modeling_results", "visiumStitched_brain_spe", - "visiumStitched_brain_spaceranger", "visiumStitched_brain_ImageJ_out"), + "visiumStitched_brain_spaceranger", "visiumStitched_brain_Fiji_out"), destdir = tempdir(), eh = ExperimentHub::ExperimentHub(), bfc = BiocFileCache::BiocFileCache() From fa9c18d2f2dda5e4ebef3838d98354347b327084 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 23 Jul 2024 11:45:44 -0400 Subject: [PATCH 191/259] v1.17.8 -- ImageJ -> Fiji --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 231688ee..42ecb133 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.7 -Date: 2024-07-19 +Version: 1.17.8 +Date: 2024-07-23 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), From ace59fa4120b073bf33318afd99ba2f19120bbfd Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 26 Jul 2024 18:46:35 -0400 Subject: [PATCH 192/259] Fix link to https://support.bioconductor.org/tag/spatialLIBD/ --- R/app_ui.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/app_ui.R b/R/app_ui.R index 3366fdd3..d042db15 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -888,7 +888,7 @@ app_ui <- function() { "Help or feedback", tagList( HTML( - 'Please get in touch with the spatialLIBD authors through the Bioconductor Support Website (using the spatialLIBD tag) or through GitHub. Remember to help others help you by including all the information required to reproduce the problem you noticed. Thank you!' + 'Please get in touch with the spatialLIBD authors through the Bioconductor Support Website (using the spatialLIBD tag) or through GitHub. Remember to help others help you by including all the information required to reproduce the problem you noticed. Thank you!' ), hr(), p("The following information will be useful to them:"), From c82c789d8538fe52e90d33af852a92d23b2368c4 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 26 Jul 2024 19:11:59 -0400 Subject: [PATCH 193/259] Fix bug on the "clusters (interactive)" tab of run_app() for stitched data. I used this code to debug things: ```R library("HDF5Array") spe <- loadHDF5SummarizedExperiment('/Users/leocollado/Dropbox/Code/_libdcode/visiumStitched_brain/code/05_shiny/spe') vars <- colnames(colData(spe)) run_app( spe, sce_layer = NULL, modeling_results = NULL, sig_genes = NULL, title = "visiumStitched_brain", spe_discrete_vars = c( "ManualAnnotation", vars[grep("^precast_k[248]$", vars)], "scran_quick_cluster" ), spe_continuous_vars = c( "sum_umi", "sum_gene", "expr_chrM", "expr_chrM_ratio" ), default_cluster = "precast_k2", docs_path = "/Users/leocollado/Dropbox/Code/_libdcode/visiumStitched_brain/code/05_shiny/www", is_stitched = TRUE ) ``` --- R/app_server.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index ca416d98..c40c1506 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -682,8 +682,7 @@ app_server <- function(input, output, session) { ## Add the reduced dims if (reduced_name != "") { - red_dims <- - reducedDim(spe, reduced_name)[spe$sample_id == sampleid, ] + red_dims <- reducedDim(spe_sub, reduced_name) colnames(red_dims) <- paste(reduced_name, "dim", seq_len(ncol(red_dims))) d <- cbind(d, red_dims) From fbe195273178d7ebac51394cc1be62ddb6d9e13a Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 1 Oct 2024 17:11:07 -0400 Subject: [PATCH 194/259] Improve example formatting. Add test for two groups, only run anova or pairwise if k>2 --- R/registration_wrapper.R | 56 ++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 38a1c297..b134c72b 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -47,7 +47,12 @@ #' ## Compute all modeling results #' example_modeling_results <- registration_wrapper( #' sce, -#' "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" +#' var_regustration ="Cell_Cycle", +#' var_sample_id ="sample_id", +#' covars = c("age"), +#' gene_ensembl = "ensembl", +#' gene_name = "gene_name", +#' suffix = "wrapper" #' ) registration_wrapper <- function(sce, @@ -76,6 +81,12 @@ registration_wrapper <- block_cor <- registration_block_cor(sce_pseudo, registration_model = registration_mod) + + ## test if registration var has two groups + registration_var_k2 <- length(grep("^registration_variable", colnames(registration_mod))) == 2 + if (registration_var_k2) { + warning("You need 'var_registration' to have at least 3 different values to compute an F-statistic, returning Enrichment statistics only", call. = FALSE) + } results_enrichment <- registration_stats_enrichment( @@ -85,29 +96,40 @@ registration_wrapper <- gene_ensembl = gene_ensembl, gene_name = gene_name ) - results_pairwise <- + + ## with more than 2 groups run ANOVA and pairwise data + if(!registration_var_k2){ + results_pairwise <- registration_stats_pairwise( - sce_pseudo, - registration_model = registration_mod, - block_cor = block_cor, - gene_ensembl = gene_ensembl, - gene_name = gene_name + sce_pseudo, + registration_model = registration_mod, + block_cor = block_cor, + gene_ensembl = gene_ensembl, + gene_name = gene_name ) - results_anova <- + results_anova <- registration_stats_anova( - sce_pseudo, - block_cor = block_cor, - covars = covars, - gene_ensembl = gene_ensembl, - gene_name = gene_name, - suffix = suffix + sce_pseudo, + block_cor = block_cor, + covars = covars, + gene_ensembl = gene_ensembl, + gene_name = gene_name, + suffix = suffix ) - - modeling_results <- list( + + modeling_results <- list( "anova" = results_anova, "enrichment" = results_enrichment, "pairwise" = results_pairwise - ) + ) + } else { + modeling_results <- list( + "anova" = NULL, + "enrichment" = results_enrichment, + "pairwise" = NULL + ) + } + return(modeling_results) } From f9882e6a2c33ae6154d60ff11b40a4889dc00882 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 1 Oct 2024 17:11:21 -0400 Subject: [PATCH 195/259] Update docs --- man/registration_wrapper.Rd | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/man/registration_wrapper.Rd b/man/registration_wrapper.Rd index 92b38b4b..2fc3f852 100644 --- a/man/registration_wrapper.Rd +++ b/man/registration_wrapper.Rd @@ -92,7 +92,12 @@ rowData(sce)$gene_name <- paste0("gene", seq_len(nrow(sce))) ## Compute all modeling results example_modeling_results <- registration_wrapper( sce, - "Cell_Cycle", "sample_id", c("age"), "ensembl", "gene_name", "wrapper" + var_regustration ="Cell_Cycle", + var_sample_id ="sample_id", + covars = c("age"), + gene_ensembl = "ensembl", + gene_name = "gene_name", + suffix = "wrapper" ) } \seealso{ From ae8fb4a8ee37fbe7516d9d84ba91c78fddd0cf7b Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 1 Oct 2024 17:30:48 -0400 Subject: [PATCH 196/259] Add a test to expect warning for k=2 registration --- tests/testthat/test-registration_wrapper.R | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/testthat/test-registration_wrapper.R diff --git a/tests/testthat/test-registration_wrapper.R b/tests/testthat/test-registration_wrapper.R new file mode 100644 index 00000000..1fc1b983 --- /dev/null +++ b/tests/testthat/test-registration_wrapper.R @@ -0,0 +1,35 @@ +## Ensure reproducibility of example data +set.seed(20220907) + +## Generate example data +sce <- scuttle::mockSCE() + +## Add some sample IDs +sce$sample_id <- sample(LETTERS[1:5], ncol(sce), replace = TRUE) + +## Add a sample-level covariate: age +ages <- rnorm(5, mean = 20, sd = 4) +names(ages) <- LETTERS[1:5] +sce$age <- ages[sce$sample_id] + +## add variable with one group +sce$batch <- "batch1" + +## Add gene-level information +rowData(sce)$ensembl <- paste0("ENSG", seq_len(nrow(sce))) +rowData(sce)$gene_name <- paste0("gene", seq_len(nrow(sce))) + + +test_that("warning for k=2 variable", + example_modeling_results <- expect_warning( + registration_wrapper( + sce, + var_registration ="Treatment", + var_sample_id ="sample_id", + covars = c("age"), + gene_ensembl = "ensembl", + gene_name = "gene_name", + suffix = "wrapper" + ) + ) +) From ed85b269d8f5ed6822ef0d3274b3ec104f637456 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 11 Oct 2024 11:14:14 -0400 Subject: [PATCH 197/259] Support finding the reference GTF properly even for spaceranger versions > 3.0.0 Co-authored-by: Manisha Barse --- R/read10xVisiumWrapper.R | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index d9f31fc2..430943e9 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -60,7 +60,18 @@ read10xVisiumWrapper <- function( if (missing(reference_gtf)) { summary_file <- file.path(samples[1], "web_summary.html") web <- readLines(summary_file) + + # For spaceranger versions before 3.0 reference_path <- gsub('.*"', "", regmatches(web, regexpr('\\["Reference Path", *"[/|A-z|0-9|-]+', web))) + + # For recent spaceranger versions (3.0.0+?) + if (length(reference_path) == 0) { + reference_path = sub( + '.*--transcriptome=(\\S*).*', + '\\1', + web[grep('--transcriptome=', web)] + ) + } reference_gtf <- file.path(reference_path, "genes", "genes.gtf") } reference_gtf <- reference_gtf[file.exists(reference_gtf)] From e2001c6eb49f1c89b472b40e9ae4f3398931ed93 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Fri, 11 Oct 2024 13:18:00 -0400 Subject: [PATCH 198/259] Support automatically importing gzip'd GTF files, which occur in the recent annotation files (e.g. 2024) --- R/read10xVisiumWrapper.R | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 430943e9..6bf42111 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -72,7 +72,10 @@ read10xVisiumWrapper <- function( web[grep('--transcriptome=', web)] ) } - reference_gtf <- file.path(reference_path, "genes", "genes.gtf") + reference_gtf <- list.files( + file.path(reference_path, "genes"), "^genes\\.gtf(\\.gz)?$", + full.names = TRUE + ) } reference_gtf <- reference_gtf[file.exists(reference_gtf)] if (length(reference_gtf) > 1) { From 97dffb7f99d394b4d449990ea0c6ffb2821b47d4 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 22 Oct 2024 08:55:29 -0400 Subject: [PATCH 199/259] v1.17.9 -- document #88 by @nick-eagles --- DESCRIPTION | 4 ++-- NEWS.md | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 42ecb133..e46b1e30 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.8 -Date: 2024-07-23 +Version: 1.17.9 +Date: 2024-10-22 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 0d9e48e1..4e451672 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.17.9 + +BUG FIXES + +* `read10xVisiumWrapper()` is now able to detect the GTF file used by +`SpaceRanger` for version 3.0.0+. Implemented by @nick-eagles at +. + + # spatialLIBD 1.17.6 BUG FIXES From f2ccc25e9523691fc25f2a71288e5e35a3be3c32 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 22 Oct 2024 09:05:01 -0400 Subject: [PATCH 200/259] Fix typo on example for registration_wrapper(). Add a bit more about how to explore the results. Actually with k = 2 we can run the pairwise model, so I've re-enabled that. Updating the warning for k = 2 accordingly. Used RStudio's automatic code formatter + styler's addin for styling the active file. Re-ran devtools::document(). Related to #86. --- R/registration_wrapper.R | 80 ++++++++++++---------- man/registration_wrapper.Rd | 14 ++-- tests/testthat/test-registration_wrapper.R | 25 +++---- 3 files changed, 66 insertions(+), 53 deletions(-) diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index b134c72b..910b929d 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -47,13 +47,19 @@ #' ## Compute all modeling results #' example_modeling_results <- registration_wrapper( #' sce, -#' var_regustration ="Cell_Cycle", -#' var_sample_id ="sample_id", +#' var_registration = "Cell_Cycle", +#' var_sample_id = "sample_id", #' covars = c("age"), -#' gene_ensembl = "ensembl", -#' gene_name = "gene_name", +#' gene_ensembl = "ensembl", +#' gene_name = "gene_name", #' suffix = "wrapper" #' ) +#' +#' ## Explore the results from registration_wrapper() +#' class(example_modeling_results) +#' length(example_modeling_results) +#' names(example_modeling_results) +#' lapply(example_modeling_results, head) registration_wrapper <- function(sce, var_registration, @@ -69,7 +75,8 @@ registration_wrapper <- ## Pseudobulk sce_pseudo <- - registration_pseudobulk(sce, + registration_pseudobulk( + sce, var_registration = var_registration, var_sample_id = var_sample_id, min_ncells = min_ncells, @@ -81,11 +88,14 @@ registration_wrapper <- block_cor <- registration_block_cor(sce_pseudo, registration_model = registration_mod) - + ## test if registration var has two groups registration_var_k2 <- length(grep("^registration_variable", colnames(registration_mod))) == 2 if (registration_var_k2) { - warning("You need 'var_registration' to have at least 3 different values to compute an F-statistic, returning Enrichment statistics only", call. = FALSE) + warning( + "You need 'var_registration' to have at least 3 unique values to compute an F-statistic and thus ANOVA modeling results cannot be computed.", + call. = FALSE + ) } results_enrichment <- @@ -96,40 +106,36 @@ registration_wrapper <- gene_ensembl = gene_ensembl, gene_name = gene_name ) - - ## with more than 2 groups run ANOVA and pairwise data - if(!registration_var_k2){ - results_pairwise <- + + results_pairwise <- registration_stats_pairwise( - sce_pseudo, - registration_model = registration_mod, - block_cor = block_cor, - gene_ensembl = gene_ensembl, - gene_name = gene_name - ) - results_anova <- - registration_stats_anova( - sce_pseudo, - block_cor = block_cor, - covars = covars, - gene_ensembl = gene_ensembl, - gene_name = gene_name, - suffix = suffix + sce_pseudo, + registration_model = registration_mod, + block_cor = block_cor, + gene_ensembl = gene_ensembl, + gene_name = gene_name ) - - modeling_results <- list( - "anova" = results_anova, - "enrichment" = results_enrichment, - "pairwise" = results_pairwise - ) + + ## with more than 2 groups run ANOVA model + if (!registration_var_k2) { + results_anova <- + registration_stats_anova( + sce_pseudo, + block_cor = block_cor, + covars = covars, + gene_ensembl = gene_ensembl, + gene_name = gene_name, + suffix = suffix + ) } else { - modeling_results <- list( - "anova" = NULL, - "enrichment" = results_enrichment, - "pairwise" = NULL - ) + results_anova <- NULL } - + ## Bundle results together + modeling_results <- list( + "anova" = NULL, + "enrichment" = results_enrichment, + "pairwise" = results_pairwise + ) return(modeling_results) } diff --git a/man/registration_wrapper.Rd b/man/registration_wrapper.Rd index 2fc3f852..76a2da32 100644 --- a/man/registration_wrapper.Rd +++ b/man/registration_wrapper.Rd @@ -92,13 +92,19 @@ rowData(sce)$gene_name <- paste0("gene", seq_len(nrow(sce))) ## Compute all modeling results example_modeling_results <- registration_wrapper( sce, - var_regustration ="Cell_Cycle", - var_sample_id ="sample_id", + var_registration = "Cell_Cycle", + var_sample_id = "sample_id", covars = c("age"), - gene_ensembl = "ensembl", - gene_name = "gene_name", + gene_ensembl = "ensembl", + gene_name = "gene_name", suffix = "wrapper" ) + +## Explore the results from registration_wrapper() +class(example_modeling_results) +length(example_modeling_results) +names(example_modeling_results) +lapply(example_modeling_results, head) } \seealso{ Other spatial registration and statistical modeling functions: diff --git a/tests/testthat/test-registration_wrapper.R b/tests/testthat/test-registration_wrapper.R index 1fc1b983..b7deec09 100644 --- a/tests/testthat/test-registration_wrapper.R +++ b/tests/testthat/test-registration_wrapper.R @@ -20,16 +20,17 @@ rowData(sce)$ensembl <- paste0("ENSG", seq_len(nrow(sce))) rowData(sce)$gene_name <- paste0("gene", seq_len(nrow(sce))) -test_that("warning for k=2 variable", - example_modeling_results <- expect_warning( - registration_wrapper( - sce, - var_registration ="Treatment", - var_sample_id ="sample_id", - covars = c("age"), - gene_ensembl = "ensembl", - gene_name = "gene_name", - suffix = "wrapper" - ) - ) +test_that( + "warning for k=2 variable", + example_modeling_results <- expect_warning( + registration_wrapper( + sce, + var_registration = "Treatment", + var_sample_id = "sample_id", + covars = c("age"), + gene_ensembl = "ensembl", + gene_name = "gene_name", + suffix = "wrapper" + ) + ) ) From 05e78863bbfae5addee2c80aca5a39c091d39145 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 22 Oct 2024 09:06:47 -0400 Subject: [PATCH 201/259] v1.17.10 -- document #86 by @lahuuki. Also made some changes to the PR. --- DESCRIPTION | 2 +- NEWS.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index e46b1e30..a95b2b05 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.9 +Version: 1.17.10 Date: 2024-10-22 Authors@R: c( diff --git a/NEWS.md b/NEWS.md index 4e451672..3492a2e5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.17.10 + +BUG FIXES + +* `registration_wrapper()` now automatically handles the scenario where `k = 2` +by not using `registration_stats_anova()` and providing an apporpriate warning. +Implemented by @lahuuki at +. + # spatialLIBD 1.17.9 BUG FIXES From eed7543cd644cac85110b163922c1137e9a42e27 Mon Sep 17 00:00:00 2001 From: lshep Date: Tue, 29 Oct 2024 09:51:06 -0400 Subject: [PATCH 202/259] bump x.y.z version to even y prior to creation of RELEASE_3_20 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index a95b2b05..cca1feef 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.17.10 +Version: 1.18.0 Date: 2024-10-22 Authors@R: c( From 069922130925b263224d5ce17f9efe92d92a130f Mon Sep 17 00:00:00 2001 From: lshep Date: Tue, 29 Oct 2024 09:51:06 -0400 Subject: [PATCH 203/259] bump x.y.z version to odd y following creation of RELEASE_3_20 branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index cca1feef..daf193e2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.18.0 +Version: 1.19.0 Date: 2024-10-22 Authors@R: c( From 544386d54ba20f85e6fe595abdd1525951616387 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 31 Oct 2024 14:02:21 -0400 Subject: [PATCH 204/259] Add textual output that catches warnings during plotting (e.g. from vis_gene() when plotting multiple genes, some of which have no expression variation). Currently works just for the Gene (static) tab. Addresses part of #83 --- R/app_server.R | 79 ++++++++++++++++++++++++++++++-------------------- R/app_ui.R | 3 +- 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index c40c1506..318ecec8 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -224,37 +224,44 @@ app_server <- function(input, output, session) { }) static_gene <- reactive({ - p <- vis_gene( - spe, - sampleid = input$sample, - geneid = input$geneid, - multi_gene_method = input$multi_gene_method, - assayname = input$assayname, - minCount = input$minCount, - cont_colors = cont_colors(), - image_id = input$imageid, - alpha = input$alphalevel, - point_size = input$pointsize, - auto_crop = input$auto_crop, - is_stitched = is_stitched - ) - if (!input$side_by_side_gene) { - return(p) - } else { - p_no_spots <- p - p_no_spots$layers[[2]] <- NULL - - p_no_spatial <- p - p_no_spatial$layers[[1]] <- NULL - cowplot::plot_grid( - plotlist = list( - p_no_spots, - p_no_spatial + ggplot2::theme(legend.position = "none") - ), - nrow = 1, - ncol = 2 + gene_warnings = NULL + withCallingHandlers({ + p <- vis_gene( + spe, + sampleid = input$sample, + geneid = input$geneid, + multi_gene_method = input$multi_gene_method, + assayname = input$assayname, + minCount = input$minCount, + cont_colors = cont_colors(), + image_id = input$imageid, + alpha = input$alphalevel, + point_size = input$pointsize, + auto_crop = input$auto_crop, + is_stitched = is_stitched ) - } + if (!input$side_by_side_gene) { + p_result = p + } else { + p_no_spots <- p + p_no_spots$layers[[2]] <- NULL + + p_no_spatial <- p + p_no_spatial$layers[[1]] <- NULL + p_result = cowplot::plot_grid( + plotlist = list( + p_no_spots, + p_no_spatial + ggplot2::theme(legend.position = "none") + ), + nrow = 1, + ncol = 2 + ) + } + }, warning = function(w) { + gene_warnings <<- c(gene_warnings, conditionMessage(w)) + invokeRestart("muffleWarning") + }) + return(list(p = p_result, gene_warnings = gene_warnings)) }) static_gene_grid <- reactive({ @@ -530,10 +537,9 @@ app_server <- function(input, output, session) { height = "auto" ) - output$gene <- renderPlot( { - static_gene() + static_gene()[['p']] }, width = function() { 600 * ifelse(input$side_by_side_gene, 2, 1) @@ -541,6 +547,15 @@ app_server <- function(input, output, session) { height = 600 ) + output$gene_warnings <- renderText({ + these_warnings = static_gene()[['gene_warnings']] + if (!is.null(these_warnings)) { + paste("Warnings:", paste(these_warnings, collapse = "; ")) + } else { + "" + } + }) + output$gene_grid_static <- renderUI({ input$gene_grid_update diff --git a/R/app_ui.R b/R/app_ui.R index d042db15..4e92425a 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -352,7 +352,8 @@ app_ui <- function() { tags$br(), tags$br(), tags$br(), - tags$br() + tags$br(), + textOutput("gene_warnings") ), tabPanel( "Gene (interactive)", From 6d3ba572f62f290e542e9a0f202edfc6b2d1523a Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 31 Oct 2024 14:12:14 -0400 Subject: [PATCH 205/259] Don't throw an error in the Z-score calculation when just one feature has variation. Update tests accordingly. Partially addresses #83 --- R/multi_gene_z_score.R | 6 +++--- tests/testthat/test-multi_gene_z_score.R | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/R/multi_gene_z_score.R b/R/multi_gene_z_score.R index 3c6f3c1a..abfdfff2 100644 --- a/R/multi_gene_z_score.R +++ b/R/multi_gene_z_score.R @@ -14,11 +14,11 @@ #' @family functions for summarizing expression of multiple continuous variables simultaneously #' @keywords internal multi_gene_z_score <- function(cont_mat) { - # Z-score calculation requires at least 2 features with nonzero variance. + # Z-score calculation requires at least 1 feature with nonzero variance. # Verify this and drop any zero-variance features good_indices <- which(colSds(cont_mat, na.rm = TRUE) != 0) - if (length(good_indices) < 2) { - stop("After dropping features with no expression variation, less than 2 features were left. This error can occur when using data from only 1 spot.", call. = FALSE) + if (length(good_indices) < 1) { + stop("After dropping features with no expression variation, no features were left. This error can occur when using data from only 1 spot.", call. = FALSE) } if (ncol(cont_mat) - length(good_indices) > 0) { warning( diff --git a/tests/testthat/test-multi_gene_z_score.R b/tests/testthat/test-multi_gene_z_score.R index cd701abb..f78af3f1 100644 --- a/tests/testthat/test-multi_gene_z_score.R +++ b/tests/testthat/test-multi_gene_z_score.R @@ -11,17 +11,32 @@ test_that( ) # NAs should be correctly removed from columns (as long as 2 non-NAs remain - # in at least 2 columns), and the result should have no NAs + # in at least 1 column), and the result should have no NAs cont_mat <- matrix(c(1, NA, 3, NA, 2, 0), ncol = 2) colnames(cont_mat) <- c("good1", "good2") expect_equal(any(is.na(multi_gene_z_score(cont_mat))), FALSE) - # With only one good column, an error should be thrown + # With only one good column, the result should simply be the + # Z-score-normalized good column. A warning should indicate which + # columns were dropped cont_mat <- matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) colnames(cont_mat) <- c("bad1", "good", "bad2") + + temp = c(3, 4) + expected_result = (temp - mean(temp)) / sd(temp) + + expect_warning( + { actual_result = multi_gene_z_score(cont_mat) }, + "Dropping features\\(s\\) 'bad1', 'bad2' which have no expression variation" + ) + expect_equal(actual_result, expected_result) + + # An error should be thrown if no columns have variation + cont_mat <- matrix(c(1, 1, 0, 0, 2, 2), ncol = 3) + colnames(cont_mat) <- c("bad1", "bad2", "bad3") expect_error( multi_gene_z_score(cont_mat), - "After dropping features with no expression variation, less than 2 features were left" + "^After dropping features with no expression variation" ) } ) From c432854653b9d215bfa32caa481299a210992703 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 31 Oct 2024 14:55:18 -0400 Subject: [PATCH 206/259] Fix duplicate error messages in Gene (static) --- R/app_server.R | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/R/app_server.R b/R/app_server.R index 318ecec8..6dd46c1f 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -548,7 +548,14 @@ app_server <- function(input, output, session) { ) output$gene_warnings <- renderText({ - these_warnings = static_gene()[['gene_warnings']] + # Since 'static_gene()' is invoked twice (once also in the assignment + # of 'output$gene'), we silence any errors that occur in this second + # invocation to not duplicate error messages + these_warnings = NULL + temp = try( + { these_warnings = static_gene()[['gene_warnings']] }, silent = TRUE + ) + if (!is.null(these_warnings)) { paste("Warnings:", paste(these_warnings, collapse = "; ")) } else { From a2b9662094e24077e1d8b604aa7b9fc201492c2c Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 31 Oct 2024 15:25:53 -0400 Subject: [PATCH 207/259] Also catch and display warnings from vis_grid_gene() when it occurs in the Gene grid (static). Part of #83 --- R/app_server.R | 66 +++++++++++++++++++++++++++++++++++--------------- R/app_ui.R | 1 + 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 6dd46c1f..03e68ae6 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -267,28 +267,37 @@ app_server <- function(input, output, session) { static_gene_grid <- reactive({ input$gene_grid_update - plots <- - vis_grid_gene( - spe, - geneid = isolate(input$geneid), - multi_gene_method = input$multi_gene_method, - assayname = isolate(input$assayname), - minCount = isolate(input$minCount), - return_plots = TRUE, - spatial = isolate(input$grid_spatial_gene), - cont_colors = isolate(cont_colors()), - image_id = isolate(input$imageid), - alpha = isolate(input$alphalevel), - point_size = isolate(input$pointsize), - sample_order = isolate(input$gene_grid_samples), - auto_crop = isolate(input$auto_crop), - is_stitched = is_stitched - ) - cowplot::plot_grid( + gene_grid_warnings = NULL + withCallingHandlers({ + plots <- + vis_grid_gene( + spe, + geneid = isolate(input$geneid), + multi_gene_method = input$multi_gene_method, + assayname = isolate(input$assayname), + minCount = isolate(input$minCount), + return_plots = TRUE, + spatial = isolate(input$grid_spatial_gene), + cont_colors = isolate(cont_colors()), + image_id = isolate(input$imageid), + alpha = isolate(input$alphalevel), + point_size = isolate(input$pointsize), + sample_order = isolate(input$gene_grid_samples), + auto_crop = isolate(input$auto_crop), + is_stitched = is_stitched + ) + }, warning = function(w) { + gene_grid_warnings <<- c(gene_grid_warnings, conditionMessage(w)) + invokeRestart("muffleWarning") + }) + + p_result = cowplot::plot_grid( plotlist = plots, nrow = isolate(input$gene_grid_nrow), ncol = isolate(input$gene_grid_ncol) ) + + return(list(p = p_result, gene_grid_warnings = gene_grid_warnings)) }) editImg_manipulations <- reactive({ @@ -474,7 +483,7 @@ app_server <- function(input, output, session) { height = 8 * isolate(input$gene_grid_nrow), width = 8 * isolate(input$gene_grid_ncol) ) - print(static_gene_grid()) + print(static_gene_grid()['p']) dev.off() } ) @@ -576,12 +585,29 @@ app_server <- function(input, output, session) { output$gene_grid <- renderPlot( { - print(static_gene_grid()) + print(static_gene_grid()[['p']]) }, width = "auto", height = "auto" ) + output$gene_grid_warnings <- renderText({ + # Since 'static_gene_grid()' is invoked twice (once also in the + # assignment of 'output$gene_grid'), we silence any errors that occur + # in this second invocation to not duplicate error messages + these_warnings = NULL + temp = try( + { these_warnings = static_gene_grid()[['gene_grid_warnings']] }, + silent = TRUE + ) + + if (!is.null(these_warnings)) { + paste("Warnings:", paste(these_warnings, collapse = "; ")) + } else { + "" + } + }) + output$editImg_plot <- renderPlot( { plot(editImg_manipulations()) diff --git a/R/app_ui.R b/R/app_ui.R index 4e92425a..208a2352 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -423,6 +423,7 @@ app_ui <- function() { actionButton("gene_grid_update", label = "Update grid plot"), downloadButton("downloadPlotGeneGrid", "Download PDF"), uiOutput("gene_grid_static"), + textOutput("gene_grid_warnings"), helpText("Click the 'upgrade grid plot' button above to re-make this plot."), tags$br(), tags$br(), From a87428b7675532ed6e38baba05be500b943389a8 Mon Sep 17 00:00:00 2001 From: Nick-Eagles Date: Thu, 31 Oct 2024 15:33:41 -0400 Subject: [PATCH 208/259] Only output one warning in Gene (static); fix returning of plots when downloading from the app. Closes #83 --- R/app_server.R | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 03e68ae6..ff5f7f64 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -224,7 +224,7 @@ app_server <- function(input, output, session) { }) static_gene <- reactive({ - gene_warnings = NULL + gene_warning = NULL withCallingHandlers({ p <- vis_gene( spe, @@ -258,10 +258,10 @@ app_server <- function(input, output, session) { ) } }, warning = function(w) { - gene_warnings <<- c(gene_warnings, conditionMessage(w)) + gene_warning <<- conditionMessage(w) invokeRestart("muffleWarning") }) - return(list(p = p_result, gene_warnings = gene_warnings)) + return(list(p = p_result, gene_warning = gene_warning)) }) static_gene_grid <- reactive({ @@ -455,7 +455,7 @@ app_server <- function(input, output, session) { height = 8, width = 8 * ifelse(input$side_by_side_gene, 2, 1) ) - print(static_gene()) + print(static_gene()[['p']]) dev.off() } ) @@ -483,7 +483,7 @@ app_server <- function(input, output, session) { height = 8 * isolate(input$gene_grid_nrow), width = 8 * isolate(input$gene_grid_ncol) ) - print(static_gene_grid()['p']) + print(static_gene_grid()[['p']]) dev.off() } ) @@ -560,13 +560,13 @@ app_server <- function(input, output, session) { # Since 'static_gene()' is invoked twice (once also in the assignment # of 'output$gene'), we silence any errors that occur in this second # invocation to not duplicate error messages - these_warnings = NULL + this_warning = NULL temp = try( - { these_warnings = static_gene()[['gene_warnings']] }, silent = TRUE + { this_warning = static_gene()[['gene_warning']] }, silent = TRUE ) - if (!is.null(these_warnings)) { - paste("Warnings:", paste(these_warnings, collapse = "; ")) + if (!is.null(this_warning)) { + paste("Warning:", this_warning) } else { "" } From 120803f3096126a65537f1d20ebfa7c864d17bc3 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 10 Dec 2024 15:05:17 -0500 Subject: [PATCH 209/259] Fix GHA badge --- README.Rmd | 2 +- README.md | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.Rmd b/README.Rmd index 573bd17d..2f3b9a1a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -24,7 +24,7 @@ knitr::opts_chunk$set( [![Bioc last commit](https://bioconductor.org/shields/lastcommit/devel/data-experiment/spatialLIBD.svg)](http://bioconductor.org/checkResults/devel/data-experiment-LATEST/spatialLIBD/) [![Bioc dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD.svg)](https://bioconductor.org/packages/release/data-experiment/html/spatialLIBD.html#since) [![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) -[![R build status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) +[![R-CMD-check-bioc](https://github.com/LieberInstitute/spatialLIBD/actions/workflows/check-bioc.yml/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions/workflows/check-bioc.yml) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) [![GitHub pulls](https://img.shields.io/github/issues-pr/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/pulls) [![DOI](https://zenodo.org/badge/225913568.svg)](https://zenodo.org/badge/latestdoi/225913568) diff --git a/README.md b/README.md index c4c49cd2..6f02d134 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,7 @@ commit](https://bioconductor.org/shields/lastcommit/devel/data-experiment/spatia dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD.svg)](https://bioconductor.org/packages/release/data-experiment/html/spatialLIBD.html#since) [![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) -[![R build -status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) +[![R-CMD-check-bioc](https://github.com/LieberInstitute/spatialLIBD/actions/workflows/check-bioc.yml/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions/workflows/check-bioc.yml) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) [![GitHub From af72cbed52176d8543af779d69246ae2f24e8c8d Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 10 Dec 2024 15:46:01 -0500 Subject: [PATCH 210/259] Improve title for layer_stat_cor_plot --- R/layer_stat_cor_plot.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 0d2653b8..a293fb66 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -1,4 +1,4 @@ -#' Visualize the layer modeling correlation of statistics +#' Visualize the correlation of layer modeling t-statistics #' #' This function makes a heatmap from the [layer_stat_cor()] correlation matrix #' between a given set of cell cluster/type statistics derived from scRNA-seq From b4f815b985d14aa99dbf83a5c0ecb21691690a03 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 10 Dec 2024 16:38:13 -0500 Subject: [PATCH 211/259] Fix GHA badge --- inst/app/www/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/app/www/README.md b/inst/app/www/README.md index 8c3e846b..65d68c96 100644 --- a/inst/app/www/README.md +++ b/inst/app/www/README.md @@ -22,7 +22,7 @@ dependencies](https://bioconductor.org/shields/dependencies/release/spatialLIBD. [![Codecov test coverage](https://codecov.io/gh/LieberInstitute/spatialLIBD/branch/devel/graph/badge.svg)](https://codecov.io/gh/LieberInstitute/spatialLIBD?branch=devel) [![R build -status](https://github.com/LieberInstitute/spatialLIBD/workflows/R-CMD-check-bioc/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions) +status](https://github.com/LieberInstitute/spatialLIBD/actions/workflows/check-bioc.yml/badge.svg)](https://github.com/LieberInstitute/spatialLIBD/actions/workflows/check-bioc.yml) [![GitHub issues](https://img.shields.io/github/issues/LieberInstitute/spatialLIBD)](https://github.com/LieberInstitute/spatialLIBD/issues) [![GitHub From 4359ed639f750f001ccc1b738cab0c9a96d63207 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Tue, 10 Dec 2024 16:39:02 -0500 Subject: [PATCH 212/259] Update GHA for bioc 3.20 --- .github/workflows/check-bioc.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index 9f88c52b..a9c9df4a 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -52,9 +52,9 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-latest, r: '4.4', bioc: '3.19', cont: "bioconductor/bioconductor_docker:RELEASE_3_19", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } - # - { os: macOS-latest, r: '4.4', bioc: '3.19'} - - { os: windows-latest, r: '4.4', bioc: '3.19'} + - { os: ubuntu-latest, r: '4.4', bioc: '3.20', cont: "bioconductor/bioconductor_docker:RELEASE_3_20", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } + - { os: macOS-latest, r: '4.4', bioc: '3.20'} + - { os: windows-latest, r: '4.4', bioc: '3.20'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent env: @@ -105,16 +105,16 @@ jobs: uses: actions/cache@v3 with: path: ${{ env.R_LIBS_USER }} - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_20-r-4.4-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_20-r-4.4- - name: Cache R packages on Linux if: "!contains(github.event.head_commit.message, '/nocache') && runner.os == 'Linux' " uses: actions/cache@v3 with: path: /home/runner/work/_temp/Library - key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4- + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_20-r-4.4-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-RELEASE_3_20-r-4.4- # - name: Install Linux system dependencies # if: runner.os == 'Linux' @@ -286,7 +286,7 @@ jobs: if: failure() uses: actions/upload-artifact@master with: - name: ${{ runner.os }}-biocversion-RELEASE_3_19-r-4.4-results + name: ${{ runner.os }}-biocversion-RELEASE_3_20-r-4.4-results path: check From 18b1a57079d6570010165bd480678b60f3679160 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 10 Dec 2024 16:54:36 -0500 Subject: [PATCH 213/259] Update docs for layer stat cor plot --- man/layer_stat_cor_plot.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/layer_stat_cor_plot.Rd b/man/layer_stat_cor_plot.Rd index 73496b45..e01991a9 100644 --- a/man/layer_stat_cor_plot.Rd +++ b/man/layer_stat_cor_plot.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/layer_stat_cor_plot.R \name{layer_stat_cor_plot} \alias{layer_stat_cor_plot} -\title{Visualize the layer modeling correlation of statistics} +\title{Visualize the correlation of layer modeling t-statistics} \usage{ layer_stat_cor_plot( cor_stats_layer, From c371907b138892c25acf64fd5270146553877ede Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Tue, 10 Dec 2024 16:58:52 -0500 Subject: [PATCH 214/259] Start adding ComplexHeatmap version of layer_stat_cor_plot, add color vectors as annotations --- NAMESPACE | 1 + R/layer_stat_cor_plot_complex.R | 99 ++++++++++++++++++++++++++++++ man/layer_stat_cor_plot_complex.Rd | 71 +++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 R/layer_stat_cor_plot_complex.R create mode 100644 man/layer_stat_cor_plot_complex.Rd diff --git a/NAMESPACE b/NAMESPACE index 42d8758a..946c57f9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,6 +25,7 @@ export(layer_boxplot) export(layer_matrix_plot) export(layer_stat_cor) export(layer_stat_cor_plot) +export(layer_stat_cor_plot_complex) export(locate_images) export(read10xVisiumAnalysis) export(read10xVisiumWrapper) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R new file mode 100644 index 00000000..f27c7d27 --- /dev/null +++ b/R/layer_stat_cor_plot_complex.R @@ -0,0 +1,99 @@ + + +#' Visualize the correlation of layer modeling t-statistics with ComplexHeatmap +#' @param query_colors named vector of colors for query row annotations +#' @param reference_colors named vector of colors for reference column annotations +#' +#' @inheritParams layer_stat_cor_plot +#' +#' @return ComplexHeatmap plot of t-stat correlations +#' @export +#' +#' @examples +#' ## Obtain the necessary data +#' ## reference human pilot modeling results +#' if (!exists("modeling_results")) { +#' modeling_results <- fetch_data(type = "modeling_results") +#' } +#' +#' ## querey spatailDLPFC modeling +#' query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") +#' +#' ## extract t-statics and rename +#' registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] +#' colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) +#' +#' ## Compute the correlations +#' cor_stats_layer <- layer_stat_cor( +#' stats = registration_t_stats, +#' modeling_results, +#' model_type = "enrichment" +#' ) +#' +#' ## Visualize the correlation matrix +#' +#' ## most basic +#' layer_stat_cor_plot_complex(cor_stats_layer) +#' +#' ## add colors +#' ## add libd_layer_colors to refrence Human Pilot layers +#' layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) +#' +#' ## supply polychrome colors to query clusters +#' cluster_colors <- Polychrome::palette36.colors(nrow(cor_stats_layer)) +#' names(cluster_colors) <- rownames(cor_stats_layer) +#' +#' layer_stat_cor_plot_complex(cor_stats_layer, +#' query_colors = cluster_colors, +#' reference_colors = libd_layer_colors) +#' +#' ## Apply additional ComplexHeatmap param +#' layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE) +#' +layer_stat_cor_plot_complex <- function(cor_stats_layer, + theSeq = seq(min(cor_stats_layer), max(cor_stats_layer), by = 0.01), + my.col = grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)), + query_colors = NULL, + reference_colors = NULL, + ... + ){ + + # ## query annotations on row + if(!is.null(query_colors)){ + + stopifnot(all(rownames(cor_stats_layer) %in% names(query_colors))) + query_colors <- query_colors[rownames(cor_stats_layer)] + + + query_row_annotation <- ComplexHeatmap::rowAnnotation( + " " = rownames(cor_stats_layer), + col = list(" " = query_colors), + show_legend = FALSE) + + } else query_row_annotation <- NULL + + ## reference annotation on bottom + if(!is.null(reference_colors)){ + stopifnot(all(colnames(cor_stats_layer) %in% names(reference_colors))) + reference_colors <- reference_colors[colnames(cor_stats_layer)] + + ref_col_annotation <- ComplexHeatmap::columnAnnotation( + " " = colnames(cor_stats_layer), + col = list(" " = reference_colors), + show_legend = FALSE + ) + } else ref_col_annotation <- NULL + + + + ## plot heatmap + ComplexHeatmap::Heatmap( + matrix = cor_stats_layer, + col = my.col, + bottom_annotation = ref_col_annotation, + right_annotation = query_row_annotation, + ... + ) + + +} diff --git a/man/layer_stat_cor_plot_complex.Rd b/man/layer_stat_cor_plot_complex.Rd new file mode 100644 index 00000000..839d6743 --- /dev/null +++ b/man/layer_stat_cor_plot_complex.Rd @@ -0,0 +1,71 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/layer_stat_cor_plot_complex.R +\name{layer_stat_cor_plot_complex} +\alias{layer_stat_cor_plot_complex} +\title{Visualize the correlation of layer modeling t-statistics with ComplexHeatmap} +\usage{ +layer_stat_cor_plot_complex( + cor_stats_layer, + theSeq = seq(min(cor_stats_layer), max(cor_stats_layer), by = 0.01), + my.col = (grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, + "PRGn")))(length(theSeq)), + query_colors = NULL, + reference_colors = NULL, + ... +) +} +\arguments{ +\item{cor_stats_layer}{The output of \code{\link[=layer_stat_cor]{layer_stat_cor()}}.} + +\item{query_colors}{named vector of colors for query row annotations} + +\item{reference_colors}{named vector of colors for reference column annotations} +} +\value{ +ComplexHeatmap plot of t-stat correlations +} +\description{ +Visualize the correlation of layer modeling t-statistics with ComplexHeatmap +} +\examples{ +## Obtain the necessary data +## reference human pilot modeling results +if (!exists("modeling_results")) { + modeling_results <- fetch_data(type = "modeling_results") +} + +## querey spatailDLPFC modeling +query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") + +## extract t-statics and rename +registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] +colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) + +## Compute the correlations +cor_stats_layer <- layer_stat_cor( + stats = registration_t_stats, + modeling_results, + model_type = "enrichment" +) + +## Visualize the correlation matrix + +## most basic +layer_stat_cor_plot_complex(cor_stats_layer) + +## add colors +## add libd_layer_colors to refrence Human Pilot layers +layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) + +## supply polychrome colors to query clusters +cluster_colors <- Polychrome::palette36.colors(nrow(cor_stats_layer)) +names(cluster_colors) <- rownames(cor_stats_layer) + +layer_stat_cor_plot_complex(cor_stats_layer, + query_colors = cluster_colors, + reference_colors = libd_layer_colors) + +## Apply additional ComplexHeatmap param +layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE) + +} From 9028592182a1d1f75c0368f708200f4c0974ffa7 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 10:54:31 -0500 Subject: [PATCH 215/259] Add simplified layer labels as new column instead of modifiing layer_label (this preserves match with refernce data) --- R/annotate_registered_clusters.R | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index 13e1d5ab..865343c4 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -59,13 +59,6 @@ annotate_registered_clusters <- cutoff_merge_ratio = cutoff_merge_ratio ) - if (all(colnames(cor_stats_layer) %in% c("WM", paste0("Layer", seq_len(6))))) { - ## Simplify names when working with the default data - annotated <- gsub("ayer", "", annotated) - annotated <- gsub("\\/L", "\\/", annotated) - annotated <- gsub("^WM\\/", "WM\\/L", annotated) - } - confidence <- apply(cor_stats_layer, 1, max) > confidence_threshold result <- data.frame( @@ -83,6 +76,16 @@ annotate_registered_clusters <- result$layer_label, ifelse(result$layer_confidence == "good", "", "*") ) + + ## Add simplified label for WM/Layer annotations + if (all(colnames(cor_stats_layer) %in% c("WM", paste0("Layer", seq_len(6))))) { + result$layer_label_simple <- result$layer_label + ## Simplify names when working with the default data + result$layer_label_simple <- gsub("ayer", "", result$layer_label_simple ) + result$layer_label_simple <- gsub("\\/L", "\\/", result$layer_label_simple ) + result$layer_label_simple <- gsub("^WM\\/", "WM\\/L", result$layer_label_simple ) + } + return(result) } From 1bc9eac24c15732f0bb6d8b1d1f40c9784e8a822 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 13:10:22 -0500 Subject: [PATCH 216/259] Add ComplexHeatmap imports --- DESCRIPTION | 3 ++- NAMESPACE | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index a95b2b05..ad66f27f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -79,7 +79,8 @@ Imports: statmod, MatrixGenerics, rlang, - dplyr + dplyr, + ComplexHeatmap RoxygenNote: 7.3.2 Roxygen: list(markdown = TRUE) URL: https://github.com/LieberInstitute/spatialLIBD diff --git a/NAMESPACE b/NAMESPACE index 946c57f9..3fb849d5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -57,6 +57,9 @@ import(plotly, except = last_plot) import(shiny) importFrom(AnnotationHub,query) importFrom(BiocGenerics,which) +importFrom(ComplexHeatmap,Heatmap) +importFrom(ComplexHeatmap,columnAnnotation) +importFrom(ComplexHeatmap,rowAnnotation) importFrom(DT,DTOutput) importFrom(DT,renderDT) importFrom(GenomicRanges,seqnames) From f4e07a3d30c669302338c61abdd2f947da0e29ae Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 13:11:37 -0500 Subject: [PATCH 217/259] Update docs, improve params, add X annotations to heatmap --- R/layer_stat_cor_plot_complex.R | 97 +++++++++++++++++++++++++++--- man/layer_stat_cor_plot_complex.Rd | 56 ++++++++++++++--- 2 files changed, 135 insertions(+), 18 deletions(-) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R index f27c7d27..a07b70c0 100644 --- a/R/layer_stat_cor_plot_complex.R +++ b/R/layer_stat_cor_plot_complex.R @@ -1,13 +1,34 @@ - - #' Visualize the correlation of layer modeling t-statistics with ComplexHeatmap -#' @param query_colors named vector of colors for query row annotations -#' @param reference_colors named vector of colors for reference column annotations +#' +#' This function updates [layer_stat_cor_plot()], using ComplexHeatmap to plot +#' the correlation matrix between a reference and query modeling statistics +#' from [layer_stat_cor()]. Includes functionality to add color annotations, +#' (helpful to match to colors in Visium spot plots), and annotations from +#' [annotate_registered_clusters()]. +#' +#' @param color_max A `numeric(1)` specifying the highest correlation value for +#' the color scale (should be between 0 and 1). +#' @param color_min A `numeric(1)` specifying the lowest correlation value for +#' the color scale (should be between 0 and -1). +#' @param color_scale A `character` vector specifying the color scale for the +#' fill of the heatmap, defaults to classic purple -> green +#' @param query_colors named `character` vector of colors, Adds colors to query +#' row annotations +#' @param reference_colors named `character` vector of colors, Adds colors to +#' reference column annotations +#' @param annotation annotation data.frame output of [annotate_registered_clusters()], +#' adds 'X' for good confidence annotations, '*' for poor confidence #' #' @inheritParams layer_stat_cor_plot #' -#' @return ComplexHeatmap plot of t-stat correlations +#' @return ([Heatmap-class][ComplexHeatmap::Heatmap-class]) plot of t-stat correlations #' @export +#' @author Louise Huuki-Myers +#' @family Layer correlation functions +#' +#' @importFrom RColorBrewer brewer.pal +#' @importFrom grDevices colorRampPalette +#' @importFrom ComplexHeatmap columnAnnotation rowAnnotation Heatmap #' #' @examples #' ## Obtain the necessary data @@ -48,16 +69,33 @@ #' reference_colors = libd_layer_colors) #' #' ## Apply additional ComplexHeatmap param -#' layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE) +#' layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) #' +#' ## Add annotation +#' annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) +#' layer_stat_cor_plot_complex(cor_stats_layer, annotation = annotation_df) +#' +#' ## All together +#' layer_stat_cor_plot_complex(cor_stats_layer, +#' query_colors = cluster_colors, +#' reference_colors = libd_layer_colors, +#' annotation = annotation_df, +#' rect_gp = gpar(col = "black", lwd = 1)) +#' layer_stat_cor_plot_complex <- function(cor_stats_layer, - theSeq = seq(min(cor_stats_layer), max(cor_stats_layer), by = 0.01), - my.col = grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)), + color_max = max(cor_stats_layer), + color_min = min(cor_stats_layer), + color_scale = RColorBrewer::brewer.pal(7, "PRGn"), query_colors = NULL, reference_colors = NULL, + annotation = NULL, ... ){ + ## define color pallet + theSeq = seq(color_min, color_max, by = 0.01) + my.col = grDevices::colorRampPalette(color_scale)(length(theSeq)) + # ## query annotations on row if(!is.null(query_colors)){ @@ -84,16 +122,55 @@ layer_stat_cor_plot_complex <- function(cor_stats_layer, ) } else ref_col_annotation <- NULL - + ## add annotation + if(!is.null(annotation)){ + anno_matrix <- create_annotation_matrix(annotation, cor_stats_layer) + + ## plot heatmap + return( + ComplexHeatmap::Heatmap( + matrix = cor_stats_layer, + col = my.col, + bottom_annotation = ref_col_annotation, + right_annotation = query_row_annotation, + cell_fun = function(j, i, x, y, width, height, fill) { + grid.text(anno_matrix[i, j], x, y, gp = gpar(fontsize = 10)) + }, + ... + )) + } ## plot heatmap + return( ComplexHeatmap::Heatmap( matrix = cor_stats_layer, col = my.col, bottom_annotation = ref_col_annotation, right_annotation = query_row_annotation, ... - ) + )) } + +create_annotation_matrix <- function(annotation_df, cor_stats_layer){ + + anno_list <- lapply(rownames(cor_stats_layer), + function(cluster){ + # look up confidence + confidence <- annotation_df[match(cluster, annotation_df$cluster),"layer_confidence"] + sym <- ifelse(confidence=="good", "X","*") + # match annotations + anno <- annotation_df[match(cluster, annotation_df$cluster),"layer_label"] + return(ifelse(unlist(lapply(colnames(cor_stats_layer), grepl, anno)),sym,"")) + }) + + anno_matrix <- t(data.frame(anno_list)) + rownames(anno_matrix) <- rownames(cor_stats_layer) + colnames(anno_matrix) <- colnames(cor_stats_layer) + + return(anno_matrix) +} + + + diff --git a/man/layer_stat_cor_plot_complex.Rd b/man/layer_stat_cor_plot_complex.Rd index 839d6743..d4e022a0 100644 --- a/man/layer_stat_cor_plot_complex.Rd +++ b/man/layer_stat_cor_plot_complex.Rd @@ -6,26 +6,45 @@ \usage{ layer_stat_cor_plot_complex( cor_stats_layer, - theSeq = seq(min(cor_stats_layer), max(cor_stats_layer), by = 0.01), - my.col = (grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, - "PRGn")))(length(theSeq)), + color_max = max(cor_stats_layer), + color_min = min(cor_stats_layer), + color_scale = RColorBrewer::brewer.pal(7, "PRGn"), query_colors = NULL, reference_colors = NULL, + annotation = NULL, ... ) } \arguments{ \item{cor_stats_layer}{The output of \code{\link[=layer_stat_cor]{layer_stat_cor()}}.} -\item{query_colors}{named vector of colors for query row annotations} +\item{color_max}{A \code{numeric(1)} specifying the highest correlation value for +the color scale (should be between 0 and 1).} -\item{reference_colors}{named vector of colors for reference column annotations} +\item{color_min}{A \code{numeric(1)} specifying the lowest correlation value for +the color scale (should be between 0 and -1).} + +\item{color_scale}{A \code{character} vector specifying the color scale for the +fill of the heatmap, defaults to classic purple -> green} + +\item{query_colors}{named \code{character} vector of colors, Adds colors to query +row annotations} + +\item{reference_colors}{named \code{character} vector of colors, Adds colors to +reference column annotations} + +\item{annotation}{annotation data.frame output of \code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}, +adds 'X' for good confidence annotations, '*' for poor confidence} } \value{ -ComplexHeatmap plot of t-stat correlations +(\link[ComplexHeatmap:Heatmap-class]{Heatmap-class}) plot of t-stat correlations } \description{ -Visualize the correlation of layer modeling t-statistics with ComplexHeatmap +This function updates \code{\link[=layer_stat_cor_plot]{layer_stat_cor_plot()}}, using ComplexHeatmap to plot +the correlation matrix between a reference and query modeling statistics +from \code{\link[=layer_stat_cor]{layer_stat_cor()}}. Includes functionality to add color annotations, +(helpful to match to colors in Visium spot plots), and annotations from +\code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}. } \examples{ ## Obtain the necessary data @@ -66,6 +85,27 @@ layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) ## Apply additional ComplexHeatmap param -layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE) +layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) + +## Add annotation +annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) +layer_stat_cor_plot_complex(cor_stats_layer, annotation = annotation_df) +## All together +layer_stat_cor_plot_complex(cor_stats_layer, + query_colors = cluster_colors, + reference_colors = libd_layer_colors, + annotation = annotation_df, + rect_gp = gpar(col = "black", lwd = 1)) + +} +\seealso{ +Other Layer correlation functions: +\code{\link{annotate_registered_clusters}()}, +\code{\link{layer_stat_cor}()}, +\code{\link{layer_stat_cor_plot}()} +} +\author{ +Louise Huuki-Myers } +\concept{Layer correlation functions} From 804add1ef02cfe08be80550778bc2e2c922d3f08 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 13:12:02 -0500 Subject: [PATCH 218/259] link layer_layer_stat_cor_plot --- man/annotate_registered_clusters.Rd | 3 ++- man/layer_stat_cor.Rd | 3 ++- man/layer_stat_cor_plot.Rd | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/man/annotate_registered_clusters.Rd b/man/annotate_registered_clusters.Rd index 41d6245a..9ba61cfb 100644 --- a/man/annotate_registered_clusters.Rd +++ b/man/annotate_registered_clusters.Rd @@ -65,6 +65,7 @@ annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) \seealso{ Other Layer correlation functions: \code{\link{layer_stat_cor}()}, -\code{\link{layer_stat_cor_plot}()} +\code{\link{layer_stat_cor_plot}()}, +\code{\link{layer_stat_cor_plot_complex}()} } \concept{Layer correlation functions} diff --git a/man/layer_stat_cor.Rd b/man/layer_stat_cor.Rd index 3801a1d4..b42b45bc 100644 --- a/man/layer_stat_cor.Rd +++ b/man/layer_stat_cor.Rd @@ -86,7 +86,8 @@ summary(layer_stat_cor( \seealso{ Other Layer correlation functions: \code{\link{annotate_registered_clusters}()}, -\code{\link{layer_stat_cor_plot}()} +\code{\link{layer_stat_cor_plot}()}, +\code{\link{layer_stat_cor_plot_complex}()} } \author{ Andrew E Jaffe, Leonardo Collado-Torres diff --git a/man/layer_stat_cor_plot.Rd b/man/layer_stat_cor_plot.Rd index e01991a9..5a9d8189 100644 --- a/man/layer_stat_cor_plot.Rd +++ b/man/layer_stat_cor_plot.Rd @@ -91,7 +91,8 @@ layer_matrix_plot annotate_registered_clusters Other Layer correlation functions: \code{\link{annotate_registered_clusters}()}, -\code{\link{layer_stat_cor}()} +\code{\link{layer_stat_cor}()}, +\code{\link{layer_stat_cor_plot_complex}()} } \author{ Andrew E Jaffe, Leonardo Collado-Torres From d3278485f5245a1a8ea89cfaf5cd75191b25f7a1 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 13:51:18 -0500 Subject: [PATCH 219/259] Write out colors instead of using Polychrome --- R/layer_stat_cor_plot_complex.R | 2 +- man/layer_stat_cor_plot_complex.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R index a07b70c0..e3e9cc28 100644 --- a/R/layer_stat_cor_plot_complex.R +++ b/R/layer_stat_cor_plot_complex.R @@ -61,7 +61,7 @@ #' layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) #' #' ## supply polychrome colors to query clusters -#' cluster_colors <- Polychrome::palette36.colors(nrow(cor_stats_layer)) +#' cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') #' names(cluster_colors) <- rownames(cor_stats_layer) #' #' layer_stat_cor_plot_complex(cor_stats_layer, diff --git a/man/layer_stat_cor_plot_complex.Rd b/man/layer_stat_cor_plot_complex.Rd index d4e022a0..109a5056 100644 --- a/man/layer_stat_cor_plot_complex.Rd +++ b/man/layer_stat_cor_plot_complex.Rd @@ -77,7 +77,7 @@ layer_stat_cor_plot_complex(cor_stats_layer) layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) ## supply polychrome colors to query clusters -cluster_colors <- Polychrome::palette36.colors(nrow(cor_stats_layer)) +cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') names(cluster_colors) <- rownames(cor_stats_layer) layer_stat_cor_plot_complex(cor_stats_layer, From 7447f6148819e12b93fb6327508024f9c56c39cf Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 14:31:51 -0500 Subject: [PATCH 220/259] Add missing documentaion for ... --- R/layer_stat_cor_plot_complex.R | 1 + man/layer_stat_cor_plot_complex.Rd | 2 ++ 2 files changed, 3 insertions(+) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R index e3e9cc28..9326b7fb 100644 --- a/R/layer_stat_cor_plot_complex.R +++ b/R/layer_stat_cor_plot_complex.R @@ -18,6 +18,7 @@ #' reference column annotations #' @param annotation annotation data.frame output of [annotate_registered_clusters()], #' adds 'X' for good confidence annotations, '*' for poor confidence +#' @param ... Additinal parameters passed to [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] #' #' @inheritParams layer_stat_cor_plot #' diff --git a/man/layer_stat_cor_plot_complex.Rd b/man/layer_stat_cor_plot_complex.Rd index 109a5056..1df67a69 100644 --- a/man/layer_stat_cor_plot_complex.Rd +++ b/man/layer_stat_cor_plot_complex.Rd @@ -35,6 +35,8 @@ reference column annotations} \item{annotation}{annotation data.frame output of \code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}, adds 'X' for good confidence annotations, '*' for poor confidence} + +\item{...}{Additinal parameters passed to \code{\link[ComplexHeatmap:Heatmap]{ComplexHeatmap::Heatmap()}}} } \value{ (\link[ComplexHeatmap:Heatmap-class]{Heatmap-class}) plot of t-stat correlations From f2c9742b5f7fdb08a0027fb66e4e69efd1350a2f Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 14:57:43 -0500 Subject: [PATCH 221/259] rm gpar example --- R/layer_stat_cor_plot_complex.R | 5 +++-- man/layer_stat_cor_plot_complex.Rd | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R index 9326b7fb..95472725 100644 --- a/R/layer_stat_cor_plot_complex.R +++ b/R/layer_stat_cor_plot_complex.R @@ -80,8 +80,9 @@ #' layer_stat_cor_plot_complex(cor_stats_layer, #' query_colors = cluster_colors, #' reference_colors = libd_layer_colors, -#' annotation = annotation_df, -#' rect_gp = gpar(col = "black", lwd = 1)) +#' annotation = annotation_df, +#' cluster_rows = FALSE, +#' cluster_columns = FALSE) #' layer_stat_cor_plot_complex <- function(cor_stats_layer, color_max = max(cor_stats_layer), diff --git a/man/layer_stat_cor_plot_complex.Rd b/man/layer_stat_cor_plot_complex.Rd index 1df67a69..b85903f6 100644 --- a/man/layer_stat_cor_plot_complex.Rd +++ b/man/layer_stat_cor_plot_complex.Rd @@ -97,8 +97,9 @@ layer_stat_cor_plot_complex(cor_stats_layer, annotation = annotation_df) layer_stat_cor_plot_complex(cor_stats_layer, query_colors = cluster_colors, reference_colors = libd_layer_colors, - annotation = annotation_df, - rect_gp = gpar(col = "black", lwd = 1)) + annotation = annotation_df, + cluster_rows = FALSE, + cluster_columns = FALSE) } \seealso{ From 51aa0c819faeaa7e5c063f8b999ec37668878586 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 15:45:57 -0500 Subject: [PATCH 222/259] Add 'Cor' as title to color scale --- R/layer_stat_cor_plot_complex.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R index 95472725..9aa509ba 100644 --- a/R/layer_stat_cor_plot_complex.R +++ b/R/layer_stat_cor_plot_complex.R @@ -133,6 +133,7 @@ layer_stat_cor_plot_complex <- function(cor_stats_layer, ComplexHeatmap::Heatmap( matrix = cor_stats_layer, col = my.col, + name = "Cor", bottom_annotation = ref_col_annotation, right_annotation = query_row_annotation, cell_fun = function(j, i, x, y, width, height, fill) { @@ -147,6 +148,7 @@ layer_stat_cor_plot_complex <- function(cor_stats_layer, ComplexHeatmap::Heatmap( matrix = cor_stats_layer, col = my.col, + name = "Cor", bottom_annotation = ref_col_annotation, right_annotation = query_row_annotation, ... From 3df883a38d3e338ae16db03cfe3bff05cabf0c19 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 17:59:45 -0500 Subject: [PATCH 223/259] Add regex test for syntatic variables, use make.names to convert non-syntatic vars, add warnings --- R/registration_pseudobulk.R | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 2d859e4e..daf84d16 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -70,15 +70,22 @@ registration_pseudobulk <- stopifnot(!var_sample_id %in% covars) stopifnot(var_registration != var_sample_id) - ## Check that the values in the registration variable are ok + ## Check that the values in the registration variable are numeric + if(is.numeric(sce[[var_registration]])){ + warning(sprintf("var_registration \"%s\" is numeric, convering to catagorial vector...", + var_registration)) + } + + ## check for Non-Syntactic variables - convert with make.names & warn uniq_var_regis <- unique(sce[[var_registration]]) - if (any(grepl("\\+|\\-", uniq_var_regis))) { - stop( - "Remove the + and - signs in colData(sce)[, '", - var_registration, - "'] to avoid downstream issues.", - call. = FALSE + syntatic <- grepl("^((([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*)|[.])$", uniq_var_regis) + if (!all(syntatic)) { + warning(sprintf("var_registration \"%s\" contains non-syntatic variables: %s\nconverting to %s", + var_registration, + paste(uniq_var_regis[!syntatic], collapse = ", "), + paste(make.names(uniq_var_regis[!syntatic]), collapse = ", ")) ) + sce[[var_registration]] <- make.names(sce[[var_registration]]) } ## Pseudo-bulk for our current BayesSpace cluster results From bccdc97615bb2da926e738cad0fa220abec2bdfa Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Wed, 11 Dec 2024 18:00:14 -0500 Subject: [PATCH 224/259] Add tests for non-syntatic variables --- tests/testthat/test-registration_pseudobulk.R | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/testthat/test-registration_pseudobulk.R b/tests/testthat/test-registration_pseudobulk.R index 0b6deb6c..a31dd18f 100644 --- a/tests/testthat/test-registration_pseudobulk.R +++ b/tests/testthat/test-registration_pseudobulk.R @@ -11,3 +11,42 @@ test_that("NA check works", { "var_registration" ) }) + + +#### Syntactic Variable Test #### +set.seed(20220907) ## Ensure reproducibility of example data +sce <- scuttle::mockSCE() +## Add some sample IDs +sce$sample_id <- sample(LETTERS[1:5], ncol(sce), replace = TRUE) + +## Add a sample-level covariate: age +ages <- rnorm(5, mean = 20, sd = 4) +names(ages) <- LETTERS[1:5] +sce$age <- ages[sce$sample_id] + +## add variable with one group +sce$batch <- "batch1" + +## non-syntactic inputs +sce$cluster_int <- sample(1:4, ncol(sce), replace = TRUE) +sce$cluster_k <- paste0("k", sce$cluster_int) +sce$cluster_j <- paste0(sce$cluster_int,"j") +sce$cluster_l <- sample(c("L-1", "L2/3", "4L", "L5"), ncol(sce), replace = TRUE) + +test_that("warn for numeric var_registration", + expect_warning(registration_pseudobulk(sce, + var_registration = "cluster_int", + var_sample_id = "sample_id", + covars = c("age"), + min_ncells = NULL)) +) + + +test_that("warn for non-syntactic var_registration", + expect_warning(registration_pseudobulk(sce, + var_registration = "cluster_l", + var_sample_id = "sample_id", + covars = c("age"), + min_ncells = NULL)) +) + From c08ac1fd498ac349b9f78d4467a60ef7c76c705f Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 12 Dec 2024 09:13:12 -0500 Subject: [PATCH 225/259] Add same Syntactic variable test to registation wrapper, comment out unused 'cluster_k' --- tests/testthat/test-registration_pseudobulk.R | 2 +- tests/testthat/test-registration_wrapper.R | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-registration_pseudobulk.R b/tests/testthat/test-registration_pseudobulk.R index a31dd18f..57a2138e 100644 --- a/tests/testthat/test-registration_pseudobulk.R +++ b/tests/testthat/test-registration_pseudobulk.R @@ -29,7 +29,7 @@ sce$batch <- "batch1" ## non-syntactic inputs sce$cluster_int <- sample(1:4, ncol(sce), replace = TRUE) -sce$cluster_k <- paste0("k", sce$cluster_int) +# sce$cluster_k <- paste0("k", sce$cluster_int) sce$cluster_j <- paste0(sce$cluster_int,"j") sce$cluster_l <- sample(c("L-1", "L2/3", "4L", "L5"), ncol(sce), replace = TRUE) diff --git a/tests/testthat/test-registration_wrapper.R b/tests/testthat/test-registration_wrapper.R index b7deec09..38f4a88b 100644 --- a/tests/testthat/test-registration_wrapper.R +++ b/tests/testthat/test-registration_wrapper.R @@ -34,3 +34,43 @@ test_that( ) ) ) + +#### Syntactic Variable Test #### + +## catagorical var as int +sce$cluster_int <- sample(1:4, ncol(sce), replace = TRUE) +# sce$cluster_k <- paste0("k", sce$cluster_int) +sce$cluster_j <- paste0(sce$cluster_int,"j") +sce$cluster_l <- sample(c("L-1", "L2/3", "4L", "L5"), ncol(sce), replace = TRUE) + +table(sce$cluster_j) + +test_that("Numeric var_regisration throws warning", + expect_warning(registration_wrapper( + sce, + var_registration = "cluster_int", + var_sample_id = "sample_id", + covars = c("age"), + gene_ensembl = "ensembl", + gene_name = "gene_name", + suffix = "wrapper" + ))) + +test_that("Non-Syntactic thows warning", + expect_warning(registration_wrapper( + sce, + var_registration = "cluster_l", + var_sample_id = "sample_id", + covars = c("age"), + gene_ensembl = "ensembl", + gene_name = "gene_name", + suffix = "wrapper" + ))) + + + + + + + + From 94a99ac05dbf49f64fb6b4b9fc4ecdbd190d733c Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 12 Dec 2024 09:22:11 -0500 Subject: [PATCH 226/259] Add note on catagorical & syntactically valid catagories in var_registation documentation --- R/registration_pseudobulk.R | 4 +++- man/registration_pseudobulk.Rd | 4 +++- man/registration_wrapper.Rd | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index daf84d16..7480b838 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -8,7 +8,9 @@ #' object or one that inherits its properties. #' @param var_registration A `character(1)` specifying the `colData(sce)` #' variable of interest against which will be used for computing the relevant -#' statistics. +#' statistics. This should be a categorical variable, with all categories +#' syntaticly valid (could be used as an R variable, no special characters or +#' leading numbers), ex. 'L1.2', 'celltype2' not 'L1/2' or '2'. #' @param var_sample_id A `character(1)` specifying the `colData(sce)` variable #' with the sample ID. #' @param covars A `character()` with names of sample-level covariates. diff --git a/man/registration_pseudobulk.Rd b/man/registration_pseudobulk.Rd index 6df2d3a2..2d26041b 100644 --- a/man/registration_pseudobulk.Rd +++ b/man/registration_pseudobulk.Rd @@ -20,7 +20,9 @@ object or one that inherits its properties.} \item{var_registration}{A \code{character(1)} specifying the \code{colData(sce)} variable of interest against which will be used for computing the relevant -statistics.} +statistics. This should be a categorical variable, with all categories +syntaticly valid (could be used as an R variable, no special characters or +leading numbers), ex. 'L1.2', 'celltype2' not 'L1/2' or '2'.} \item{var_sample_id}{A \code{character(1)} specifying the \code{colData(sce)} variable with the sample ID.} diff --git a/man/registration_wrapper.Rd b/man/registration_wrapper.Rd index 76a2da32..d7463870 100644 --- a/man/registration_wrapper.Rd +++ b/man/registration_wrapper.Rd @@ -23,7 +23,9 @@ object or one that inherits its properties.} \item{var_registration}{A \code{character(1)} specifying the \code{colData(sce)} variable of interest against which will be used for computing the relevant -statistics.} +statistics. This should be a categorical variable, with all categories +syntaticly valid (could be used as an R variable, no special characters or +leading numbers), ex. 'L1.2', 'celltype2' not 'L1/2' or '2'.} \item{var_sample_id}{A \code{character(1)} specifying the \code{colData(sce)} variable with the sample ID.} From 8237d45f6f5753cdad1a064aca10b19e196fe79a Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 12 Dec 2024 10:49:06 -0500 Subject: [PATCH 227/259] Improve docs --- R/layer_stat_cor_plot_complex.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R index 9aa509ba..d7cfdbc9 100644 --- a/R/layer_stat_cor_plot_complex.R +++ b/R/layer_stat_cor_plot_complex.R @@ -6,6 +6,7 @@ #' (helpful to match to colors in Visium spot plots), and annotations from #' [annotate_registered_clusters()]. #' +#' @param cor_stats_layer The output of [layer_stat_cor()]. #' @param color_max A `numeric(1)` specifying the highest correlation value for #' the color scale (should be between 0 and 1). #' @param color_min A `numeric(1)` specifying the lowest correlation value for @@ -18,9 +19,9 @@ #' reference column annotations #' @param annotation annotation data.frame output of [annotate_registered_clusters()], #' adds 'X' for good confidence annotations, '*' for poor confidence -#' @param ... Additinal parameters passed to [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] +#' @param ... Additional parameters passed to [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] +#' ex. `cluster_rows` and `cluster_columns`. #' -#' @inheritParams layer_stat_cor_plot #' #' @return ([Heatmap-class][ComplexHeatmap::Heatmap-class]) plot of t-stat correlations #' @export From 8d6ed2626dd4f52d3ce737556544a31168afc498 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 12 Dec 2024 10:50:30 -0500 Subject: [PATCH 228/259] Replace layer_stat_cor_plot with layer_stat_cor_complex --- R/layer_stat_cor_plot.R | 255 ++++++++++++++++++++++++---------------- 1 file changed, 155 insertions(+), 100 deletions(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index a293fb66..1846a61f 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -1,126 +1,181 @@ -#' Visualize the correlation of layer modeling t-statistics -#' -#' This function makes a heatmap from the [layer_stat_cor()] correlation matrix -#' between a given set of cell cluster/type statistics derived from scRNA-seq -#' or snRNA-seq data (among other types) and the layer statistics from the -#' Human DLPFC Visium data (when using the default arguments). -#' +#' Visualize the correlation of layer modeling t-statistics with ComplexHeatmap +#' +#' This function updates [layer_stat_cor_plot()], using ComplexHeatmap to plot +#' the correlation matrix between a reference and query modeling statistics +#' from [layer_stat_cor()]. Includes functionality to add color annotations, +#' (helpful to match to colors in Visium spot plots), and annotations from +#' [annotate_registered_clusters()]. +#' #' @param cor_stats_layer The output of [layer_stat_cor()]. -#' @param max A `numeric(1)` specifying the highest correlation value for the -#' color scale (should be between 0 and 1). -#' @param min A `numeric(1)` specifying the lowest correlation value for the -#' color scale (should be between 0 and -1). -#' @param layerHeights A `numeric()` vector of length equal to -#' `ncol(cor_stats_layer) + 1` that starts at 0 specifying where -#' to plot the y-axis breaks which can be used for re-creating the length of -#' each brain layer. Gets passed to [layer_matrix_plot()]. -#' @param cex Passed to [layer_matrix_plot()]. +#' @param color_max A `numeric(1)` specifying the highest correlation value for +#' the color scale (should be between 0 and 1). +#' @param color_min A `numeric(1)` specifying the lowest correlation value for +#' the color scale (should be between 0 and -1). +#' @param color_scale A `character` vector specifying the color scale for the +#' fill of the heatmap, defaults to classic purple -> green +#' @param query_colors named `character` vector of colors, Adds colors to query +#' row annotations +#' @param reference_colors named `character` vector of colors, Adds colors to +#' reference column annotations +#' @param annotation annotation data.frame output of [annotate_registered_clusters()], +#' adds 'X' for good confidence annotations, '*' for poor confidence +#' @param ... Additional parameters passed to [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] +#' ex. `cluster_rows` and `cluster_columns`. #' -#' @return A heatmap for the correlation matrix between statistics. +#' +#' @return ([Heatmap-class][ComplexHeatmap::Heatmap-class]) plot of t-stat correlations #' @export -#' @author Andrew E Jaffe, Leonardo Collado-Torres +#' @author Louise Huuki-Myers #' @family Layer correlation functions -#' @seealso layer_matrix_plot annotate_registered_clusters #' #' @importFrom RColorBrewer brewer.pal #' @importFrom grDevices colorRampPalette -#' @details Check -#' https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R -#' for a full analysis from which this family of functions is derived from. +#' @importFrom ComplexHeatmap columnAnnotation rowAnnotation Heatmap #' #' @examples -#' #' ## Obtain the necessary data +#' ## reference human pilot modeling results #' if (!exists("modeling_results")) { #' modeling_results <- fetch_data(type = "modeling_results") #' } +#' +#' ## querey spatailDLPFC modeling +#' query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") +#' +#' ## extract t-statics and rename +#' registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] +#' colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) #' #' ## Compute the correlations #' cor_stats_layer <- layer_stat_cor( -#' tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer, +#' stats = registration_t_stats, #' modeling_results, #' model_type = "enrichment" #' ) #' #' ## Visualize the correlation matrix -#' layer_stat_cor_plot(cor_stats_layer, max = max(cor_stats_layer)) -#' -#' ## Annotate then re-plot -#' rownames(cor_stats_layer) <- paste0( -#' rownames(cor_stats_layer), -#' " - ", -#' annotate_registered_clusters(cor_stats_layer)$layer_label -#' ) -#' layer_stat_cor_plot(cor_stats_layer, max = max(cor_stats_layer)) -#' -#' ## Restrict the range of colors further -#' layer_stat_cor_plot(cor_stats_layer, max = 0.25) +#' +#' ## most basic +#' layer_stat_cor_plot_complex(cor_stats_layer) +#' +#' ## add colors +#' ## add libd_layer_colors to refrence Human Pilot layers +#' layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) +#' +#' ## supply polychrome colors to query clusters +#' cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') +#' names(cluster_colors) <- rownames(cor_stats_layer) #' -#' ## Repeat with just the top 10 layer marker genes -#' layer_stat_cor_plot(layer_stat_cor( -#' tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer, -#' modeling_results, -#' model_type = "enrichment", -#' top_n = 10 -#' ), max = 0.25) -#' -#' ## Now with the "pairwise" modeling results and also top_n = 10 -#' layer_stat_cor_plot(layer_stat_cor( -#' tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer, -#' modeling_results, -#' model_type = "pairwise", -#' top_n = 10 -#' ), max = 0.25) -layer_stat_cor_plot <- - function( - cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2) { - ## From https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R - theSeq <- seq(min, max, by = 0.01) - my.col <- grDevices::colorRampPalette(RColorBrewer::brewer.pal(7, "PRGn"))(length(theSeq)) - - ## Subset values - cor_stats_layer[cor_stats_layer <= min] <- min - cor_stats_layer[cor_stats_layer >= max] <- max - - ## Re-shape the matrix - mat_vals <- t(cor_stats_layer) - - ## Re-order and shorten names if they match our data - if (all(rownames(mat_vals) %in% c("WM", paste0("Layer", seq_len(6))))) { - rownames(mat_vals) <- gsub("ayer", "", rownames(mat_vals)) - mat_vals <- mat_vals[c("WM", paste0("L", rev(seq_len(6)))), , drop = FALSE] +#' layer_stat_cor_plot_complex(cor_stats_layer, +#' query_colors = cluster_colors, +#' reference_colors = libd_layer_colors) +#' +#' ## Apply additional ComplexHeatmap param +#' layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) +#' +#' ## Add annotation +#' annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) +#' layer_stat_cor_plot_complex(cor_stats_layer, annotation = annotation_df) +#' +#' ## All together +#' layer_stat_cor_plot_complex(cor_stats_layer, +#' query_colors = cluster_colors, +#' reference_colors = libd_layer_colors, +#' annotation = annotation_df, +#' cluster_rows = FALSE, +#' cluster_columns = FALSE) +#' +layer_stat_cor_plot <- function(cor_stats_layer, + color_max = max(cor_stats_layer), + color_min = min(cor_stats_layer), + color_scale = RColorBrewer::brewer.pal(7, "PRGn"), + query_colors = NULL, + reference_colors = NULL, + annotation = NULL, + ... +){ + + ## define color pallet + theSeq = seq(color_min, color_max, by = 0.01) + my.col = grDevices::colorRampPalette(color_scale)(length(theSeq)) + + # ## query annotations on row + if(!is.null(query_colors)){ + + stopifnot(all(rownames(cor_stats_layer) %in% names(query_colors))) + query_colors <- query_colors[rownames(cor_stats_layer)] + + + query_row_annotation <- ComplexHeatmap::rowAnnotation( + " " = rownames(cor_stats_layer), + col = list(" " = query_colors), + show_legend = FALSE) + + } else query_row_annotation <- NULL + + ## reference annotation on bottom + if(!is.null(reference_colors)){ + stopifnot(all(colnames(cor_stats_layer) %in% names(reference_colors))) + reference_colors <- reference_colors[colnames(cor_stats_layer)] + + ref_col_annotation <- ComplexHeatmap::columnAnnotation( + " " = colnames(cor_stats_layer), + col = list(" " = reference_colors), + show_legend = FALSE + ) + } else ref_col_annotation <- NULL + + ## add annotation + if(!is.null(annotation)){ + anno_matrix <- create_annotation_matrix(annotation, cor_stats_layer) + + ## plot heatmap + return( + ComplexHeatmap::Heatmap( + matrix = cor_stats_layer, + col = my.col, + name = "Cor", + bottom_annotation = ref_col_annotation, + right_annotation = query_row_annotation, + cell_fun = function(j, i, x, y, width, height, fill) { + grid.text(anno_matrix[i, j], x, y, gp = gpar(fontsize = 10)) + }, + ... + )) + } + + ## plot heatmap + return( + ComplexHeatmap::Heatmap( + matrix = cor_stats_layer, + col = my.col, + name = "Cor", + bottom_annotation = ref_col_annotation, + right_annotation = query_row_annotation, + ... + )) + + +} - ## Use our default layer heights also - if (is.null(layerHeights)) { - layerHeights <- c(0, 40, 55, 75, 85, 110, 120, 135) - } - } +create_annotation_matrix <- function(annotation_df, cor_stats_layer){ + + anno_list <- lapply(rownames(cor_stats_layer), + function(cluster){ + # look up confidence + confidence <- annotation_df[match(cluster, annotation_df$cluster),"layer_confidence"] + sym <- ifelse(confidence=="good", "X","*") + # match annotations + anno <- annotation_df[match(cluster, annotation_df$cluster),"layer_label"] + return(ifelse(unlist(lapply(colnames(cor_stats_layer), grepl, anno)),sym,"")) + }) + + anno_matrix <- t(data.frame(anno_list)) + rownames(anno_matrix) <- rownames(cor_stats_layer) + colnames(anno_matrix) <- colnames(cor_stats_layer) + + return(anno_matrix) +} - ## From fields:::imagePlotInfo - midpoints <- seq(min, max, length.out = length(my.col)) - delta <- (midpoints[2] - midpoints[1]) / 2 - breaks <- c(midpoints[1] - delta, midpoints + delta) - legend_cuts <- seq(-1, 1, by = 0.1) - legend_cuts <- legend_cuts[legend_cuts >= min & legend_cuts <= max] - axis.args <- list( - at = legend_cuts, - labels = legend_cuts - ) - layer_matrix_plot( - matrix_values = mat_vals, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = layerHeights, - mypal = my.col, - breaks = breaks, - axis.args = axis.args, - srt = 90, - cex = cex - ) - } From f6b74cd03144e6e0e240d200320478368507ed67 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 12 Dec 2024 10:53:49 -0500 Subject: [PATCH 229/259] Update docs for layer_stat_cor_plot --- R/layer_stat_cor_plot.R | 27 +++++---- man/layer_stat_cor_plot.Rd | 119 +++++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 64 deletions(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 1846a61f..df432d8a 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -1,8 +1,9 @@ #' Visualize the correlation of layer modeling t-statistics with ComplexHeatmap #' -#' This function updates [layer_stat_cor_plot()], using ComplexHeatmap to plot -#' the correlation matrix between a reference and query modeling statistics -#' from [layer_stat_cor()]. Includes functionality to add color annotations, +#' Use ComplexHeatmap to plot the correlation matrix between a reference and +#' query modeling statistics from [layer_stat_cor()]. +#' +#' Includes functionality to add color annotations, #' (helpful to match to colors in Visium spot plots), and annotations from #' [annotate_registered_clusters()]. #' @@ -12,13 +13,13 @@ #' @param color_min A `numeric(1)` specifying the lowest correlation value for #' the color scale (should be between 0 and -1). #' @param color_scale A `character` vector specifying the color scale for the -#' fill of the heatmap, defaults to classic purple -> green +#' fill of the heatmap, defaults to classic purple -> green. #' @param query_colors named `character` vector of colors, Adds colors to query -#' row annotations +#' row annotations. #' @param reference_colors named `character` vector of colors, Adds colors to -#' reference column annotations +#' reference column annotations. #' @param annotation annotation data.frame output of [annotate_registered_clusters()], -#' adds 'X' for good confidence annotations, '*' for poor confidence +#' adds 'X' for good confidence annotations, '*' for poor confidence. #' @param ... Additional parameters passed to [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] #' ex. `cluster_rows` and `cluster_columns`. #' @@ -56,29 +57,29 @@ #' ## Visualize the correlation matrix #' #' ## most basic -#' layer_stat_cor_plot_complex(cor_stats_layer) +#' layer_stat_cor_plot(cor_stats_layer) #' #' ## add colors #' ## add libd_layer_colors to refrence Human Pilot layers -#' layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) +#' layer_stat_cor_plot(cor_stats_layer, reference_colors = libd_layer_colors) #' #' ## supply polychrome colors to query clusters #' cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') #' names(cluster_colors) <- rownames(cor_stats_layer) #' -#' layer_stat_cor_plot_complex(cor_stats_layer, +#' layer_stat_cor_plot(cor_stats_layer, #' query_colors = cluster_colors, #' reference_colors = libd_layer_colors) #' #' ## Apply additional ComplexHeatmap param -#' layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) +#' layer_stat_cor_plot(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) #' #' ## Add annotation #' annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) -#' layer_stat_cor_plot_complex(cor_stats_layer, annotation = annotation_df) +#' layer_stat_cor_plot(cor_stats_layer, annotation = annotation_df) #' #' ## All together -#' layer_stat_cor_plot_complex(cor_stats_layer, +#' layer_stat_cor_plot(cor_stats_layer, #' query_colors = cluster_colors, #' reference_colors = libd_layer_colors, #' annotation = annotation_df, diff --git a/man/layer_stat_cor_plot.Rd b/man/layer_stat_cor_plot.Rd index 5a9d8189..482233a5 100644 --- a/man/layer_stat_cor_plot.Rd +++ b/man/layer_stat_cor_plot.Rd @@ -2,99 +2,116 @@ % Please edit documentation in R/layer_stat_cor_plot.R \name{layer_stat_cor_plot} \alias{layer_stat_cor_plot} -\title{Visualize the correlation of layer modeling t-statistics} +\title{Visualize the correlation of layer modeling t-statistics with ComplexHeatmap} \usage{ layer_stat_cor_plot( cor_stats_layer, - max = 0.81, - min = -max, - layerHeights = NULL, - cex = 1.2 + color_max = max(cor_stats_layer), + color_min = min(cor_stats_layer), + color_scale = RColorBrewer::brewer.pal(7, "PRGn"), + query_colors = NULL, + reference_colors = NULL, + annotation = NULL, + ... ) } \arguments{ \item{cor_stats_layer}{The output of \code{\link[=layer_stat_cor]{layer_stat_cor()}}.} -\item{max}{A \code{numeric(1)} specifying the highest correlation value for the -color scale (should be between 0 and 1).} +\item{color_max}{A \code{numeric(1)} specifying the highest correlation value for +the color scale (should be between 0 and 1).} -\item{min}{A \code{numeric(1)} specifying the lowest correlation value for the -color scale (should be between 0 and -1).} +\item{color_min}{A \code{numeric(1)} specifying the lowest correlation value for +the color scale (should be between 0 and -1).} -\item{layerHeights}{A \code{numeric()} vector of length equal to -\code{ncol(cor_stats_layer) + 1} that starts at 0 specifying where -to plot the y-axis breaks which can be used for re-creating the length of -each brain layer. Gets passed to \code{\link[=layer_matrix_plot]{layer_matrix_plot()}}.} +\item{color_scale}{A \code{character} vector specifying the color scale for the +fill of the heatmap, defaults to classic purple -> green.} -\item{cex}{Passed to \code{\link[=layer_matrix_plot]{layer_matrix_plot()}}.} +\item{query_colors}{named \code{character} vector of colors, Adds colors to query +row annotations.} + +\item{reference_colors}{named \code{character} vector of colors, Adds colors to +reference column annotations.} + +\item{annotation}{annotation data.frame output of \code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}, +adds 'X' for good confidence annotations, '*' for poor confidence.} + +\item{...}{Additional parameters passed to \code{\link[ComplexHeatmap:Heatmap]{ComplexHeatmap::Heatmap()}} +ex. \code{cluster_rows} and \code{cluster_columns}.} } \value{ -A heatmap for the correlation matrix between statistics. +(\link[ComplexHeatmap:Heatmap-class]{Heatmap-class}) plot of t-stat correlations } \description{ -This function makes a heatmap from the \code{\link[=layer_stat_cor]{layer_stat_cor()}} correlation matrix -between a given set of cell cluster/type statistics derived from scRNA-seq -or snRNA-seq data (among other types) and the layer statistics from the -Human DLPFC Visium data (when using the default arguments). +Use ComplexHeatmap to plot the correlation matrix between a reference and +query modeling statistics from \code{\link[=layer_stat_cor]{layer_stat_cor()}}. } \details{ -Check -https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/dlpfc_snRNAseq_annotation.R -for a full analysis from which this family of functions is derived from. +Includes functionality to add color annotations, +(helpful to match to colors in Visium spot plots), and annotations from +\code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}. } \examples{ - ## Obtain the necessary data +## reference human pilot modeling results if (!exists("modeling_results")) { modeling_results <- fetch_data(type = "modeling_results") } +## querey spatailDLPFC modeling +query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") + +## extract t-statics and rename +registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] +colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) + ## Compute the correlations cor_stats_layer <- layer_stat_cor( - tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer, + stats = registration_t_stats, modeling_results, model_type = "enrichment" ) ## Visualize the correlation matrix -layer_stat_cor_plot(cor_stats_layer, max = max(cor_stats_layer)) -## Annotate then re-plot -rownames(cor_stats_layer) <- paste0( - rownames(cor_stats_layer), - " - ", - annotate_registered_clusters(cor_stats_layer)$layer_label -) -layer_stat_cor_plot(cor_stats_layer, max = max(cor_stats_layer)) +## most basic +layer_stat_cor_plot(cor_stats_layer) -## Restrict the range of colors further -layer_stat_cor_plot(cor_stats_layer, max = 0.25) +## add colors +## add libd_layer_colors to refrence Human Pilot layers +layer_stat_cor_plot(cor_stats_layer, reference_colors = libd_layer_colors) -## Repeat with just the top 10 layer marker genes -layer_stat_cor_plot(layer_stat_cor( - tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer, - modeling_results, - model_type = "enrichment", - top_n = 10 -), max = 0.25) +## supply polychrome colors to query clusters +cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') +names(cluster_colors) <- rownames(cor_stats_layer) -## Now with the "pairwise" modeling results and also top_n = 10 -layer_stat_cor_plot(layer_stat_cor( - tstats_Human_DLPFC_snRNAseq_Nguyen_topLayer, - modeling_results, - model_type = "pairwise", - top_n = 10 -), max = 0.25) +layer_stat_cor_plot(cor_stats_layer, + query_colors = cluster_colors, + reference_colors = libd_layer_colors) + +## Apply additional ComplexHeatmap param +layer_stat_cor_plot(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) + +## Add annotation +annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) +layer_stat_cor_plot(cor_stats_layer, annotation = annotation_df) + +## All together +layer_stat_cor_plot(cor_stats_layer, + query_colors = cluster_colors, + reference_colors = libd_layer_colors, + annotation = annotation_df, + cluster_rows = FALSE, + cluster_columns = FALSE) + } \seealso{ -layer_matrix_plot annotate_registered_clusters - Other Layer correlation functions: \code{\link{annotate_registered_clusters}()}, \code{\link{layer_stat_cor}()}, \code{\link{layer_stat_cor_plot_complex}()} } \author{ -Andrew E Jaffe, Leonardo Collado-Torres +Louise Huuki-Myers } \concept{Layer correlation functions} From 445a62cbb0b0f782c3426363454b0b3e85db577f Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Thu, 12 Dec 2024 10:54:40 -0500 Subject: [PATCH 230/259] rm layer_stat_cor_complex.R --- NAMESPACE | 1 - R/layer_stat_cor_plot_complex.R | 181 ---------------------------- man/annotate_registered_clusters.Rd | 3 +- man/layer_stat_cor.Rd | 3 +- man/layer_stat_cor_plot.Rd | 3 +- man/layer_stat_cor_plot_complex.Rd | 114 ------------------ 6 files changed, 3 insertions(+), 302 deletions(-) delete mode 100644 R/layer_stat_cor_plot_complex.R delete mode 100644 man/layer_stat_cor_plot_complex.Rd diff --git a/NAMESPACE b/NAMESPACE index 3fb849d5..c85f884a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,7 +25,6 @@ export(layer_boxplot) export(layer_matrix_plot) export(layer_stat_cor) export(layer_stat_cor_plot) -export(layer_stat_cor_plot_complex) export(locate_images) export(read10xVisiumAnalysis) export(read10xVisiumWrapper) diff --git a/R/layer_stat_cor_plot_complex.R b/R/layer_stat_cor_plot_complex.R deleted file mode 100644 index d7cfdbc9..00000000 --- a/R/layer_stat_cor_plot_complex.R +++ /dev/null @@ -1,181 +0,0 @@ -#' Visualize the correlation of layer modeling t-statistics with ComplexHeatmap -#' -#' This function updates [layer_stat_cor_plot()], using ComplexHeatmap to plot -#' the correlation matrix between a reference and query modeling statistics -#' from [layer_stat_cor()]. Includes functionality to add color annotations, -#' (helpful to match to colors in Visium spot plots), and annotations from -#' [annotate_registered_clusters()]. -#' -#' @param cor_stats_layer The output of [layer_stat_cor()]. -#' @param color_max A `numeric(1)` specifying the highest correlation value for -#' the color scale (should be between 0 and 1). -#' @param color_min A `numeric(1)` specifying the lowest correlation value for -#' the color scale (should be between 0 and -1). -#' @param color_scale A `character` vector specifying the color scale for the -#' fill of the heatmap, defaults to classic purple -> green -#' @param query_colors named `character` vector of colors, Adds colors to query -#' row annotations -#' @param reference_colors named `character` vector of colors, Adds colors to -#' reference column annotations -#' @param annotation annotation data.frame output of [annotate_registered_clusters()], -#' adds 'X' for good confidence annotations, '*' for poor confidence -#' @param ... Additional parameters passed to [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] -#' ex. `cluster_rows` and `cluster_columns`. -#' -#' -#' @return ([Heatmap-class][ComplexHeatmap::Heatmap-class]) plot of t-stat correlations -#' @export -#' @author Louise Huuki-Myers -#' @family Layer correlation functions -#' -#' @importFrom RColorBrewer brewer.pal -#' @importFrom grDevices colorRampPalette -#' @importFrom ComplexHeatmap columnAnnotation rowAnnotation Heatmap -#' -#' @examples -#' ## Obtain the necessary data -#' ## reference human pilot modeling results -#' if (!exists("modeling_results")) { -#' modeling_results <- fetch_data(type = "modeling_results") -#' } -#' -#' ## querey spatailDLPFC modeling -#' query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") -#' -#' ## extract t-statics and rename -#' registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] -#' colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) -#' -#' ## Compute the correlations -#' cor_stats_layer <- layer_stat_cor( -#' stats = registration_t_stats, -#' modeling_results, -#' model_type = "enrichment" -#' ) -#' -#' ## Visualize the correlation matrix -#' -#' ## most basic -#' layer_stat_cor_plot_complex(cor_stats_layer) -#' -#' ## add colors -#' ## add libd_layer_colors to refrence Human Pilot layers -#' layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) -#' -#' ## supply polychrome colors to query clusters -#' cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') -#' names(cluster_colors) <- rownames(cor_stats_layer) -#' -#' layer_stat_cor_plot_complex(cor_stats_layer, -#' query_colors = cluster_colors, -#' reference_colors = libd_layer_colors) -#' -#' ## Apply additional ComplexHeatmap param -#' layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) -#' -#' ## Add annotation -#' annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) -#' layer_stat_cor_plot_complex(cor_stats_layer, annotation = annotation_df) -#' -#' ## All together -#' layer_stat_cor_plot_complex(cor_stats_layer, -#' query_colors = cluster_colors, -#' reference_colors = libd_layer_colors, -#' annotation = annotation_df, -#' cluster_rows = FALSE, -#' cluster_columns = FALSE) -#' -layer_stat_cor_plot_complex <- function(cor_stats_layer, - color_max = max(cor_stats_layer), - color_min = min(cor_stats_layer), - color_scale = RColorBrewer::brewer.pal(7, "PRGn"), - query_colors = NULL, - reference_colors = NULL, - annotation = NULL, - ... - ){ - - ## define color pallet - theSeq = seq(color_min, color_max, by = 0.01) - my.col = grDevices::colorRampPalette(color_scale)(length(theSeq)) - - # ## query annotations on row - if(!is.null(query_colors)){ - - stopifnot(all(rownames(cor_stats_layer) %in% names(query_colors))) - query_colors <- query_colors[rownames(cor_stats_layer)] - - - query_row_annotation <- ComplexHeatmap::rowAnnotation( - " " = rownames(cor_stats_layer), - col = list(" " = query_colors), - show_legend = FALSE) - - } else query_row_annotation <- NULL - - ## reference annotation on bottom - if(!is.null(reference_colors)){ - stopifnot(all(colnames(cor_stats_layer) %in% names(reference_colors))) - reference_colors <- reference_colors[colnames(cor_stats_layer)] - - ref_col_annotation <- ComplexHeatmap::columnAnnotation( - " " = colnames(cor_stats_layer), - col = list(" " = reference_colors), - show_legend = FALSE - ) - } else ref_col_annotation <- NULL - - ## add annotation - if(!is.null(annotation)){ - anno_matrix <- create_annotation_matrix(annotation, cor_stats_layer) - - ## plot heatmap - return( - ComplexHeatmap::Heatmap( - matrix = cor_stats_layer, - col = my.col, - name = "Cor", - bottom_annotation = ref_col_annotation, - right_annotation = query_row_annotation, - cell_fun = function(j, i, x, y, width, height, fill) { - grid.text(anno_matrix[i, j], x, y, gp = gpar(fontsize = 10)) - }, - ... - )) - } - - ## plot heatmap - return( - ComplexHeatmap::Heatmap( - matrix = cor_stats_layer, - col = my.col, - name = "Cor", - bottom_annotation = ref_col_annotation, - right_annotation = query_row_annotation, - ... - )) - - -} - -create_annotation_matrix <- function(annotation_df, cor_stats_layer){ - - anno_list <- lapply(rownames(cor_stats_layer), - function(cluster){ - # look up confidence - confidence <- annotation_df[match(cluster, annotation_df$cluster),"layer_confidence"] - sym <- ifelse(confidence=="good", "X","*") - # match annotations - anno <- annotation_df[match(cluster, annotation_df$cluster),"layer_label"] - return(ifelse(unlist(lapply(colnames(cor_stats_layer), grepl, anno)),sym,"")) - }) - - anno_matrix <- t(data.frame(anno_list)) - rownames(anno_matrix) <- rownames(cor_stats_layer) - colnames(anno_matrix) <- colnames(cor_stats_layer) - - return(anno_matrix) -} - - - diff --git a/man/annotate_registered_clusters.Rd b/man/annotate_registered_clusters.Rd index 9ba61cfb..41d6245a 100644 --- a/man/annotate_registered_clusters.Rd +++ b/man/annotate_registered_clusters.Rd @@ -65,7 +65,6 @@ annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) \seealso{ Other Layer correlation functions: \code{\link{layer_stat_cor}()}, -\code{\link{layer_stat_cor_plot}()}, -\code{\link{layer_stat_cor_plot_complex}()} +\code{\link{layer_stat_cor_plot}()} } \concept{Layer correlation functions} diff --git a/man/layer_stat_cor.Rd b/man/layer_stat_cor.Rd index b42b45bc..3801a1d4 100644 --- a/man/layer_stat_cor.Rd +++ b/man/layer_stat_cor.Rd @@ -86,8 +86,7 @@ summary(layer_stat_cor( \seealso{ Other Layer correlation functions: \code{\link{annotate_registered_clusters}()}, -\code{\link{layer_stat_cor_plot}()}, -\code{\link{layer_stat_cor_plot_complex}()} +\code{\link{layer_stat_cor_plot}()} } \author{ Andrew E Jaffe, Leonardo Collado-Torres diff --git a/man/layer_stat_cor_plot.Rd b/man/layer_stat_cor_plot.Rd index 482233a5..8eccd53d 100644 --- a/man/layer_stat_cor_plot.Rd +++ b/man/layer_stat_cor_plot.Rd @@ -108,8 +108,7 @@ layer_stat_cor_plot(cor_stats_layer, \seealso{ Other Layer correlation functions: \code{\link{annotate_registered_clusters}()}, -\code{\link{layer_stat_cor}()}, -\code{\link{layer_stat_cor_plot_complex}()} +\code{\link{layer_stat_cor}()} } \author{ Louise Huuki-Myers diff --git a/man/layer_stat_cor_plot_complex.Rd b/man/layer_stat_cor_plot_complex.Rd deleted file mode 100644 index b85903f6..00000000 --- a/man/layer_stat_cor_plot_complex.Rd +++ /dev/null @@ -1,114 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/layer_stat_cor_plot_complex.R -\name{layer_stat_cor_plot_complex} -\alias{layer_stat_cor_plot_complex} -\title{Visualize the correlation of layer modeling t-statistics with ComplexHeatmap} -\usage{ -layer_stat_cor_plot_complex( - cor_stats_layer, - color_max = max(cor_stats_layer), - color_min = min(cor_stats_layer), - color_scale = RColorBrewer::brewer.pal(7, "PRGn"), - query_colors = NULL, - reference_colors = NULL, - annotation = NULL, - ... -) -} -\arguments{ -\item{cor_stats_layer}{The output of \code{\link[=layer_stat_cor]{layer_stat_cor()}}.} - -\item{color_max}{A \code{numeric(1)} specifying the highest correlation value for -the color scale (should be between 0 and 1).} - -\item{color_min}{A \code{numeric(1)} specifying the lowest correlation value for -the color scale (should be between 0 and -1).} - -\item{color_scale}{A \code{character} vector specifying the color scale for the -fill of the heatmap, defaults to classic purple -> green} - -\item{query_colors}{named \code{character} vector of colors, Adds colors to query -row annotations} - -\item{reference_colors}{named \code{character} vector of colors, Adds colors to -reference column annotations} - -\item{annotation}{annotation data.frame output of \code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}, -adds 'X' for good confidence annotations, '*' for poor confidence} - -\item{...}{Additinal parameters passed to \code{\link[ComplexHeatmap:Heatmap]{ComplexHeatmap::Heatmap()}}} -} -\value{ -(\link[ComplexHeatmap:Heatmap-class]{Heatmap-class}) plot of t-stat correlations -} -\description{ -This function updates \code{\link[=layer_stat_cor_plot]{layer_stat_cor_plot()}}, using ComplexHeatmap to plot -the correlation matrix between a reference and query modeling statistics -from \code{\link[=layer_stat_cor]{layer_stat_cor()}}. Includes functionality to add color annotations, -(helpful to match to colors in Visium spot plots), and annotations from -\code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}. -} -\examples{ -## Obtain the necessary data -## reference human pilot modeling results -if (!exists("modeling_results")) { - modeling_results <- fetch_data(type = "modeling_results") -} - -## querey spatailDLPFC modeling -query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") - -## extract t-statics and rename -registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] -colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) - -## Compute the correlations -cor_stats_layer <- layer_stat_cor( - stats = registration_t_stats, - modeling_results, - model_type = "enrichment" -) - -## Visualize the correlation matrix - -## most basic -layer_stat_cor_plot_complex(cor_stats_layer) - -## add colors -## add libd_layer_colors to refrence Human Pilot layers -layer_stat_cor_plot_complex(cor_stats_layer, reference_colors = libd_layer_colors) - -## supply polychrome colors to query clusters -cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') -names(cluster_colors) <- rownames(cor_stats_layer) - -layer_stat_cor_plot_complex(cor_stats_layer, - query_colors = cluster_colors, - reference_colors = libd_layer_colors) - -## Apply additional ComplexHeatmap param -layer_stat_cor_plot_complex(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) - -## Add annotation -annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) -layer_stat_cor_plot_complex(cor_stats_layer, annotation = annotation_df) - -## All together -layer_stat_cor_plot_complex(cor_stats_layer, - query_colors = cluster_colors, - reference_colors = libd_layer_colors, - annotation = annotation_df, - cluster_rows = FALSE, - cluster_columns = FALSE) - -} -\seealso{ -Other Layer correlation functions: -\code{\link{annotate_registered_clusters}()}, -\code{\link{layer_stat_cor}()}, -\code{\link{layer_stat_cor_plot}()} -} -\author{ -Louise Huuki-Myers -} -\concept{Layer correlation functions} From a7c808fd8274ebec29d267020bc188ad6669d0b9 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 11:29:16 -0500 Subject: [PATCH 231/259] Restore some of the initial function description + update the language. Co-authored-by: Louise Huuki --- R/layer_stat_cor_plot.R | 94 +++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index df432d8a..845954c5 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -1,22 +1,26 @@ #' Visualize the correlation of layer modeling t-statistics with ComplexHeatmap -#' -#' Use ComplexHeatmap to plot the correlation matrix between a reference and -#' query modeling statistics from [layer_stat_cor()]. -#' -#' Includes functionality to add color annotations, -#' (helpful to match to colors in Visium spot plots), and annotations from +#' +#' This function makes a ComplexHeatmap from the correlation matrix +#' between a reference and query modeling statistics from [layer_stat_cor()]. +#' For example, between the query statistics from a set of cell cluster/types derived +#' from scRNA-seq or snRNA-seq data (among other types) and the reference layer +#' statistics from the Human DLPFC Visium data (when using the default +#' arguments). +#' +#' Includes functionality to add color annotations, +#' (helpful to match to colors in Visium spot plots), and annotations from #' [annotate_registered_clusters()]. -#' +#' #' @param cor_stats_layer The output of [layer_stat_cor()]. -#' @param color_max A `numeric(1)` specifying the highest correlation value for +#' @param color_max A `numeric(1)` specifying the highest correlation value for #' the color scale (should be between 0 and 1). -#' @param color_min A `numeric(1)` specifying the lowest correlation value for +#' @param color_min A `numeric(1)` specifying the lowest correlation value for #' the color scale (should be between 0 and -1). -#' @param color_scale A `character` vector specifying the color scale for the +#' @param color_scale A `character` vector specifying the color scale for the #' fill of the heatmap, defaults to classic purple -> green. -#' @param query_colors named `character` vector of colors, Adds colors to query +#' @param query_colors named `character` vector of colors, Adds colors to query #' row annotations. -#' @param reference_colors named `character` vector of colors, Adds colors to +#' @param reference_colors named `character` vector of colors, Adds colors to #' reference column annotations. #' @param annotation annotation data.frame output of [annotate_registered_clusters()], #' adds 'X' for good confidence annotations, '*' for poor confidence. @@ -39,10 +43,10 @@ #' if (!exists("modeling_results")) { #' modeling_results <- fetch_data(type = "modeling_results") #' } -#' -#' ## querey spatailDLPFC modeling +#' +#' ## querey spatailDLPFC modeling #' query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") -#' +#' #' ## extract t-statics and rename #' registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] #' colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) @@ -55,37 +59,37 @@ #' ) #' #' ## Visualize the correlation matrix -#' +#' #' ## most basic #' layer_stat_cor_plot(cor_stats_layer) -#' +#' #' ## add colors #' ## add libd_layer_colors to refrence Human Pilot layers #' layer_stat_cor_plot(cor_stats_layer, reference_colors = libd_layer_colors) -#' +#' #' ## supply polychrome colors to query clusters #' cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') #' names(cluster_colors) <- rownames(cor_stats_layer) #' -#' layer_stat_cor_plot(cor_stats_layer, +#' layer_stat_cor_plot(cor_stats_layer, #' query_colors = cluster_colors, #' reference_colors = libd_layer_colors) -#' +#' #' ## Apply additional ComplexHeatmap param #' layer_stat_cor_plot(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) -#' +#' #' ## Add annotation #' annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) #' layer_stat_cor_plot(cor_stats_layer, annotation = annotation_df) -#' +#' #' ## All together -#' layer_stat_cor_plot(cor_stats_layer, +#' layer_stat_cor_plot(cor_stats_layer, #' query_colors = cluster_colors, -#' reference_colors = libd_layer_colors, -#' annotation = annotation_df, -#' cluster_rows = FALSE, +#' reference_colors = libd_layer_colors, +#' annotation = annotation_df, +#' cluster_rows = FALSE, #' cluster_columns = FALSE) -#' +#' layer_stat_cor_plot <- function(cor_stats_layer, color_max = max(cor_stats_layer), color_min = min(cor_stats_layer), @@ -95,41 +99,41 @@ layer_stat_cor_plot <- function(cor_stats_layer, annotation = NULL, ... ){ - + ## define color pallet theSeq = seq(color_min, color_max, by = 0.01) my.col = grDevices::colorRampPalette(color_scale)(length(theSeq)) - + # ## query annotations on row if(!is.null(query_colors)){ - + stopifnot(all(rownames(cor_stats_layer) %in% names(query_colors))) query_colors <- query_colors[rownames(cor_stats_layer)] - - + + query_row_annotation <- ComplexHeatmap::rowAnnotation( " " = rownames(cor_stats_layer), col = list(" " = query_colors), show_legend = FALSE) - + } else query_row_annotation <- NULL - + ## reference annotation on bottom if(!is.null(reference_colors)){ stopifnot(all(colnames(cor_stats_layer) %in% names(reference_colors))) reference_colors <- reference_colors[colnames(cor_stats_layer)] - + ref_col_annotation <- ComplexHeatmap::columnAnnotation( " " = colnames(cor_stats_layer), col = list(" " = reference_colors), show_legend = FALSE ) } else ref_col_annotation <- NULL - + ## add annotation if(!is.null(annotation)){ anno_matrix <- create_annotation_matrix(annotation, cor_stats_layer) - + ## plot heatmap return( ComplexHeatmap::Heatmap( @@ -144,7 +148,7 @@ layer_stat_cor_plot <- function(cor_stats_layer, ... )) } - + ## plot heatmap return( ComplexHeatmap::Heatmap( @@ -155,26 +159,26 @@ layer_stat_cor_plot <- function(cor_stats_layer, right_annotation = query_row_annotation, ... )) - - + + } create_annotation_matrix <- function(annotation_df, cor_stats_layer){ - - anno_list <- lapply(rownames(cor_stats_layer), + + anno_list <- lapply(rownames(cor_stats_layer), function(cluster){ - # look up confidence + # look up confidence confidence <- annotation_df[match(cluster, annotation_df$cluster),"layer_confidence"] sym <- ifelse(confidence=="good", "X","*") # match annotations anno <- annotation_df[match(cluster, annotation_df$cluster),"layer_label"] return(ifelse(unlist(lapply(colnames(cor_stats_layer), grepl, anno)),sym,"")) }) - + anno_matrix <- t(data.frame(anno_list)) rownames(anno_matrix) <- rownames(cor_stats_layer) colnames(anno_matrix) <- colnames(cor_stats_layer) - + return(anno_matrix) } From c9bbcd0bf382047ded4b1c74d648ec3d1f03be8f Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 11:32:22 -0500 Subject: [PATCH 232/259] Rename color_max and color_min to max and min to match the original argument names. Co-authored-by: Louise Huuki --- R/layer_stat_cor_plot.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 845954c5..99a315c2 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -12,9 +12,9 @@ #' [annotate_registered_clusters()]. #' #' @param cor_stats_layer The output of [layer_stat_cor()]. -#' @param color_max A `numeric(1)` specifying the highest correlation value for +#' @param max A `numeric(1)` specifying the highest correlation value for #' the color scale (should be between 0 and 1). -#' @param color_min A `numeric(1)` specifying the lowest correlation value for +#' @param min A `numeric(1)` specifying the lowest correlation value for #' the color scale (should be between 0 and -1). #' @param color_scale A `character` vector specifying the color scale for the #' fill of the heatmap, defaults to classic purple -> green. @@ -91,8 +91,8 @@ #' cluster_columns = FALSE) #' layer_stat_cor_plot <- function(cor_stats_layer, - color_max = max(cor_stats_layer), - color_min = min(cor_stats_layer), + max = max(cor_stats_layer), + min = min(cor_stats_layer), color_scale = RColorBrewer::brewer.pal(7, "PRGn"), query_colors = NULL, reference_colors = NULL, @@ -101,7 +101,7 @@ layer_stat_cor_plot <- function(cor_stats_layer, ){ ## define color pallet - theSeq = seq(color_min, color_max, by = 0.01) + theSeq = seq(min, max, by = 0.01) my.col = grDevices::colorRampPalette(color_scale)(length(theSeq)) # ## query annotations on row From d817ce6c0256f111df28a9bf68faf2a0b00830c3 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 11:37:15 -0500 Subject: [PATCH 233/259] Reformat code so it's under 80 chars per line Co-authored-by: Louise Huuki --- R/layer_stat_cor_plot.R | 73 +++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 99a315c2..b1771991 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -2,10 +2,10 @@ #' #' This function makes a ComplexHeatmap from the correlation matrix #' between a reference and query modeling statistics from [layer_stat_cor()]. -#' For example, between the query statistics from a set of cell cluster/types derived -#' from scRNA-seq or snRNA-seq data (among other types) and the reference layer -#' statistics from the Human DLPFC Visium data (when using the default -#' arguments). +#' For example, between the query statistics from a set of cell cluster/types +#' derived from scRNA-seq or snRNA-seq data (among other types) and the +#' reference layer statistics from the Human DLPFC Visium data (when using the +#' default arguments). #' #' Includes functionality to add color annotations, #' (helpful to match to colors in Visium spot plots), and annotations from @@ -22,13 +22,16 @@ #' row annotations. #' @param reference_colors named `character` vector of colors, Adds colors to #' reference column annotations. -#' @param annotation annotation data.frame output of [annotate_registered_clusters()], -#' adds 'X' for good confidence annotations, '*' for poor confidence. -#' @param ... Additional parameters passed to [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] -#' ex. `cluster_rows` and `cluster_columns`. +#' @param annotation annotation data.frame output of +#' [annotate_registered_clusters()], adds 'X' for good confidence annotations, +#' '*' for poor confidence. +#' @param ... Additional parameters passed to +#' [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()] such as `cluster_rows` +#' and `cluster_columns`. #' #' -#' @return ([Heatmap-class][ComplexHeatmap::Heatmap-class]) plot of t-stat correlations +#' @return ([Heatmap-class][ComplexHeatmap::Heatmap-class]) plot of t-stat +#' correlations #' @export #' @author Louise Huuki-Myers #' @family Layer correlation functions @@ -45,11 +48,16 @@ #' } #' #' ## querey spatailDLPFC modeling -#' query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") +#' query_modeling_results <- fetch_data( +#' type = "spatialDLPFC_Visium_modeling_results" +#' ) #' #' ## extract t-statics and rename -#' registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] -#' colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) +#' registration_t_stats <- query_modeling_results$enrichment[, +#' grep("^t_stat", colnames(query_modeling_results$enrichment))] +#' colnames(registration_t_stats) <- gsub( +#' "^t_stat_", "", colnames(registration_t_stats) +#' ) #' #' ## Compute the correlations #' cor_stats_layer <- layer_stat_cor( @@ -64,31 +72,48 @@ #' layer_stat_cor_plot(cor_stats_layer) #' #' ## add colors -#' ## add libd_layer_colors to refrence Human Pilot layers +#' ## add libd_layer_colors to reference Human Pilot layers #' layer_stat_cor_plot(cor_stats_layer, reference_colors = libd_layer_colors) #' #' ## supply polychrome colors to query clusters -#' cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') +#' cluster_colors <- c( +#' '#5A5156', +#' '#E4E1E3', +#' '#F6222E', +#' '#FE00FA', +#' '#16FF32', +#' '#3283FE', +#' '#FEAF16', +#' '#B00068', +#' '#1CFFCE' +#' ) #' names(cluster_colors) <- rownames(cor_stats_layer) #' #' layer_stat_cor_plot(cor_stats_layer, -#' query_colors = cluster_colors, -#' reference_colors = libd_layer_colors) +#' query_colors = cluster_colors, +#' reference_colors = libd_layer_colors) #' #' ## Apply additional ComplexHeatmap param -#' layer_stat_cor_plot(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) +#' layer_stat_cor_plot(cor_stats_layer, +#' cluster_rows = FALSE, +#' cluster_columns = FALSE) #' #' ## Add annotation -#' annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) +#' annotation_df <- annotate_registered_clusters( +#' cor_stats_layer, +#' confidence_threshold = .55 +#' ) #' layer_stat_cor_plot(cor_stats_layer, annotation = annotation_df) #' #' ## All together -#' layer_stat_cor_plot(cor_stats_layer, -#' query_colors = cluster_colors, -#' reference_colors = libd_layer_colors, -#' annotation = annotation_df, -#' cluster_rows = FALSE, -#' cluster_columns = FALSE) +#' layer_stat_cor_plot( +#' cor_stats_layer, +#' query_colors = cluster_colors, +#' reference_colors = libd_layer_colors, +#' annotation = annotation_df, +#' cluster_rows = FALSE, +#' cluster_columns = FALSE +#' ) #' layer_stat_cor_plot <- function(cor_stats_layer, max = max(cor_stats_layer), From 55a2bfbd32010be342d288986d46187e1ede9e10 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 11:56:26 -0500 Subject: [PATCH 234/259] We updated layer_stat_cor() to handle the output of registration_wrapper() (aka registration_stats_enrichment() ) without having to reformat the inputs before using this function. We also updated the documentation. Co-authored-by: Louise Huuki --- R/layer_stat_cor.R | 30 ++++++++++++++++++++++++------ R/layer_stat_cor_plot.R | 13 +++---------- R/sig_genes_extract.R | 3 ++- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index f484c912..247c412d 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -1,19 +1,24 @@ #' Layer modeling correlation of statistics #' -#' @param stats A data.frame where the row names are Ensembl gene IDs, the -#' column names are labels for clusters of cells or cell types, and where +#' @param stats A query `data.frame` where the row names are ENSEMBL gene IDs, +#' the column names are labels for clusters of cells or cell types, and where #' each cell contains the given statistic for that gene and cell type. These #' statistics should be computed similarly to the modeling results from #' the data we provide. For example, like the `enrichment` t-statistics that #' are derived from comparing one layer against the rest. The `stats` will be -#' matched and then correlated with our statistics. +#' matched and then correlated with the reference statistics. +#' +#' If using the output of `registration_wrapper()` then use `$enrichment` to +#' access the results from `registration_stats_enrichment()`. This function will +#' automatically extract the statistics and assign the ENSEMBL gene IDs to the +#' row names of the query matrix. #' @inheritParams sig_genes_extract #' @param top_n An `integer(1)` specifying whether to filter to the top n marker #' genes. The default is `NULL` in which case no filtering is done. #' -#' @return A correlation matrix between `stats` and our statistics using only -#' the Ensembl gene IDs present in both tables. The columns are sorted using -#' a hierarchical cluster. +#' @return A correlation matrix between the query `stats` and the reference +#' statistics using only the ENSEMBL gene IDs present in both tables. +#' The columns are sorted using hierarchical clustering. #' #' @export #' @importFrom stats cor dist hclust @@ -62,6 +67,19 @@ layer_stat_cor <- colnames(tstats) <- gsub("[f|t]_stat_", "", colnames(tstats)) + ## Use the 'ensembl' column for gene names if present in 'stats' + if ("ensembl" %in% colnames(stats)) { + rownames(stats) <- stats$ensembl + } + + ## Do the same for stats + if (any(grepl("[f|t]_stat_", colnames(stats)))) { + stats <- + stats[, grep("[f|t]_stat_", colnames(stats))] + colnames(stats) <- + gsub("[f|t]_stat_", "", colnames(stats)) + } + if (reverse) { tstats <- tstats * -1 colnames(tstats) <- diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index b1771991..4a177a2e 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -47,28 +47,21 @@ #' modeling_results <- fetch_data(type = "modeling_results") #' } #' -#' ## querey spatailDLPFC modeling +#' ## query spatialDLPFC modeling results #' query_modeling_results <- fetch_data( #' type = "spatialDLPFC_Visium_modeling_results" #' ) #' -#' ## extract t-statics and rename -#' registration_t_stats <- query_modeling_results$enrichment[, -#' grep("^t_stat", colnames(query_modeling_results$enrichment))] -#' colnames(registration_t_stats) <- gsub( -#' "^t_stat_", "", colnames(registration_t_stats) -#' ) -#' #' ## Compute the correlations #' cor_stats_layer <- layer_stat_cor( -#' stats = registration_t_stats, +#' stats = query_modeling_results$enrichment, #' modeling_results, #' model_type = "enrichment" #' ) #' #' ## Visualize the correlation matrix #' -#' ## most basic +#' ## Default plot with no annotations and defaults for ComplexHeatmap() #' layer_stat_cor_plot(cor_stats_layer) #' #' ## add colors diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index fac5f65b..332aa70a 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -12,7 +12,8 @@ #' columns `f_stat_*` or `t_stat_*` as well as `p_value_*` and `fdr_*` plus #' `ensembl`. The column name is used to extract the statistic results, the #' p-values, and the FDR adjusted p-values. Then the `ensembl` column is used -#' for matching in some cases. See [fetch_data()] for more details. +#' for matching in some cases. See [fetch_data()] for more details. Typically +#' this is the set of reference statistics used in `layer_stat_cor()`. #' @param model_type A named element of the `modeling_results` list. By default #' that is either `enrichment` for the model that tests one human brain layer #' against the rest (one group vs the rest), `pairwise` which compares two From b73cf46b92bc5bcd73e2b37af8560a05847a1360 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 12:02:57 -0500 Subject: [PATCH 235/259] Revert "Rename color_max and color_min to max and min to match the original argument names." This reverts commit c9bbcd0bf382047ded4b1c74d648ec3d1f03be8f. --- R/layer_stat_cor_plot.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index 4a177a2e..a532e036 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -12,9 +12,9 @@ #' [annotate_registered_clusters()]. #' #' @param cor_stats_layer The output of [layer_stat_cor()]. -#' @param max A `numeric(1)` specifying the highest correlation value for +#' @param color_max A `numeric(1)` specifying the highest correlation value for #' the color scale (should be between 0 and 1). -#' @param min A `numeric(1)` specifying the lowest correlation value for +#' @param color_min A `numeric(1)` specifying the lowest correlation value for #' the color scale (should be between 0 and -1). #' @param color_scale A `character` vector specifying the color scale for the #' fill of the heatmap, defaults to classic purple -> green. @@ -109,8 +109,8 @@ #' ) #' layer_stat_cor_plot <- function(cor_stats_layer, - max = max(cor_stats_layer), - min = min(cor_stats_layer), + color_max = max(cor_stats_layer), + color_min = min(cor_stats_layer), color_scale = RColorBrewer::brewer.pal(7, "PRGn"), query_colors = NULL, reference_colors = NULL, @@ -119,7 +119,7 @@ layer_stat_cor_plot <- function(cor_stats_layer, ){ ## define color pallet - theSeq = seq(min, max, by = 0.01) + theSeq = seq(color_min, color_max, by = 0.01) my.col = grDevices::colorRampPalette(color_scale)(length(theSeq)) # ## query annotations on row From 2b5e841cfe516825b30e182de19ef3a8228a3fd4 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 12:10:18 -0500 Subject: [PATCH 236/259] Use get_colors() in the example --- R/layer_stat_cor_plot.R | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index a532e036..eb3747aa 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -68,20 +68,8 @@ #' ## add libd_layer_colors to reference Human Pilot layers #' layer_stat_cor_plot(cor_stats_layer, reference_colors = libd_layer_colors) #' -#' ## supply polychrome colors to query clusters -#' cluster_colors <- c( -#' '#5A5156', -#' '#E4E1E3', -#' '#F6222E', -#' '#FE00FA', -#' '#16FF32', -#' '#3283FE', -#' '#FEAF16', -#' '#B00068', -#' '#1CFFCE' -#' ) -#' names(cluster_colors) <- rownames(cor_stats_layer) -#' +#' ## obtain colors for the query clusters +#' cluster_colors <- get_colors(clusters = rownames(cor_stats_layer)) #' layer_stat_cor_plot(cor_stats_layer, #' query_colors = cluster_colors, #' reference_colors = libd_layer_colors) From 2fb4351ece348f5e293e6dd6ebc118bf4d20dc9d Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 12:25:51 -0500 Subject: [PATCH 237/259] Ran code from dev/04_update.R --- R/add10xVisiumAnalysis.R | 5 +- R/add_images.R | 13 +- R/annotate_registered_clusters.R | 26 ++-- R/app_server.R | 149 ++++++++++--------- R/check_sce.R | 69 +++++---- R/check_spe.R | 15 +- R/fetch_data.R | 47 +++--- R/frame_limits.R | 21 ++- R/gene_set_enrichment.R | 11 +- R/gene_set_enrichment_plot.R | 23 ++- R/geom_spatial.R | 17 ++- R/get_colors.R | 3 +- R/layer_boxplot.R | 27 ++-- R/layer_matrix_plot.R | 27 ++-- R/layer_stat_cor.R | 17 ++- R/layer_stat_cor_plot.R | 175 ++++++++++++----------- R/read10xVisiumAnalysis.R | 5 +- R/read10xVisiumWrapper.R | 29 ++-- R/registration_model.R | 7 +- R/registration_pseudobulk.R | 13 +- R/registration_stats_anova.R | 17 ++- R/registration_stats_enrichment.R | 15 +- R/registration_stats_pairwise.R | 15 +- R/registration_wrapper.R | 19 +-- R/run_app.R | 99 ++++++------- R/sig_genes_extract.R | 11 +- R/sig_genes_extract_all.R | 7 +- R/sort_clusters.R | 3 +- R/vis_clus.R | 51 +++---- R/vis_clus_p.R | 25 ++-- R/vis_gene.R | 33 ++--- R/vis_gene_p.R | 27 ++-- man/check_modeling_results.Rd | 3 +- man/gene_set_enrichment.Rd | 3 +- man/get_colors.Rd | 3 +- man/layer_stat_cor.Rd | 20 ++- man/layer_stat_cor_plot.Rd | 76 +++++----- man/run_app.Rd | 3 +- man/sig_genes_extract.Rd | 3 +- man/sig_genes_extract_all.Rd | 3 +- man/sort_clusters.Rd | 3 +- tests/testthat/test-multi_gene_z_score.R | 10 +- 42 files changed, 591 insertions(+), 557 deletions(-) diff --git a/R/add10xVisiumAnalysis.R b/R/add10xVisiumAnalysis.R index dbe49f86..de4f5fee 100644 --- a/R/add10xVisiumAnalysis.R +++ b/R/add10xVisiumAnalysis.R @@ -29,9 +29,8 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -add10xVisiumAnalysis <- function( - spe, - visium_analysis) { +add10xVisiumAnalysis <- function(spe, + visium_analysis) { col_info <- colData(spe) barcode_present <- "barcode" %in% colnames(col_info) if (!barcode_present) { diff --git a/R/add_images.R b/R/add_images.R index e7b09e5c..bfdddbe5 100644 --- a/R/add_images.R +++ b/R/add_images.R @@ -43,13 +43,12 @@ #' )) #' } add_images <- - function( - spe, - image_dir, - image_pattern, - image_id_current = "lowres", - image_id = image_pattern, - image_paths = locate_images(spe, image_dir, image_pattern)) { + function(spe, + image_dir, + image_pattern, + image_id_current = "lowres", + image_id = image_pattern, + image_paths = locate_images(spe, image_dir, image_pattern)) { stopifnot(length(names(image_paths)) > 0) stopifnot(all(names(image_paths) %in% unique(spe$sample_id))) stopifnot(!any(duplicated(names(image_paths)))) diff --git a/R/annotate_registered_clusters.R b/R/annotate_registered_clusters.R index 865343c4..505ea600 100644 --- a/R/annotate_registered_clusters.R +++ b/R/annotate_registered_clusters.R @@ -48,10 +48,9 @@ #' ## More relaxed merging threshold #' annotate_registered_clusters(cor_stats_layer, cutoff_merge_ratio = 1) annotate_registered_clusters <- - function( - cor_stats_layer, - confidence_threshold = 0.25, - cutoff_merge_ratio = 0.25) { + function(cor_stats_layer, + confidence_threshold = 0.25, + cutoff_merge_ratio = 0.25) { annotated <- apply(cor_stats_layer, 1, @@ -76,25 +75,24 @@ annotate_registered_clusters <- result$layer_label, ifelse(result$layer_confidence == "good", "", "*") ) - + ## Add simplified label for WM/Layer annotations if (all(colnames(cor_stats_layer) %in% c("WM", paste0("Layer", seq_len(6))))) { result$layer_label_simple <- result$layer_label ## Simplify names when working with the default data - result$layer_label_simple <- gsub("ayer", "", result$layer_label_simple ) - result$layer_label_simple <- gsub("\\/L", "\\/", result$layer_label_simple ) - result$layer_label_simple <- gsub("^WM\\/", "WM\\/L", result$layer_label_simple ) + result$layer_label_simple <- gsub("ayer", "", result$layer_label_simple) + result$layer_label_simple <- gsub("\\/L", "\\/", result$layer_label_simple) + result$layer_label_simple <- gsub("^WM\\/", "WM\\/L", result$layer_label_simple) } - + return(result) } annotate_registered_cluster <- - function( - remaining, - label = "", - current = NULL, - cutoff_merge_ratio = 0.25) { + function(remaining, + label = "", + current = NULL, + cutoff_merge_ratio = 0.25) { ## Filter negative correlations remaining <- remaining[remaining > 0] diff --git a/R/app_server.R b/R/app_server.R index ff5f7f64..05914017 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -224,74 +224,80 @@ app_server <- function(input, output, session) { }) static_gene <- reactive({ - gene_warning = NULL - withCallingHandlers({ - p <- vis_gene( - spe, - sampleid = input$sample, - geneid = input$geneid, - multi_gene_method = input$multi_gene_method, - assayname = input$assayname, - minCount = input$minCount, - cont_colors = cont_colors(), - image_id = input$imageid, - alpha = input$alphalevel, - point_size = input$pointsize, - auto_crop = input$auto_crop, - is_stitched = is_stitched - ) - if (!input$side_by_side_gene) { - p_result = p - } else { - p_no_spots <- p - p_no_spots$layers[[2]] <- NULL - - p_no_spatial <- p - p_no_spatial$layers[[1]] <- NULL - p_result = cowplot::plot_grid( - plotlist = list( - p_no_spots, - p_no_spatial + ggplot2::theme(legend.position = "none") - ), - nrow = 1, - ncol = 2 + gene_warning <- NULL + withCallingHandlers( + { + p <- vis_gene( + spe, + sampleid = input$sample, + geneid = input$geneid, + multi_gene_method = input$multi_gene_method, + assayname = input$assayname, + minCount = input$minCount, + cont_colors = cont_colors(), + image_id = input$imageid, + alpha = input$alphalevel, + point_size = input$pointsize, + auto_crop = input$auto_crop, + is_stitched = is_stitched ) + if (!input$side_by_side_gene) { + p_result <- p + } else { + p_no_spots <- p + p_no_spots$layers[[2]] <- NULL + + p_no_spatial <- p + p_no_spatial$layers[[1]] <- NULL + p_result <- cowplot::plot_grid( + plotlist = list( + p_no_spots, + p_no_spatial + ggplot2::theme(legend.position = "none") + ), + nrow = 1, + ncol = 2 + ) + } + }, + warning = function(w) { + gene_warning <<- conditionMessage(w) + invokeRestart("muffleWarning") } - }, warning = function(w) { - gene_warning <<- conditionMessage(w) - invokeRestart("muffleWarning") - }) + ) return(list(p = p_result, gene_warning = gene_warning)) }) static_gene_grid <- reactive({ input$gene_grid_update - gene_grid_warnings = NULL - withCallingHandlers({ - plots <- - vis_grid_gene( - spe, - geneid = isolate(input$geneid), - multi_gene_method = input$multi_gene_method, - assayname = isolate(input$assayname), - minCount = isolate(input$minCount), - return_plots = TRUE, - spatial = isolate(input$grid_spatial_gene), - cont_colors = isolate(cont_colors()), - image_id = isolate(input$imageid), - alpha = isolate(input$alphalevel), - point_size = isolate(input$pointsize), - sample_order = isolate(input$gene_grid_samples), - auto_crop = isolate(input$auto_crop), - is_stitched = is_stitched - ) - }, warning = function(w) { - gene_grid_warnings <<- c(gene_grid_warnings, conditionMessage(w)) - invokeRestart("muffleWarning") - }) + gene_grid_warnings <- NULL + withCallingHandlers( + { + plots <- + vis_grid_gene( + spe, + geneid = isolate(input$geneid), + multi_gene_method = input$multi_gene_method, + assayname = isolate(input$assayname), + minCount = isolate(input$minCount), + return_plots = TRUE, + spatial = isolate(input$grid_spatial_gene), + cont_colors = isolate(cont_colors()), + image_id = isolate(input$imageid), + alpha = isolate(input$alphalevel), + point_size = isolate(input$pointsize), + sample_order = isolate(input$gene_grid_samples), + auto_crop = isolate(input$auto_crop), + is_stitched = is_stitched + ) + }, + warning = function(w) { + gene_grid_warnings <<- c(gene_grid_warnings, conditionMessage(w)) + invokeRestart("muffleWarning") + } + ) - p_result = cowplot::plot_grid( + p_result <- cowplot::plot_grid( plotlist = plots, nrow = isolate(input$gene_grid_nrow), ncol = isolate(input$gene_grid_ncol) @@ -455,7 +461,7 @@ app_server <- function(input, output, session) { height = 8, width = 8 * ifelse(input$side_by_side_gene, 2, 1) ) - print(static_gene()[['p']]) + print(static_gene()[["p"]]) dev.off() } ) @@ -483,7 +489,7 @@ app_server <- function(input, output, session) { height = 8 * isolate(input$gene_grid_nrow), width = 8 * isolate(input$gene_grid_ncol) ) - print(static_gene_grid()[['p']]) + print(static_gene_grid()[["p"]]) dev.off() } ) @@ -548,7 +554,7 @@ app_server <- function(input, output, session) { output$gene <- renderPlot( { - static_gene()[['p']] + static_gene()[["p"]] }, width = function() { 600 * ifelse(input$side_by_side_gene, 2, 1) @@ -560,9 +566,12 @@ app_server <- function(input, output, session) { # Since 'static_gene()' is invoked twice (once also in the assignment # of 'output$gene'), we silence any errors that occur in this second # invocation to not duplicate error messages - this_warning = NULL - temp = try( - { this_warning = static_gene()[['gene_warning']] }, silent = TRUE + this_warning <- NULL + temp <- try( + { + this_warning <- static_gene()[["gene_warning"]] + }, + silent = TRUE ) if (!is.null(this_warning)) { @@ -585,7 +594,7 @@ app_server <- function(input, output, session) { output$gene_grid <- renderPlot( { - print(static_gene_grid()[['p']]) + print(static_gene_grid()[["p"]]) }, width = "auto", height = "auto" @@ -595,9 +604,11 @@ app_server <- function(input, output, session) { # Since 'static_gene_grid()' is invoked twice (once also in the # assignment of 'output$gene_grid'), we silence any errors that occur # in this second invocation to not duplicate error messages - these_warnings = NULL - temp = try( - { these_warnings = static_gene_grid()[['gene_grid_warnings']] }, + these_warnings <- NULL + temp <- try( + { + these_warnings <- static_gene_grid()[["gene_grid_warnings"]] + }, silent = TRUE ) diff --git a/R/check_sce.R b/R/check_sce.R index 1d625342..0d17423b 100644 --- a/R/check_sce.R +++ b/R/check_sce.R @@ -24,41 +24,40 @@ #' ## Check the object #' check_sce(sce_example) #' } -check_sce <- function( - sce, - variables = c( - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "spatialLIBD", - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio", - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - )) { +check_sce <- function(sce, + variables = c( + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "spatialLIBD", + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio", + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + )) { ## Should be a SingleCellExperiment object stopifnot(is(sce, "SingleCellExperiment")) diff --git a/R/check_spe.R b/R/check_spe.R index d0344daa..47de3c0a 100644 --- a/R/check_spe.R +++ b/R/check_spe.R @@ -25,14 +25,13 @@ #' ## Check the object #' check_spe(spe) #' } -check_spe <- function( - spe, - variables = c( - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - )) { +check_spe <- function(spe, + variables = c( + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + )) { ## Should be a SpatialExperiment object stopifnot(is(spe, "SpatialExperiment")) diff --git a/R/fetch_data.R b/R/fetch_data.R index 334c553a..97a75a8b 100644 --- a/R/fetch_data.R +++ b/R/fetch_data.R @@ -84,29 +84,30 @@ #' #> 172.28 MB #' } fetch_data <- - function(type = c( - "sce", - "sce_layer", - "modeling_results", - "sce_example", - "spe", - "spatialDLPFC_Visium", - "spatialDLPFC_Visium_example_subset", - "spatialDLPFC_Visium_pseudobulk", - "spatialDLPFC_Visium_modeling_results", - "spatialDLPFC_Visium_SPG", - "spatialDLPFC_snRNAseq", - "Visium_SPG_AD_Visium_wholegenome_spe", - "Visium_SPG_AD_Visium_targeted_spe", - "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", - "Visium_SPG_AD_Visium_wholegenome_modeling_results", - "visiumStitched_brain_spe", - "visiumStitched_brain_spaceranger", - "visiumStitched_brain_Fiji_out" - ), - destdir = tempdir(), - eh = ExperimentHub::ExperimentHub(), - bfc = BiocFileCache::BiocFileCache()) { + function( + type = c( + "sce", + "sce_layer", + "modeling_results", + "sce_example", + "spe", + "spatialDLPFC_Visium", + "spatialDLPFC_Visium_example_subset", + "spatialDLPFC_Visium_pseudobulk", + "spatialDLPFC_Visium_modeling_results", + "spatialDLPFC_Visium_SPG", + "spatialDLPFC_snRNAseq", + "Visium_SPG_AD_Visium_wholegenome_spe", + "Visium_SPG_AD_Visium_targeted_spe", + "Visium_SPG_AD_Visium_wholegenome_pseudobulk_spe", + "Visium_SPG_AD_Visium_wholegenome_modeling_results", + "visiumStitched_brain_spe", + "visiumStitched_brain_spaceranger", + "visiumStitched_brain_Fiji_out" + ), + destdir = tempdir(), + eh = ExperimentHub::ExperimentHub(), + bfc = BiocFileCache::BiocFileCache()) { ## Some variables sce <- sce_layer <- modeling_results <- sce_sub <- spe <- NULL diff --git a/R/frame_limits.R b/R/frame_limits.R index 320cc643..b22b5c8a 100644 --- a/R/frame_limits.R +++ b/R/frame_limits.R @@ -37,17 +37,16 @@ #' } #' frame_limits <- - function( - spe, - sampleid, - image_id = "lowres", - visium_grid = list( - row_min = 0, - row_max = 77, - col_min = 0, - col_max = 127, - fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 - )) { + function(spe, + sampleid, + image_id = "lowres", + visium_grid = list( + row_min = 0, + row_max = 77, + col_min = 0, + col_max = 127, + fiducial_vs_capture_edge = (8 - 6.5) * 1000 / 2 / 100 + )) { ## Subset the info we need for the particular sample d <- as.data.frame(cbind(colData(spe), SpatialExperiment::spatialCoords(spe))[spe$sample_id == sampleid, ], diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index e6b6a63d..1accea28 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -58,12 +58,11 @@ #' ## Explore the results #' asd_sfari_enrichment gene_set_enrichment <- - function( - gene_list, - fdr_cut = 0.1, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE) { + function(gene_list, + fdr_cut = 0.1, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE) { model_results <- modeling_results[[model_type]] ## Keep only the genes present diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index c155e672..4ccbfcbc 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -84,18 +84,17 @@ #' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), #' ) gene_set_enrichment_plot <- - function( - enrichment, - xlabs = unique(enrichment$ID), - PThresh = 12, - ORcut = 3, - enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { + function(enrichment, + xlabs = unique(enrichment$ID), + PThresh = 12, + ORcut = 3, + enrichOnly = FALSE, + layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + cex = 1.2) { ## Re-order and shorten names if they match our data if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { enrichment$test <- diff --git a/R/geom_spatial.R b/R/geom_spatial.R index 965db758..64f00cc3 100644 --- a/R/geom_spatial.R +++ b/R/geom_spatial.R @@ -58,15 +58,14 @@ #' ## Clean up #' rm(spe_sub) #' } -geom_spatial <- function( - mapping = NULL, - data = NULL, - stat = "identity", - position = "identity", - na.rm = FALSE, - show.legend = NA, - inherit.aes = FALSE, - ...) { +geom_spatial <- function(mapping = NULL, + data = NULL, + stat = "identity", + position = "identity", + na.rm = FALSE, + show.legend = NA, + inherit.aes = FALSE, + ...) { ## To avoid a NOTE on R CMD check ggname <- function(prefix, grob) { grob$name <- grid::grobName(grob, prefix) diff --git a/R/get_colors.R b/R/get_colors.R index 93b53351..9ed0c5e1 100644 --- a/R/get_colors.R +++ b/R/get_colors.R @@ -37,7 +37,8 @@ #' log_var <- sample(c(TRUE, FALSE, NA), #' 1000, #' replace = TRUE, -#' prob = c(0.3, 0.15, 0.55)) +#' prob = c(0.3, 0.15, 0.55) +#' ) #' log_var_sorted <- sort_clusters(log_var) #' ## A color does get assigned to 'NA', but will be overwritten by #' ## 'na_color' passed to `vis_clus_p()` and related functions. diff --git a/R/layer_boxplot.R b/R/layer_boxplot.R index 6a671a5e..345d5499 100644 --- a/R/layer_boxplot.R +++ b/R/layer_boxplot.R @@ -114,20 +114,19 @@ #' col_high_point = "firebrick4", #' cex = 3 #' ) -layer_boxplot <- function( - i = 1, - sig_genes = sig_genes_extract(), - short_title = TRUE, - sce_layer = fetch_data(type = "sce_layer"), - col_bkg_box = "grey80", - col_bkg_point = "grey40", - col_low_box = "violet", - col_low_point = "darkviolet", - col_high_box = "skyblue", - col_high_point = "dodgerblue4", - cex = 2, - group_var = "layer_guess_reordered_short", - assayname = "logcounts") { +layer_boxplot <- function(i = 1, + sig_genes = sig_genes_extract(), + short_title = TRUE, + sce_layer = fetch_data(type = "sce_layer"), + col_bkg_box = "grey80", + col_bkg_point = "grey40", + col_low_box = "violet", + col_low_point = "darkviolet", + col_high_box = "skyblue", + col_high_point = "dodgerblue4", + cex = 2, + group_var = "layer_guess_reordered_short", + assayname = "logcounts") { ## Extract the logcounts (default) mat <- assay(sce_layer, assayname) diff --git a/R/layer_matrix_plot.R b/R/layer_matrix_plot.R index 4a44fd18..f1530fb1 100644 --- a/R/layer_matrix_plot.R +++ b/R/layer_matrix_plot.R @@ -55,20 +55,19 @@ #' cex = 2 #' ) layer_matrix_plot <- - function( - matrix_values, - matrix_labels = NULL, - xlabs = NULL, - layerHeights = NULL, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - breaks = NULL, - axis.args = NULL, - srt = 45, - mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, - cex = 1.2) { + function(matrix_values, + matrix_labels = NULL, + xlabs = NULL, + layerHeights = NULL, + mypal = c( + "white", + grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) + ), + breaks = NULL, + axis.args = NULL, + srt = 45, + mar = c(8, 4 + (max(nchar(rownames(matrix_values))) %/% 3) * 0.5, 4, 2) + 0.1, + cex = 1.2) { ## Create some default values in case the user didn't specify them if (is.null(xlabs)) { if (is.null(colnames(matrix_values))) { diff --git a/R/layer_stat_cor.R b/R/layer_stat_cor.R index 247c412d..eb21228a 100644 --- a/R/layer_stat_cor.R +++ b/R/layer_stat_cor.R @@ -54,12 +54,11 @@ #' top_n = 10 #' )) layer_stat_cor <- - function( - stats, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - top_n = NULL) { + function(stats, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + top_n = NULL) { model_results <- modeling_results[[model_type]] tstats <- @@ -75,9 +74,9 @@ layer_stat_cor <- ## Do the same for stats if (any(grepl("[f|t]_stat_", colnames(stats)))) { stats <- - stats[, grep("[f|t]_stat_", colnames(stats))] - colnames(stats) <- - gsub("[f|t]_stat_", "", colnames(stats)) + stats[, grep("[f|t]_stat_", colnames(stats))] + colnames(stats) <- + gsub("[f|t]_stat_", "", colnames(stats)) } if (reverse) { diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index eb3747aa..eed0daa8 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -72,12 +72,14 @@ #' cluster_colors <- get_colors(clusters = rownames(cor_stats_layer)) #' layer_stat_cor_plot(cor_stats_layer, #' query_colors = cluster_colors, -#' reference_colors = libd_layer_colors) +#' reference_colors = libd_layer_colors +#' ) #' #' ## Apply additional ComplexHeatmap param #' layer_stat_cor_plot(cor_stats_layer, #' cluster_rows = FALSE, -#' cluster_columns = FALSE) +#' cluster_columns = FALSE +#' ) #' #' ## Add annotation #' annotation_df <- annotate_registered_clusters( @@ -97,96 +99,95 @@ #' ) #' layer_stat_cor_plot <- function(cor_stats_layer, - color_max = max(cor_stats_layer), - color_min = min(cor_stats_layer), - color_scale = RColorBrewer::brewer.pal(7, "PRGn"), - query_colors = NULL, - reference_colors = NULL, - annotation = NULL, - ... -){ - - ## define color pallet - theSeq = seq(color_min, color_max, by = 0.01) - my.col = grDevices::colorRampPalette(color_scale)(length(theSeq)) - - # ## query annotations on row - if(!is.null(query_colors)){ - - stopifnot(all(rownames(cor_stats_layer) %in% names(query_colors))) - query_colors <- query_colors[rownames(cor_stats_layer)] - - - query_row_annotation <- ComplexHeatmap::rowAnnotation( - " " = rownames(cor_stats_layer), - col = list(" " = query_colors), - show_legend = FALSE) - - } else query_row_annotation <- NULL - - ## reference annotation on bottom - if(!is.null(reference_colors)){ - stopifnot(all(colnames(cor_stats_layer) %in% names(reference_colors))) - reference_colors <- reference_colors[colnames(cor_stats_layer)] - - ref_col_annotation <- ComplexHeatmap::columnAnnotation( - " " = colnames(cor_stats_layer), - col = list(" " = reference_colors), - show_legend = FALSE - ) - } else ref_col_annotation <- NULL - - ## add annotation - if(!is.null(annotation)){ - anno_matrix <- create_annotation_matrix(annotation, cor_stats_layer) + color_max = max(cor_stats_layer), + color_min = min(cor_stats_layer), + color_scale = RColorBrewer::brewer.pal(7, "PRGn"), + query_colors = NULL, + reference_colors = NULL, + annotation = NULL, + ...) { + ## define color pallet + theSeq <- seq(color_min, color_max, by = 0.01) + my.col <- grDevices::colorRampPalette(color_scale)(length(theSeq)) + + # ## query annotations on row + if (!is.null(query_colors)) { + stopifnot(all(rownames(cor_stats_layer) %in% names(query_colors))) + query_colors <- query_colors[rownames(cor_stats_layer)] + + + query_row_annotation <- ComplexHeatmap::rowAnnotation( + " " = rownames(cor_stats_layer), + col = list(" " = query_colors), + show_legend = FALSE + ) + } else { + query_row_annotation <- NULL + } + + ## reference annotation on bottom + if (!is.null(reference_colors)) { + stopifnot(all(colnames(cor_stats_layer) %in% names(reference_colors))) + reference_colors <- reference_colors[colnames(cor_stats_layer)] + + ref_col_annotation <- ComplexHeatmap::columnAnnotation( + " " = colnames(cor_stats_layer), + col = list(" " = reference_colors), + show_legend = FALSE + ) + } else { + ref_col_annotation <- NULL + } + + ## add annotation + if (!is.null(annotation)) { + anno_matrix <- create_annotation_matrix(annotation, cor_stats_layer) + + ## plot heatmap + return( + ComplexHeatmap::Heatmap( + matrix = cor_stats_layer, + col = my.col, + name = "Cor", + bottom_annotation = ref_col_annotation, + right_annotation = query_row_annotation, + cell_fun = function(j, i, x, y, width, height, fill) { + grid.text(anno_matrix[i, j], x, y, gp = gpar(fontsize = 10)) + }, + ... + ) + ) + } ## plot heatmap return( - ComplexHeatmap::Heatmap( - matrix = cor_stats_layer, - col = my.col, - name = "Cor", - bottom_annotation = ref_col_annotation, - right_annotation = query_row_annotation, - cell_fun = function(j, i, x, y, width, height, fill) { - grid.text(anno_matrix[i, j], x, y, gp = gpar(fontsize = 10)) - }, - ... - )) - } - - ## plot heatmap - return( - ComplexHeatmap::Heatmap( - matrix = cor_stats_layer, - col = my.col, - name = "Cor", - bottom_annotation = ref_col_annotation, - right_annotation = query_row_annotation, - ... - )) - - + ComplexHeatmap::Heatmap( + matrix = cor_stats_layer, + col = my.col, + name = "Cor", + bottom_annotation = ref_col_annotation, + right_annotation = query_row_annotation, + ... + ) + ) } -create_annotation_matrix <- function(annotation_df, cor_stats_layer){ - - anno_list <- lapply(rownames(cor_stats_layer), - function(cluster){ - # look up confidence - confidence <- annotation_df[match(cluster, annotation_df$cluster),"layer_confidence"] - sym <- ifelse(confidence=="good", "X","*") - # match annotations - anno <- annotation_df[match(cluster, annotation_df$cluster),"layer_label"] - return(ifelse(unlist(lapply(colnames(cor_stats_layer), grepl, anno)),sym,"")) - }) +create_annotation_matrix <- function(annotation_df, cor_stats_layer) { + anno_list <- lapply( + rownames(cor_stats_layer), + function(cluster) { + # look up confidence + confidence <- annotation_df[match(cluster, annotation_df$cluster), "layer_confidence"] + sym <- ifelse(confidence == "good", "X", "*") + # match annotations + anno <- annotation_df[match(cluster, annotation_df$cluster), "layer_label"] + return(ifelse(unlist(lapply(colnames(cor_stats_layer), grepl, anno)), sym, "")) + } + ) - anno_matrix <- t(data.frame(anno_list)) - rownames(anno_matrix) <- rownames(cor_stats_layer) - colnames(anno_matrix) <- colnames(cor_stats_layer) + anno_matrix <- t(data.frame(anno_list)) + rownames(anno_matrix) <- rownames(cor_stats_layer) + colnames(anno_matrix) <- colnames(cor_stats_layer) - return(anno_matrix) + return(anno_matrix) } - - - diff --git a/R/read10xVisiumAnalysis.R b/R/read10xVisiumAnalysis.R index 70bc49ac..ef76f1d0 100644 --- a/R/read10xVisiumAnalysis.R +++ b/R/read10xVisiumAnalysis.R @@ -24,8 +24,9 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumAnalysis <- function(samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { +read10xVisiumAnalysis <- function( + samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples)))) { # check sample identifiers if (is.null(sids <- names(samples))) { if (is.null(sids <- sample_id)) { diff --git a/R/read10xVisiumWrapper.R b/R/read10xVisiumWrapper.R index 6bf42111..8c64f060 100644 --- a/R/read10xVisiumWrapper.R +++ b/R/read10xVisiumWrapper.R @@ -44,17 +44,16 @@ #' #' ## Note that ?SpatialExperiment::read10xVisium doesn't include all the files #' ## we need to illustrate read10xVisiumWrapper(). -read10xVisiumWrapper <- function( - samples = "", - sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), - type = c("HDF5", "sparse"), - data = c("filtered", "raw"), - images = c("lowres", "hires", "detected", "aligned"), - load = TRUE, - reference_gtf = NULL, - chrM = "chrM", - gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), - verbose = TRUE) { +read10xVisiumWrapper <- function(samples = "", + sample_id = paste0("sample", sprintf("%02d", seq_along(samples))), + type = c("HDF5", "sparse"), + data = c("filtered", "raw"), + images = c("lowres", "hires", "detected", "aligned"), + load = TRUE, + reference_gtf = NULL, + chrM = "chrM", + gtf_cols = c("source", "type", "gene_id", "gene_version", "gene_name", "gene_type"), + verbose = TRUE) { stopifnot(all(c("gene_name", "gene_id") %in% gtf_cols)) if (missing(reference_gtf)) { @@ -66,10 +65,10 @@ read10xVisiumWrapper <- function( # For recent spaceranger versions (3.0.0+?) if (length(reference_path) == 0) { - reference_path = sub( - '.*--transcriptome=(\\S*).*', - '\\1', - web[grep('--transcriptome=', web)] + reference_path <- sub( + ".*--transcriptome=(\\S*).*", + "\\1", + web[grep("--transcriptome=", web)] ) } reference_gtf <- list.files( diff --git a/R/registration_model.R b/R/registration_model.R index 6921dbb9..3f36260c 100644 --- a/R/registration_model.R +++ b/R/registration_model.R @@ -24,10 +24,9 @@ #' head(registration_mod) #' registration_model <- - function( - sce_pseudo, - covars = NULL, - var_registration = "registration_variable") { + function(sce_pseudo, + covars = NULL, + var_registration = "registration_variable") { ## Specify a formula without an intercept if (is.null(covars)) { mat_formula <- diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 2d859e4e..5f3c5dd2 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -51,12 +51,13 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) diff --git a/R/registration_stats_anova.R b/R/registration_stats_anova.R index d1d0b135..c899459d 100644 --- a/R/registration_stats_anova.R +++ b/R/registration_stats_anova.R @@ -50,15 +50,14 @@ #' results_anova_merged <- merge(results_anova, results_anova_nocovar) #' head(results_anova_merged) registration_stats_anova <- - function( - sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL, - suffix = "") { + function(sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL, + suffix = "") { if (is.null(covars)) { mat_formula <- eval(str2expression(paste("~", var_registration))) } else { diff --git a/R/registration_stats_enrichment.R b/R/registration_stats_enrichment.R index cd3ee182..d186547e 100644 --- a/R/registration_stats_enrichment.R +++ b/R/registration_stats_enrichment.R @@ -34,13 +34,14 @@ #' ) #' head(results_enrichment_nan) registration_stats_enrichment <- - function(sce_pseudo, - block_cor, - covars = NULL, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + block_cor, + covars = NULL, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## For each cluster, test it against the rest cluster_idx <- split(seq(along = sce_pseudo[[var_registration]]), sce_pseudo[[var_registration]]) diff --git a/R/registration_stats_pairwise.R b/R/registration_stats_pairwise.R index 09bb3ff9..afb9771a 100644 --- a/R/registration_stats_pairwise.R +++ b/R/registration_stats_pairwise.R @@ -32,13 +32,14 @@ #' ) #' head(results_pairwise_nan) registration_stats_pairwise <- - function(sce_pseudo, - registration_model, - block_cor, - var_registration = "registration_variable", - var_sample_id = "registration_sample_id", - gene_ensembl = NULL, - gene_name = NULL) { + function( + sce_pseudo, + registration_model, + block_cor, + var_registration = "registration_variable", + var_sample_id = "registration_sample_id", + gene_ensembl = NULL, + gene_name = NULL) { ## Identify which are the pairwise columns of interest (aka, don't use ## the sample-level covariates we are adjusting for) and then ## shorten the names diff --git a/R/registration_wrapper.R b/R/registration_wrapper.R index 910b929d..a5713544 100644 --- a/R/registration_wrapper.R +++ b/R/registration_wrapper.R @@ -61,15 +61,16 @@ #' names(example_modeling_results) #' lapply(example_modeling_results, head) registration_wrapper <- - function(sce, - var_registration, - var_sample_id, - covars = NULL, - gene_ensembl = NULL, - gene_name = NULL, - suffix = "", - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function( + sce, + var_registration, + var_sample_id, + covars = NULL, + gene_ensembl = NULL, + gene_name = NULL, + suffix = "", + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Change the rownames to ENSEMBL IDs rownames(sce) <- rowData(sce)[, gene_ensembl] diff --git a/R/run_app.R b/R/run_app.R index 2389d541..851045a3 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -209,55 +209,56 @@ #' is_stitched = TRUE #' ) #' } -run_app <- function(spe = fetch_data(type = "spe"), - sce_layer = fetch_data(type = "sce_layer"), - modeling_results = fetch_data(type = "modeling_results"), - sig_genes = sig_genes_extract_all( - n = nrow(sce_layer), - modeling_results = modeling_results, - sce_layer = sce_layer - ), - docs_path = system.file("app", "www", package = "spatialLIBD"), - title = "spatialLIBD", - spe_discrete_vars = c( - "spatialLIBD", - "GraphBased", - "ManualAnnotation", - "Maynard", - "Martinowich", - paste0("SNN_k50_k", 4:28), - "SpatialDE_PCA", - "SpatialDE_pool_PCA", - "HVG_PCA", - "pseudobulk_PCA", - "markers_PCA", - "SpatialDE_UMAP", - "SpatialDE_pool_UMAP", - "HVG_UMAP", - "pseudobulk_UMAP", - "markers_UMAP", - "SpatialDE_PCA_spatial", - "SpatialDE_pool_PCA_spatial", - "HVG_PCA_spatial", - "pseudobulk_PCA_spatial", - "markers_PCA_spatial", - "SpatialDE_UMAP_spatial", - "SpatialDE_pool_UMAP_spatial", - "HVG_UMAP_spatial", - "pseudobulk_UMAP_spatial", - "markers_UMAP_spatial" - ), - spe_continuous_vars = c( - "cell_count", - "sum_umi", - "sum_gene", - "expr_chrM", - "expr_chrM_ratio" - ), - default_cluster = "spatialLIBD", - auto_crop_default = TRUE, - is_stitched = FALSE, - ...) { +run_app <- function( + spe = fetch_data(type = "spe"), + sce_layer = fetch_data(type = "sce_layer"), + modeling_results = fetch_data(type = "modeling_results"), + sig_genes = sig_genes_extract_all( + n = nrow(sce_layer), + modeling_results = modeling_results, + sce_layer = sce_layer + ), + docs_path = system.file("app", "www", package = "spatialLIBD"), + title = "spatialLIBD", + spe_discrete_vars = c( + "spatialLIBD", + "GraphBased", + "ManualAnnotation", + "Maynard", + "Martinowich", + paste0("SNN_k50_k", 4:28), + "SpatialDE_PCA", + "SpatialDE_pool_PCA", + "HVG_PCA", + "pseudobulk_PCA", + "markers_PCA", + "SpatialDE_UMAP", + "SpatialDE_pool_UMAP", + "HVG_UMAP", + "pseudobulk_UMAP", + "markers_UMAP", + "SpatialDE_PCA_spatial", + "SpatialDE_pool_PCA_spatial", + "HVG_PCA_spatial", + "pseudobulk_PCA_spatial", + "markers_PCA_spatial", + "SpatialDE_UMAP_spatial", + "SpatialDE_pool_UMAP_spatial", + "HVG_UMAP_spatial", + "pseudobulk_UMAP_spatial", + "markers_UMAP_spatial" + ), + spe_continuous_vars = c( + "cell_count", + "sum_umi", + "sum_gene", + "expr_chrM", + "expr_chrM_ratio" + ), + default_cluster = "spatialLIBD", + auto_crop_default = TRUE, + is_stitched = FALSE, + ...) { ## Run the checks in the relevant order stopifnot(length(default_cluster) == 1) stopifnot(default_cluster %in% spe_discrete_vars) diff --git a/R/sig_genes_extract.R b/R/sig_genes_extract.R index 332aa70a..26562a6b 100644 --- a/R/sig_genes_extract.R +++ b/R/sig_genes_extract.R @@ -60,11 +60,12 @@ #' sce_layer = sce_layer, #' n = nrow(sce_layer) #' ) -sig_genes_extract <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - model_type = names(modeling_results)[1], - reverse = FALSE, - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + model_type = names(modeling_results)[1], + reverse = FALSE, + sce_layer = fetch_data(type = "sce_layer")) { model_results <- modeling_results[[model_type]] tstats <- diff --git a/R/sig_genes_extract_all.R b/R/sig_genes_extract_all.R index 0d68b880..d2c3c01f 100644 --- a/R/sig_genes_extract_all.R +++ b/R/sig_genes_extract_all.R @@ -27,9 +27,10 @@ #' modeling_results = modeling_results, #' sce_layer = sce_layer #' ) -sig_genes_extract_all <- function(n = 10, - modeling_results = fetch_data(type = "modeling_results"), - sce_layer = fetch_data(type = "sce_layer")) { +sig_genes_extract_all <- function( + n = 10, + modeling_results = fetch_data(type = "modeling_results"), + sce_layer = fetch_data(type = "sce_layer")) { ## Run checks since this function is run by default by run_app() ## before the checks have been run elsewhere sce_layer <- check_sce_layer(sce_layer) diff --git a/R/sort_clusters.R b/R/sort_clusters.R index f4b8563c..f9554af9 100644 --- a/R/sort_clusters.R +++ b/R/sort_clusters.R @@ -52,7 +52,8 @@ #' log_var <- sample(c(TRUE, FALSE, NA), #' 1000, #' replace = TRUE, -#' prob = c(0.3, 0.15, 0.55)) +#' prob = c(0.3, 0.15, 0.55) +#' ) #' ## Here, the NAs are the most frequent group. #' table(log_var, useNA = "ifany") #' diff --git a/R/vis_clus.R b/R/vis_clus.R index e1e0eaa0..7286705e 100644 --- a/R/vis_clus.R +++ b/R/vis_clus.R @@ -103,31 +103,32 @@ #' ) #' print(p4) #' } -vis_clus <- function(spe, - sampleid = unique(spe$sample_id)[1], - clustervar, - colors = c( - "#b2df8a", - "#e41a1c", - "#377eb8", - "#4daf4a", - "#ff7f00", - "gold", - "#a65628", - "#999999", - "black", - "grey", - "white", - "purple" - ), - spatial = TRUE, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { +vis_clus <- function( + spe, + sampleid = unique(spe$sample_id)[1], + clustervar, + colors = c( + "#b2df8a", + "#e41a1c", + "#377eb8", + "#4daf4a", + "#ff7f00", + "gold", + "#a65628", + "#999999", + "black", + "grey", + "white", + "purple" + ), + spatial = TRUE, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { # Verify existence and legitimacy of 'sampleid' if ( !("sample_id" %in% colnames(colData(spe))) || diff --git a/R/vis_clus_p.R b/R/vis_clus_p.R index f74b95f6..b7a381d6 100644 --- a/R/vis_clus_p.R +++ b/R/vis_clus_p.R @@ -42,19 +42,18 @@ #' rm(spe_sub) #' } vis_clus_p <- - function( - spe, - d, - clustervar, - sampleid = unique(spe$sample_id)[1], - colors, - spatial, - title, - image_id = "lowres", - alpha = NA, - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40") { + function(spe, + d, + clustervar, + sampleid = unique(spe$sample_id)[1], + colors, + spatial, + title, + image_id = "lowres", + alpha = NA, + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- NULL # stopifnot(all(c("pxl_col_in_fullres", "pxl_row_in_fullres", "key") %in% colnames(d))) diff --git a/R/vis_gene.R b/R/vis_gene.R index ed056ba5..15218962 100644 --- a/R/vis_gene.R +++ b/R/vis_gene.R @@ -158,22 +158,23 @@ #' print(p8) #' } vis_gene <- - function(spe, - sampleid = unique(spe$sample_id)[1], - geneid = rowData(spe)$gene_search[1], - spatial = TRUE, - assayname = "logcounts", - minCount = 0, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - multi_gene_method = c("z_score", "pca", "sparsity"), - is_stitched = FALSE, - ...) { + function( + spe, + sampleid = unique(spe$sample_id)[1], + geneid = rowData(spe)$gene_search[1], + spatial = TRUE, + assayname = "logcounts", + minCount = 0, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + multi_gene_method = c("z_score", "pca", "sparsity"), + is_stitched = FALSE, + ...) { multi_gene_method <- rlang::arg_match(multi_gene_method) # Verify existence and legitimacy of 'sampleid' if ( diff --git a/R/vis_gene_p.R b/R/vis_gene_p.R index 48741fa9..900bd651 100644 --- a/R/vis_gene_p.R +++ b/R/vis_gene_p.R @@ -47,20 +47,19 @@ #' rm(spe_sub) #' } vis_gene_p <- - function( - spe, - d, - sampleid = unique(spe$sample_id)[1], - spatial, - title, - viridis = TRUE, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - legend_title = "") { + function(spe, + d, + sampleid = unique(spe$sample_id)[1], + spatial, + title, + viridis = TRUE, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + legend_title = "") { ## Some variables pxl_row_in_fullres <- pxl_col_in_fullres <- key <- COUNT <- NULL diff --git a/man/check_modeling_results.Rd b/man/check_modeling_results.Rd index 48cf5f6a..284c07f3 100644 --- a/man/check_modeling_results.Rd +++ b/man/check_modeling_results.Rd @@ -12,7 +12,8 @@ check_modeling_results(modeling_results) columns \verb{f_stat_*} or \verb{t_stat_*} as well as \verb{p_value_*} and \verb{fdr_*} plus \code{ensembl}. The column name is used to extract the statistic results, the p-values, and the FDR adjusted p-values. Then the \code{ensembl} column is used -for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details. Typically +this is the set of reference statistics used in \code{layer_stat_cor()}.} } \value{ The input object if all checks are passed. diff --git a/man/gene_set_enrichment.Rd b/man/gene_set_enrichment.Rd index cf8889a4..04702437 100644 --- a/man/gene_set_enrichment.Rd +++ b/man/gene_set_enrichment.Rd @@ -24,7 +24,8 @@ determining significance among the modeling results genes.} columns \verb{f_stat_*} or \verb{t_stat_*} as well as \verb{p_value_*} and \verb{fdr_*} plus \code{ensembl}. The column name is used to extract the statistic results, the p-values, and the FDR adjusted p-values. Then the \code{ensembl} column is used -for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details. Typically +this is the set of reference statistics used in \code{layer_stat_cor()}.} \item{model_type}{A named element of the \code{modeling_results} list. By default that is either \code{enrichment} for the model that tests one human brain layer diff --git a/man/get_colors.Rd b/man/get_colors.Rd index 82d96a6d..9373c33c 100644 --- a/man/get_colors.Rd +++ b/man/get_colors.Rd @@ -45,7 +45,8 @@ set.seed(20240712) log_var <- sample(c(TRUE, FALSE, NA), 1000, replace = TRUE, - prob = c(0.3, 0.15, 0.55)) + prob = c(0.3, 0.15, 0.55) +) log_var_sorted <- sort_clusters(log_var) ## A color does get assigned to 'NA', but will be overwritten by ## 'na_color' passed to `vis_clus_p()` and related functions. diff --git a/man/layer_stat_cor.Rd b/man/layer_stat_cor.Rd index 3801a1d4..8ccf2c0f 100644 --- a/man/layer_stat_cor.Rd +++ b/man/layer_stat_cor.Rd @@ -13,20 +13,26 @@ layer_stat_cor( ) } \arguments{ -\item{stats}{A data.frame where the row names are Ensembl gene IDs, the -column names are labels for clusters of cells or cell types, and where +\item{stats}{A query \code{data.frame} where the row names are ENSEMBL gene IDs, +the column names are labels for clusters of cells or cell types, and where each cell contains the given statistic for that gene and cell type. These statistics should be computed similarly to the modeling results from the data we provide. For example, like the \code{enrichment} t-statistics that are derived from comparing one layer against the rest. The \code{stats} will be -matched and then correlated with our statistics.} +matched and then correlated with the reference statistics. + +If using the output of \code{registration_wrapper()} then use \verb{$enrichment} to +access the results from \code{registration_stats_enrichment()}. This function will +automatically extract the statistics and assign the ENSEMBL gene IDs to the +row names of the query matrix.} \item{modeling_results}{Defaults to the output of \code{fetch_data(type = 'modeling_results')}. This is a list of tables with the columns \verb{f_stat_*} or \verb{t_stat_*} as well as \verb{p_value_*} and \verb{fdr_*} plus \code{ensembl}. The column name is used to extract the statistic results, the p-values, and the FDR adjusted p-values. Then the \code{ensembl} column is used -for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details. Typically +this is the set of reference statistics used in \code{layer_stat_cor()}.} \item{model_type}{A named element of the \code{modeling_results} list. By default that is either \code{enrichment} for the model that tests one human brain layer @@ -45,9 +51,9 @@ into \code{layerB-layerA}.} genes. The default is \code{NULL} in which case no filtering is done.} } \value{ -A correlation matrix between \code{stats} and our statistics using only -the Ensembl gene IDs present in both tables. The columns are sorted using -a hierarchical cluster. +A correlation matrix between the query \code{stats} and the reference +statistics using only the ENSEMBL gene IDs present in both tables. +The columns are sorted using hierarchical clustering. } \description{ Layer modeling correlation of statistics diff --git a/man/layer_stat_cor_plot.Rd b/man/layer_stat_cor_plot.Rd index 8eccd53d..0f839360 100644 --- a/man/layer_stat_cor_plot.Rd +++ b/man/layer_stat_cor_plot.Rd @@ -33,18 +33,25 @@ row annotations.} \item{reference_colors}{named \code{character} vector of colors, Adds colors to reference column annotations.} -\item{annotation}{annotation data.frame output of \code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}, -adds 'X' for good confidence annotations, '*' for poor confidence.} +\item{annotation}{annotation data.frame output of +\code{\link[=annotate_registered_clusters]{annotate_registered_clusters()}}, adds 'X' for good confidence annotations, +'*' for poor confidence.} -\item{...}{Additional parameters passed to \code{\link[ComplexHeatmap:Heatmap]{ComplexHeatmap::Heatmap()}} -ex. \code{cluster_rows} and \code{cluster_columns}.} +\item{...}{Additional parameters passed to +\code{\link[ComplexHeatmap:Heatmap]{ComplexHeatmap::Heatmap()}} such as \code{cluster_rows} +and \code{cluster_columns}.} } \value{ -(\link[ComplexHeatmap:Heatmap-class]{Heatmap-class}) plot of t-stat correlations +(\link[ComplexHeatmap:Heatmap-class]{Heatmap-class}) plot of t-stat +correlations } \description{ -Use ComplexHeatmap to plot the correlation matrix between a reference and -query modeling statistics from \code{\link[=layer_stat_cor]{layer_stat_cor()}}. +This function makes a ComplexHeatmap from the correlation matrix +between a reference and query modeling statistics from \code{\link[=layer_stat_cor]{layer_stat_cor()}}. +For example, between the query statistics from a set of cell cluster/types +derived from scRNA-seq or snRNA-seq data (among other types) and the +reference layer statistics from the Human DLPFC Visium data (when using the +default arguments). } \details{ Includes functionality to add color annotations, @@ -58,52 +65,57 @@ if (!exists("modeling_results")) { modeling_results <- fetch_data(type = "modeling_results") } -## querey spatailDLPFC modeling -query_modeling_results <- fetch_data(type = "spatialDLPFC_Visium_modeling_results") - -## extract t-statics and rename -registration_t_stats <- query_modeling_results$enrichment[, grep("^t_stat", colnames(query_modeling_results$enrichment))] -colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) +## query spatialDLPFC modeling results +query_modeling_results <- fetch_data( + type = "spatialDLPFC_Visium_modeling_results" +) ## Compute the correlations cor_stats_layer <- layer_stat_cor( - stats = registration_t_stats, + stats = query_modeling_results$enrichment, modeling_results, model_type = "enrichment" ) ## Visualize the correlation matrix -## most basic +## Default plot with no annotations and defaults for ComplexHeatmap() layer_stat_cor_plot(cor_stats_layer) ## add colors -## add libd_layer_colors to refrence Human Pilot layers +## add libd_layer_colors to reference Human Pilot layers layer_stat_cor_plot(cor_stats_layer, reference_colors = libd_layer_colors) -## supply polychrome colors to query clusters -cluster_colors <- c('#5A5156', '#E4E1E3', '#F6222E', '#FE00FA', '#16FF32', '#3283FE', '#FEAF16', '#B00068', '#1CFFCE') -names(cluster_colors) <- rownames(cor_stats_layer) - -layer_stat_cor_plot(cor_stats_layer, - query_colors = cluster_colors, - reference_colors = libd_layer_colors) +## obtain colors for the query clusters +cluster_colors <- get_colors(clusters = rownames(cor_stats_layer)) +layer_stat_cor_plot(cor_stats_layer, + query_colors = cluster_colors, + reference_colors = libd_layer_colors +) ## Apply additional ComplexHeatmap param -layer_stat_cor_plot(cor_stats_layer, cluster_rows = FALSE, cluster_columns = FALSE) +layer_stat_cor_plot(cor_stats_layer, + cluster_rows = FALSE, + cluster_columns = FALSE +) ## Add annotation -annotation_df <- annotate_registered_clusters(cor_stats_layer, confidence_threshold = .55) +annotation_df <- annotate_registered_clusters( + cor_stats_layer, + confidence_threshold = .55 +) layer_stat_cor_plot(cor_stats_layer, annotation = annotation_df) ## All together -layer_stat_cor_plot(cor_stats_layer, - query_colors = cluster_colors, - reference_colors = libd_layer_colors, - annotation = annotation_df, - cluster_rows = FALSE, - cluster_columns = FALSE) - +layer_stat_cor_plot( + cor_stats_layer, + query_colors = cluster_colors, + reference_colors = libd_layer_colors, + annotation = annotation_df, + cluster_rows = FALSE, + cluster_columns = FALSE +) + } \seealso{ Other Layer correlation functions: diff --git a/man/run_app.Rd b/man/run_app.Rd index 0eb0295d..587d081e 100644 --- a/man/run_app.Rd +++ b/man/run_app.Rd @@ -46,7 +46,8 @@ layer-level (group-level) resolution. See \code{\link[=fetch_data]{fetch_data()} columns \verb{f_stat_*} or \verb{t_stat_*} as well as \verb{p_value_*} and \verb{fdr_*} plus \code{ensembl}. The column name is used to extract the statistic results, the p-values, and the FDR adjusted p-values. Then the \code{ensembl} column is used -for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details. Typically +this is the set of reference statistics used in \code{layer_stat_cor()}.} \item{sig_genes}{The output of \code{\link[=sig_genes_extract_all]{sig_genes_extract_all()}} which is a table in long format with the modeling results. You can subset this if the object diff --git a/man/sig_genes_extract.Rd b/man/sig_genes_extract.Rd index ad838055..cd144460 100644 --- a/man/sig_genes_extract.Rd +++ b/man/sig_genes_extract.Rd @@ -20,7 +20,8 @@ sig_genes_extract( columns \verb{f_stat_*} or \verb{t_stat_*} as well as \verb{p_value_*} and \verb{fdr_*} plus \code{ensembl}. The column name is used to extract the statistic results, the p-values, and the FDR adjusted p-values. Then the \code{ensembl} column is used -for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details. Typically +this is the set of reference statistics used in \code{layer_stat_cor()}.} \item{model_type}{A named element of the \code{modeling_results} list. By default that is either \code{enrichment} for the model that tests one human brain layer diff --git a/man/sig_genes_extract_all.Rd b/man/sig_genes_extract_all.Rd index c79edf28..d984b84a 100644 --- a/man/sig_genes_extract_all.Rd +++ b/man/sig_genes_extract_all.Rd @@ -18,7 +18,8 @@ sig_genes_extract_all( columns \verb{f_stat_*} or \verb{t_stat_*} as well as \verb{p_value_*} and \verb{fdr_*} plus \code{ensembl}. The column name is used to extract the statistic results, the p-values, and the FDR adjusted p-values. Then the \code{ensembl} column is used -for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details.} +for matching in some cases. See \code{\link[=fetch_data]{fetch_data()}} for more details. Typically +this is the set of reference statistics used in \code{layer_stat_cor()}.} \item{sce_layer}{Defaults to the output of \code{fetch_data(type = 'sce_layer')}. This is a diff --git a/man/sort_clusters.Rd b/man/sort_clusters.Rd index 66ec783c..a2b911bc 100644 --- a/man/sort_clusters.Rd +++ b/man/sort_clusters.Rd @@ -60,7 +60,8 @@ set.seed(20240712) log_var <- sample(c(TRUE, FALSE, NA), 1000, replace = TRUE, - prob = c(0.3, 0.15, 0.55)) + prob = c(0.3, 0.15, 0.55) +) ## Here, the NAs are the most frequent group. table(log_var, useNA = "ifany") diff --git a/tests/testthat/test-multi_gene_z_score.R b/tests/testthat/test-multi_gene_z_score.R index f78af3f1..27c8ae7d 100644 --- a/tests/testthat/test-multi_gene_z_score.R +++ b/tests/testthat/test-multi_gene_z_score.R @@ -21,12 +21,14 @@ test_that( # columns were dropped cont_mat <- matrix(c(1, NA, 3, 4, 2, 2), ncol = 3) colnames(cont_mat) <- c("bad1", "good", "bad2") - - temp = c(3, 4) - expected_result = (temp - mean(temp)) / sd(temp) + + temp <- c(3, 4) + expected_result <- (temp - mean(temp)) / sd(temp) expect_warning( - { actual_result = multi_gene_z_score(cont_mat) }, + { + actual_result <- multi_gene_z_score(cont_mat) + }, "Dropping features\\(s\\) 'bad1', 'bad2' which have no expression variation" ) expect_equal(actual_result, expected_result) From 5e6912aa79ea9caa5d692bb2e526bb0925a532af Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 12:29:59 -0500 Subject: [PATCH 238/259] Don't need to set the color_max anymore as it's done by default in the function call --- vignettes/spatialLIBD.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/spatialLIBD.Rmd b/vignettes/spatialLIBD.Rmd index 00189010..3afb8432 100644 --- a/vignettes/spatialLIBD.Rmd +++ b/vignettes/spatialLIBD.Rmd @@ -466,7 +466,7 @@ Once we have computed this correlation matrix, we can then visualize it using `l ```{r 'layer_stat_cor_plot', fig.wide = TRUE} ## Visualize the correlation matrix -layer_stat_cor_plot(cor_stats_layer, max = max(cor_stats_layer)) +layer_stat_cor_plot(cor_stats_layer) ``` In order to fully interpret the resulting heatmap you need to know what each of the cell clusters labels mean. In this case, the syntax is `xx (Y)` where `xx` is the cluster number and `Y` is: From df1c105086c4cac3b53367ec5e2ffb2e0c2becde Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 12:30:37 -0500 Subject: [PATCH 239/259] Ibidem --- vignettes/guide_to_spatial_registration.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index cefdf0fa..df1037d3 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -283,7 +283,7 @@ We can see from this heatmap what layers the different cell types are associated ```{r layer_cor_plot} -layer_stat_cor_plot(cor_layer, max = max(cor_layer)) +layer_stat_cor_plot(cor_layer) ``` ## Annotate Cell Types by Top Correlation From 86a677c90d9f1fe75ba954cf633e304d0a019140 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 12:58:39 -0500 Subject: [PATCH 240/259] Mention ComplexHeatmap on the vignette --- vignettes/spatialLIBD.Rmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vignettes/spatialLIBD.Rmd b/vignettes/spatialLIBD.Rmd index 3afb8432..323d948f 100644 --- a/vignettes/spatialLIBD.Rmd +++ b/vignettes/spatialLIBD.Rmd @@ -49,6 +49,7 @@ bib <- c( BiocFileCache = citation("BiocFileCache")[1], BiocGenerics = citation("BiocGenerics")[1], BiocStyle = citation("BiocStyle")[1], + ComplexHeatmap = citation("ComplexHeatmap")[1], cowplot = citation("cowplot")[1], DT = citation("DT")[1], edgeR = citation("edgeR")[1], @@ -615,6 +616,7 @@ The `r Biocpkg('spatialLIBD')` package `r Citep(bib[['spatialLIBD']])` was made * `r Biocpkg('BiocFileCache')` `r Citep(bib[['BiocFileCache']])` * `r Biocpkg('BiocGenerics')` `r Citep(bib[['BiocGenerics']])` * `r Biocpkg('BiocStyle')` `r Citep(bib[['BiocStyle']])` +* `r Biocpkg('ComplexHeatmap')` `r Citep(bib[['ComplexHeatmap']])` * `r CRANpkg('cowplot')` `r Citep(bib[['cowplot']])` * `r CRANpkg('DT')` `r Citep(bib[['DT']])` * `r Biocpkg('edgeR')` `r Citep(bib[['edgeR']])` From 2166cac6fb073dda6ff728df3c3288b378d83af2 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 13:04:18 -0500 Subject: [PATCH 241/259] Showcase new features of layer_stat_cor_plot() on the spatial registration vignette --- vignettes/guide_to_spatial_registration.Rmd | 30 ++++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/vignettes/guide_to_spatial_registration.Rmd b/vignettes/guide_to_spatial_registration.Rmd index df1037d3..e1442a79 100644 --- a/vignettes/guide_to_spatial_registration.Rmd +++ b/vignettes/guide_to_spatial_registration.Rmd @@ -239,16 +239,10 @@ sce_modeling_results <- registration_wrapper( ``` ## Extract Enrichment t-statistics -```{r "extract_t_stats"} -## extract t-statics and rename -registration_t_stats <- sce_modeling_results$enrichment[, grep("^t_stat", colnames(sce_modeling_results$enrichment))] -colnames(registration_t_stats) <- gsub("^t_stat_", "", colnames(registration_t_stats)) - -## cell types x gene -dim(registration_t_stats) -## check out table -registration_t_stats[1:5, 1:5] +```{r "extract_t_stats"} +## check out table on enrichment t-statistics +sce_modeling_results$enrichment[1:5, 1:5] ``` @@ -256,7 +250,7 @@ registration_t_stats[1:5, 1:5] ```{r "layer_stat_cor"} cor_layer <- layer_stat_cor( - stats = registration_t_stats, + stats = sce_modeling_results$enrichment, modeling_results = layer_modeling_results, model_type = "enrichment", top_n = 100 @@ -301,6 +295,22 @@ anno <- annotate_registered_clusters( anno ``` +## Plot Annotated Cell Types + +Finally, we can update our heatmap with colors and annotations based on cluster +registration for the snRNA-seq clusters. + +```{r "plot_anno"} +layer_stat_cor_plot( + cor_layer, + query_colors = get_colors(clusters = rownames(cor_layer)), + reference_colors = libd_layer_colors, + annotation = anno, + cluster_rows = FALSE, + cluster_columns = FALSE +) +``` + # Reproducibility From e9de73123c35f4f3407f3aa2f5596252b10c7634 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 13:07:00 -0500 Subject: [PATCH 242/259] Ignore macOS on GHA for now due to the issue with system curl. --- .github/workflows/check-bioc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index a9c9df4a..c46db55d 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -53,7 +53,7 @@ jobs: matrix: config: - { os: ubuntu-latest, r: '4.4', bioc: '3.20', cont: "bioconductor/bioconductor_docker:RELEASE_3_20", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } - - { os: macOS-latest, r: '4.4', bioc: '3.20'} + # - { os: macOS-latest, r: '4.4', bioc: '3.20'} - { os: windows-latest, r: '4.4', bioc: '3.20'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent From c0e7756002a11688e5288ce2b24f40d16edfb864 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 13:49:40 -0500 Subject: [PATCH 243/259] We are now using circlize::colorRamp2() inside layer_stat_cor_plot() to make things compatible with ComplexHeatmap::Heatmap() based on https://jokergoo.github.io/ComplexHeatmap-reference/book/a-single-heatmap.html#colors. We also updated app_ui.R and app_server.R to use the ComplexHeatmap version + also auto-annotate the registered clusters. Co-authored-by: Louise Huuki --- DESCRIPTION | 7 ++++--- NAMESPACE | 3 +-- R/app_server.R | 23 ++++++++++++++++++++--- R/app_ui.R | 20 +++++++++++++++++++- R/layer_stat_cor_plot.R | 16 +++++++++------- man/layer_stat_cor_plot.Rd | 7 ++++--- vignettes/spatialLIBD.Rmd | 2 ++ 7 files changed, 59 insertions(+), 19 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0ace277d..5ae3fb5c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -55,7 +55,6 @@ Imports: scater, DT, ExperimentHub, - RColorBrewer, SummarizedExperiment, stats, graphics, @@ -80,7 +79,8 @@ Imports: MatrixGenerics, rlang, dplyr, - ComplexHeatmap + ComplexHeatmap, + circlize RoxygenNote: 7.3.2 Roxygen: list(markdown = TRUE) URL: https://github.com/LieberInstitute/spatialLIBD @@ -95,7 +95,8 @@ Suggests: here, BiocManager, lobstr, - DropletUtils + DropletUtils, + RColorBrewer VignetteBuilder: knitr biocViews: Homo_sapiens_Data, ExperimentHub, SequencingData, SingleCellData, ExpressionData, Tissue, PackageTypeData, SpatialData diff --git a/NAMESPACE b/NAMESPACE index c85f884a..10d3d368 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -64,7 +64,6 @@ importFrom(DT,renderDT) importFrom(GenomicRanges,seqnames) importFrom(IRanges,CharacterList) importFrom(IRanges,IntegerList) -importFrom(RColorBrewer,brewer.pal) importFrom(S4Vectors,"mcols<-") importFrom(S4Vectors,DataFrame) importFrom(S4Vectors,mcols) @@ -89,6 +88,7 @@ importFrom(SummarizedExperiment,assayNames) importFrom(SummarizedExperiment,assays) importFrom(SummarizedExperiment,colData) importFrom(benchmarkme,get_ram) +importFrom(circlize,colorRamp2) importFrom(cowplot,plot_grid) importFrom(dplyr,group_by) importFrom(dplyr,left_join) @@ -100,7 +100,6 @@ importFrom(edgeR,filterByExpr) importFrom(fields,image.plot) importFrom(golem,with_golem_options) importFrom(grDevices,as.raster) -importFrom(grDevices,colorRampPalette) importFrom(grDevices,dev.off) importFrom(grDevices,pdf) importFrom(graphics,abline) diff --git a/R/app_server.R b/R/app_server.R index 05914017..2239ad33 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1471,7 +1471,15 @@ app_server <- function(input, output, session) { static_layer_external_tstat_plot <- reactive({ layer_stat_cor_plot( static_layer_external_tstat(), - max(c(0.1, input$layer_tstat_max)) + max(c(0.1, input$layer_tstat_max)), + -max(c(0.1, input$layer_tstat_max)), + cluster_rows = FALSE, + cluster_columns = FALSE, + annotation = annotate_registered_clusters( + static_layer_external_tstat(), + input$layer_confidence_threshold, + input$layer_cutoff_merge_ratio + ) ) }) @@ -1639,10 +1647,19 @@ app_server <- function(input, output, session) { height = 8, width = 12 ) - layer_stat_cor_plot( + p <- layer_stat_cor_plot( static_layer_external_tstat(), - max(c(0.1, input$layer_tstat_max)) + max(c(0.1, input$layer_tstat_max)), + -max(c(0.1, input$layer_tstat_max)), + cluster_rows = FALSE, + cluster_columns = FALSE, + annotation = annotate_registered_clusters( + static_layer_external_tstat(), + input$layer_confidence_threshold, + input$layer_cutoff_merge_ratio + ) ) + print(p) dev.off() } ) diff --git a/R/app_ui.R b/R/app_ui.R index 208a2352..70c0383a 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -856,7 +856,25 @@ app_ui <- function() { max = 1, step = 0.01 ), - helpText("Use a smaller positive number to change the range of the color scale used. Use 1 if you want the color range to reflect the maximum range of correlation values. Default: 0.81.") + helpText("Use a smaller positive number to change the range of the color scale used. Use 1 if you want the color range to reflect the maximum range of correlation values. Default: 0.81."), + numericInput( + "layer_confidence_threshold", + label = "Annotation confidence threshold", + value = 0.25, + min = 0, + max = 1, + step = 0.01 + ), + helpText("Minimum correlation for a high confidence annotation. Higher values are more strict in annotating. Default: 0.25."), + numericInput( + "layer_cutoff_merge_ratio", + label = "Annotation cutoff merge ratio", + value = 0.25, + min = 0, + max = 1, + step = 0.01 + ), + helpText("Ratio the next closest correlation and the current one. Lower values are more strict in annotating. Default: 0.25.") ) ), hr(), diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index eed0daa8..ff8eca61 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -16,8 +16,9 @@ #' the color scale (should be between 0 and 1). #' @param color_min A `numeric(1)` specifying the lowest correlation value for #' the color scale (should be between 0 and -1). -#' @param color_scale A `character` vector specifying the color scale for the -#' fill of the heatmap, defaults to classic purple -> green. +#' @param color_scale A `character(3)` vector specifying the color scale for the +#' fill of the heatmap. The first value is used for `color_min`, the second one +#' for zero, and the third for `color_max`. #' @param query_colors named `character` vector of colors, Adds colors to query #' row annotations. #' @param reference_colors named `character` vector of colors, Adds colors to @@ -36,8 +37,7 @@ #' @author Louise Huuki-Myers #' @family Layer correlation functions #' -#' @importFrom RColorBrewer brewer.pal -#' @importFrom grDevices colorRampPalette +#' @importFrom circlize colorRamp2 #' @importFrom ComplexHeatmap columnAnnotation rowAnnotation Heatmap #' #' @examples @@ -101,14 +101,16 @@ layer_stat_cor_plot <- function(cor_stats_layer, color_max = max(cor_stats_layer), color_min = min(cor_stats_layer), - color_scale = RColorBrewer::brewer.pal(7, "PRGn"), + color_scale = c("#762A83", "#F7F7F7", "#1B7837"), query_colors = NULL, reference_colors = NULL, annotation = NULL, ...) { ## define color pallet - theSeq <- seq(color_min, color_max, by = 0.01) - my.col <- grDevices::colorRampPalette(color_scale)(length(theSeq)) + stopifnot(color_min < color_max) + stopifnot(color_min < 0) + stopifnot(length(color_scale) == 3) + my.col <- circlize::colorRamp2(c(color_min, 0, color_max), color_scale) # ## query annotations on row if (!is.null(query_colors)) { diff --git a/man/layer_stat_cor_plot.Rd b/man/layer_stat_cor_plot.Rd index 0f839360..835ceb4e 100644 --- a/man/layer_stat_cor_plot.Rd +++ b/man/layer_stat_cor_plot.Rd @@ -8,7 +8,7 @@ layer_stat_cor_plot( cor_stats_layer, color_max = max(cor_stats_layer), color_min = min(cor_stats_layer), - color_scale = RColorBrewer::brewer.pal(7, "PRGn"), + color_scale = c("#762A83", "#F7F7F7", "#1B7837"), query_colors = NULL, reference_colors = NULL, annotation = NULL, @@ -24,8 +24,9 @@ the color scale (should be between 0 and 1).} \item{color_min}{A \code{numeric(1)} specifying the lowest correlation value for the color scale (should be between 0 and -1).} -\item{color_scale}{A \code{character} vector specifying the color scale for the -fill of the heatmap, defaults to classic purple -> green.} +\item{color_scale}{A \code{character(3)} vector specifying the color scale for the +fill of the heatmap. The first value is used for \code{color_min}, the second one +for zero, and the third for \code{color_max}.} \item{query_colors}{named \code{character} vector of colors, Adds colors to query row annotations.} diff --git a/vignettes/spatialLIBD.Rmd b/vignettes/spatialLIBD.Rmd index 323d948f..694d47d9 100644 --- a/vignettes/spatialLIBD.Rmd +++ b/vignettes/spatialLIBD.Rmd @@ -49,6 +49,7 @@ bib <- c( BiocFileCache = citation("BiocFileCache")[1], BiocGenerics = citation("BiocGenerics")[1], BiocStyle = citation("BiocStyle")[1], + circlize = citation("circlize")[1], ComplexHeatmap = citation("ComplexHeatmap")[1], cowplot = citation("cowplot")[1], DT = citation("DT")[1], @@ -616,6 +617,7 @@ The `r Biocpkg('spatialLIBD')` package `r Citep(bib[['spatialLIBD']])` was made * `r Biocpkg('BiocFileCache')` `r Citep(bib[['BiocFileCache']])` * `r Biocpkg('BiocGenerics')` `r Citep(bib[['BiocGenerics']])` * `r Biocpkg('BiocStyle')` `r Citep(bib[['BiocStyle']])` +* `r CRANpkg('circlize')` `r Citep(bib[['circlize']])` * `r Biocpkg('ComplexHeatmap')` `r Citep(bib[['ComplexHeatmap']])` * `r CRANpkg('cowplot')` `r Citep(bib[['cowplot']])` * `r CRANpkg('DT')` `r Citep(bib[['DT']])` From b36548ac03e062eac628ee5ca6e969385b86082b Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:02:36 -0500 Subject: [PATCH 244/259] Use get_colors() to decorate the cluster registration heatmap. Also, there's no need to duplicate code since this is no longer a base R plot. This is in relation the the PDF download button. Co-authored-by: Louise Huuki --- R/app_server.R | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index 2239ad33..dcbcc440 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1479,6 +1479,12 @@ app_server <- function(input, output, session) { static_layer_external_tstat(), input$layer_confidence_threshold, input$layer_cutoff_merge_ratio + ), + query_colors = get_colors( + clusters = rownames(static_layer_external_tstat()) + ), + reference_colors = get_colors( + clusters = colnames(static_layer_external_tstat()) ) ) }) @@ -1647,18 +1653,7 @@ app_server <- function(input, output, session) { height = 8, width = 12 ) - p <- layer_stat_cor_plot( - static_layer_external_tstat(), - max(c(0.1, input$layer_tstat_max)), - -max(c(0.1, input$layer_tstat_max)), - cluster_rows = FALSE, - cluster_columns = FALSE, - annotation = annotate_registered_clusters( - static_layer_external_tstat(), - input$layer_confidence_threshold, - input$layer_cutoff_merge_ratio - ) - ) + p <- static_layer_external_tstat_plot() print(p) dev.off() } From 7cf67fb714a8e11a44c2ec6d806fc408eba7d62b Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:15:10 -0500 Subject: [PATCH 245/259] Enable downloading a CSV file with the annotated clusters as requested by @lahuuki. --- R/app_server.R | 38 +++++++++++++++++++++++++++++++++----- R/app_ui.R | 2 ++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/R/app_server.R b/R/app_server.R index dcbcc440..a90ea7ac 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1468,6 +1468,14 @@ app_server <- function(input, output, session) { layer_stat_cor(input_stat, modeling_results, input$layer_model) }) + static_layer_external_tstat_annotated_clusters <- reactive({ + annotate_registered_clusters( + static_layer_external_tstat(), + input$layer_confidence_threshold, + input$layer_cutoff_merge_ratio + ) + }) + static_layer_external_tstat_plot <- reactive({ layer_stat_cor_plot( static_layer_external_tstat(), @@ -1475,11 +1483,7 @@ app_server <- function(input, output, session) { -max(c(0.1, input$layer_tstat_max)), cluster_rows = FALSE, cluster_columns = FALSE, - annotation = annotate_registered_clusters( - static_layer_external_tstat(), - input$layer_confidence_threshold, - input$layer_cutoff_merge_ratio - ), + annotation = static_layer_external_tstat_annotated_clusters(), query_colors = get_colors( clusters = rownames(static_layer_external_tstat()) ), @@ -1880,6 +1884,30 @@ app_server <- function(input, output, session) { } ) + output$layer_downloadTstatCor_annotation <- downloadHandler( + filename = function() { + gsub( + " ", + "_", + paste0( + "spatialLIBD_layer_TstatCor_annotated_clusters_", + input$layer_model, + "_", + Sys.time(), + ".csv" + ) + ) + }, + content = function(file) { + write.csv( + static_layer_external_tstat_annotated_clusters(), + file = file, + quote = FALSE, + row.names = TRUE + ) + } + ) + ## Reproducibility info diff --git a/R/app_ui.R b/R/app_ui.R index 70c0383a..8dfea1a6 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -896,6 +896,8 @@ app_ui <- function() { hr(), downloadButton("layer_downloadTstatCorTable", "Download CSV"), helpText("Correlation matrix that is visually illustrated with the previous plot."), + downloadButton("layer_downloadTstatCor_annotation", "Download CSV"), + helpText("Annotated clusters."), DT::DTOutput("layer_tstat_cor_table") ) ) From 8c215c25911930800828b9536796782b15f5dbbf Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:28:59 -0500 Subject: [PATCH 246/259] Use LIBD layer colors by default. --- R/app_server.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/app_server.R b/R/app_server.R index a90ea7ac..0d40265c 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1488,6 +1488,7 @@ app_server <- function(input, output, session) { clusters = rownames(static_layer_external_tstat()) ), reference_colors = get_colors( + libd_layer_colors, clusters = colnames(static_layer_external_tstat()) ) ) From 64d99dfc72df5f2bc68dc5df4d1411b4a125aaae Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:29:11 -0500 Subject: [PATCH 247/259] Improve help text for the merging threshold --- R/app_ui.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/app_ui.R b/R/app_ui.R index 8dfea1a6..d1bf2c91 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -874,7 +874,7 @@ app_ui <- function() { max = 1, step = 0.01 ), - helpText("Ratio the next closest correlation and the current one. Lower values are more strict in annotating. Default: 0.25.") + helpText("Merging threshold for the ratio of the difference between the current one to the next closest correlation, relative to the next closest correlation: (current - next_cor) / next_cor. Lower values are more strict in annotating. Default: 0.25.") ) ), hr(), From 9eda0691c4bdbbf22325c5285641295dfa470b34 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:34:27 -0500 Subject: [PATCH 248/259] v1.19.1 -- bump version and update NEWS after merging and processing https://github.com/LieberInstitute/spatialLIBD/pull/91 by @lahuuki --- DESCRIPTION | 4 ++-- NEWS.md | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5ae3fb5c..7ff6154e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.19.0 -Date: 2024-10-22 +Version: 1.19.1 +Date: 2024-12-12 Authors@R: c( person("Leonardo", "Collado-Torres", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 3492a2e5..b8413d3d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,22 @@ +# spatialLIBD 1.19.1 + +NEW FEATURES + +* Merged by @lahuuki. +This pull request fully re-implemented `layer_stat_cor_plot()` with a version +that uses `ComplexHeatmap::Heatmap()` internally. It also adds support for +incorporating the automatic annotation results from +`annotate_registered_clusters()`. NOTE that the `max` argument was renamed to +`color_max`, as well as `min` to `color_min`. Also, the default for `min` used +to be `-max` and now for `color_min` the default is the `min()` correlation +observed. The default for `max` was 0.81 and the default for `color_max()` is +the `max()` observed correlation. +* `run_app()` was also updated to match the updated in `layer_stat_cor_plot()` +and now has 2 new inputs for controlling the annotation process with +`annotate_registered_clusters()`. It also allows downloading a CSV file with +the annotation results. + + # spatialLIBD 1.17.10 BUG FIXES From 9dff4b75ef4f974887519b6b32f8f912d0d4e60c Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:38:28 -0500 Subject: [PATCH 249/259] Fix some typos, then auto-indent code. Also use call. = FALSE on the warning() calls. --- R/registration_pseudobulk.R | 34 ++++++++++++++-------- tests/testthat/test-registration_wrapper.R | 14 +++++---- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index b8ab52f0..63819b8a 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -8,8 +8,8 @@ #' object or one that inherits its properties. #' @param var_registration A `character(1)` specifying the `colData(sce)` #' variable of interest against which will be used for computing the relevant -#' statistics. This should be a categorical variable, with all categories -#' syntaticly valid (could be used as an R variable, no special characters or +#' statistics. This should be a categorical variable, with all categories +#' syntaticly valid (could be used as an R variable, no special characters or #' leading numbers), ex. 'L1.2', 'celltype2' not 'L1/2' or '2'. #' @param var_sample_id A `character(1)` specifying the `colData(sce)` variable #' with the sample ID. @@ -74,21 +74,31 @@ registration_pseudobulk <- stopifnot(var_registration != var_sample_id) ## Check that the values in the registration variable are numeric - if(is.numeric(sce[[var_registration]])){ - warning(sprintf("var_registration \"%s\" is numeric, convering to catagorial vector...", - var_registration)) + if (is.numeric(sce[[var_registration]])) { + warning( + sprintf( + "var_registration \"%s\" is numeric, convering to categorical vector...", + var_registration + ), + call. = FALSE + ) } - + ## check for Non-Syntactic variables - convert with make.names & warn uniq_var_regis <- unique(sce[[var_registration]]) - syntatic <- grepl("^((([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*)|[.])$", uniq_var_regis) + syntatic <- grepl("^((([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*)|[.])$", + uniq_var_regis) if (!all(syntatic)) { - warning(sprintf("var_registration \"%s\" contains non-syntatic variables: %s\nconverting to %s", - var_registration, - paste(uniq_var_regis[!syntatic], collapse = ", "), - paste(make.names(uniq_var_regis[!syntatic]), collapse = ", ")) + warning( + sprintf( + "var_registration \"%s\" contains non-syntatic variables: %s\nconverting to %s", + var_registration, + paste(uniq_var_regis[!syntatic], collapse = ", "), + paste(make.names(uniq_var_regis[!syntatic]), collapse = ", ") + ), + call. = FALSE ) - sce[[var_registration]] <- make.names(sce[[var_registration]]) + sce[[var_registration]] <- make.names(sce[[var_registration]]) } ## Pseudo-bulk for our current BayesSpace cluster results diff --git a/tests/testthat/test-registration_wrapper.R b/tests/testthat/test-registration_wrapper.R index 38f4a88b..ff6e8de0 100644 --- a/tests/testthat/test-registration_wrapper.R +++ b/tests/testthat/test-registration_wrapper.R @@ -46,7 +46,8 @@ sce$cluster_l <- sample(c("L-1", "L2/3", "4L", "L5"), ncol(sce), replace = TRUE) table(sce$cluster_j) test_that("Numeric var_regisration throws warning", - expect_warning(registration_wrapper( + expect_warning( + registration_wrapper( sce, var_registration = "cluster_int", var_sample_id = "sample_id", @@ -54,10 +55,12 @@ test_that("Numeric var_regisration throws warning", gene_ensembl = "ensembl", gene_name = "gene_name", suffix = "wrapper" - ))) + ) + )) -test_that("Non-Syntactic thows warning", - expect_warning(registration_wrapper( +test_that("Non-Syntactic throws warning", + expect_warning( + registration_wrapper( sce, var_registration = "cluster_l", var_sample_id = "sample_id", @@ -65,7 +68,8 @@ test_that("Non-Syntactic thows warning", gene_ensembl = "ensembl", gene_name = "gene_name", suffix = "wrapper" - ))) + ) + )) From 40af9804d104df0dd6a59f8f08e03c1e74cd2b72 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:39:37 -0500 Subject: [PATCH 250/259] Ran dev/04_update.R --- R/img_edit.R | 37 +++++++++--------- R/img_update.R | 13 +++---- R/img_update_all.R | 11 +++--- R/layer_stat_cor_plot.R | 17 ++++---- R/registration_pseudobulk.R | 19 ++++----- R/vis_grid_clus.R | 35 +++++++++-------- R/vis_grid_gene.R | 39 ++++++++++--------- tests/testthat/test-registration_pseudobulk.R | 31 ++++++++------- tests/testthat/test-registration_wrapper.R | 22 +++++------ 9 files changed, 112 insertions(+), 112 deletions(-) diff --git a/R/img_edit.R b/R/img_edit.R index 93aceee3..ec6fae90 100644 --- a/R/img_edit.R +++ b/R/img_edit.R @@ -58,25 +58,24 @@ #' plot(x) #' } img_edit <- - function( - spe, - sampleid, - image_id = "lowres", - channel = NA, - brightness = 100, - saturation = 100, - hue = 100, - enhance = FALSE, - contrast_sharpen = NA, - quantize_max = NA, - quantize_dither = TRUE, - equalize = FALSE, - normalize = FALSE, - transparent_color = NA, - transparent_fuzz = 0, - background_color = NA, - median_radius = NA, - negate = FALSE) { + function(spe, + sampleid, + image_id = "lowres", + channel = NA, + brightness = 100, + saturation = 100, + hue = 100, + enhance = FALSE, + contrast_sharpen = NA, + quantize_max = NA, + quantize_dither = TRUE, + equalize = FALSE, + normalize = FALSE, + transparent_color = NA, + transparent_fuzz = 0, + background_color = NA, + median_radius = NA, + negate = FALSE) { img <- magick::image_read(SpatialExperiment::imgRaster(spe, sample_id = sampleid, image_id = image_id)) diff --git a/R/img_update.R b/R/img_update.R index fdfe5b83..db6dfcb1 100644 --- a/R/img_update.R +++ b/R/img_update.R @@ -41,13 +41,12 @@ #' imgData(img_update(spe, sampleid = "151507", brightness = 25)) #' } img_update <- - function( - spe, - sampleid, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + sampleid, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { img_data <- SpatialExperiment::imgData(spe) ## Skip this sample if there's no existing image to update diff --git a/R/img_update_all.R b/R/img_update_all.R index 314b9b0d..31c368c9 100644 --- a/R/img_update_all.R +++ b/R/img_update_all.R @@ -22,12 +22,11 @@ #' imgData(img_update_all(spe, brightness = 25)) #' } img_update_all <- - function( - spe, - image_id = "lowres", - new_image_id = paste0("edited_", image_id), - overwrite = FALSE, - ...) { + function(spe, + image_id = "lowres", + new_image_id = paste0("edited_", image_id), + overwrite = FALSE, + ...) { for (sampleid in unique(spe$sample_id)) { spe <- img_update( diff --git a/R/layer_stat_cor_plot.R b/R/layer_stat_cor_plot.R index ff8eca61..edefd095 100644 --- a/R/layer_stat_cor_plot.R +++ b/R/layer_stat_cor_plot.R @@ -98,14 +98,15 @@ #' cluster_columns = FALSE #' ) #' -layer_stat_cor_plot <- function(cor_stats_layer, - color_max = max(cor_stats_layer), - color_min = min(cor_stats_layer), - color_scale = c("#762A83", "#F7F7F7", "#1B7837"), - query_colors = NULL, - reference_colors = NULL, - annotation = NULL, - ...) { +layer_stat_cor_plot <- function( + cor_stats_layer, + color_max = max(cor_stats_layer), + color_min = min(cor_stats_layer), + color_scale = c("#762A83", "#F7F7F7", "#1B7837"), + query_colors = NULL, + reference_colors = NULL, + annotation = NULL, + ...) { ## define color pallet stopifnot(color_min < color_max) stopifnot(color_min < 0) diff --git a/R/registration_pseudobulk.R b/R/registration_pseudobulk.R index 63819b8a..70c78d7a 100644 --- a/R/registration_pseudobulk.R +++ b/R/registration_pseudobulk.R @@ -53,13 +53,12 @@ #' sce_pseudo <- registration_pseudobulk(sce, "Cell_Cycle", "sample_id", c("age"), min_ncells = NULL) #' colData(sce_pseudo) registration_pseudobulk <- - function( - sce, - var_registration, - var_sample_id, - covars = NULL, - min_ncells = 10, - pseudobulk_rds_file = NULL) { + function(sce, + var_registration, + var_sample_id, + covars = NULL, + min_ncells = 10, + pseudobulk_rds_file = NULL) { ## Check that inputs are correct stopifnot(is(sce, "SingleCellExperiment")) stopifnot(var_registration %in% colnames(colData(sce))) @@ -86,8 +85,10 @@ registration_pseudobulk <- ## check for Non-Syntactic variables - convert with make.names & warn uniq_var_regis <- unique(sce[[var_registration]]) - syntatic <- grepl("^((([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*)|[.])$", - uniq_var_regis) + syntatic <- grepl( + "^((([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*)|[.])$", + uniq_var_regis + ) if (!all(syntatic)) { warning( sprintf( diff --git a/R/vis_grid_clus.R b/R/vis_grid_clus.R index b3c5086a..c84dbac4 100644 --- a/R/vis_grid_clus.R +++ b/R/vis_grid_clus.R @@ -47,23 +47,24 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_clus <- - function(spe, - clustervar, - pdf_file, - sort_clust = TRUE, - colors = NULL, - return_plots = FALSE, - spatial = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { + function( + spe, + clustervar, + pdf_file, + sort_clust = TRUE, + colors = NULL, + return_plots = FALSE, + spatial = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) if (sort_clust) { diff --git a/R/vis_grid_gene.R b/R/vis_grid_gene.R index 8ddddbfb..bf32dd7a 100644 --- a/R/vis_grid_gene.R +++ b/R/vis_grid_gene.R @@ -35,25 +35,26 @@ #' cowplot::plot_grid(plotlist = p_list, ncol = 2) #' } vis_grid_gene <- - function(spe, - geneid = rowData(spe)$gene_search[1], - pdf_file, - assayname = "logcounts", - minCount = 0, - return_plots = FALSE, - spatial = TRUE, - viridis = TRUE, - height = 24, - width = 36, - image_id = "lowres", - alpha = NA, - cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), - sample_order = unique(spe$sample_id), - point_size = 2, - auto_crop = TRUE, - na_color = "#CCCCCC40", - is_stitched = FALSE, - ...) { + function( + spe, + geneid = rowData(spe)$gene_search[1], + pdf_file, + assayname = "logcounts", + minCount = 0, + return_plots = FALSE, + spatial = TRUE, + viridis = TRUE, + height = 24, + width = 36, + image_id = "lowres", + alpha = NA, + cont_colors = if (viridis) viridisLite::viridis(21) else c("aquamarine4", "springgreen", "goldenrod", "red"), + sample_order = unique(spe$sample_id), + point_size = 2, + auto_crop = TRUE, + na_color = "#CCCCCC40", + is_stitched = FALSE, + ...) { stopifnot(all(sample_order %in% unique(spe$sample_id))) plots <- lapply(sample_order, function(sampleid) { diff --git a/tests/testthat/test-registration_pseudobulk.R b/tests/testthat/test-registration_pseudobulk.R index 57a2138e..841dd12b 100644 --- a/tests/testthat/test-registration_pseudobulk.R +++ b/tests/testthat/test-registration_pseudobulk.R @@ -30,23 +30,26 @@ sce$batch <- "batch1" ## non-syntactic inputs sce$cluster_int <- sample(1:4, ncol(sce), replace = TRUE) # sce$cluster_k <- paste0("k", sce$cluster_int) -sce$cluster_j <- paste0(sce$cluster_int,"j") +sce$cluster_j <- paste0(sce$cluster_int, "j") sce$cluster_l <- sample(c("L-1", "L2/3", "4L", "L5"), ncol(sce), replace = TRUE) -test_that("warn for numeric var_registration", - expect_warning(registration_pseudobulk(sce, - var_registration = "cluster_int", - var_sample_id = "sample_id", - covars = c("age"), - min_ncells = NULL)) +test_that( + "warn for numeric var_registration", + expect_warning(registration_pseudobulk(sce, + var_registration = "cluster_int", + var_sample_id = "sample_id", + covars = c("age"), + min_ncells = NULL + )) ) -test_that("warn for non-syntactic var_registration", - expect_warning(registration_pseudobulk(sce, - var_registration = "cluster_l", - var_sample_id = "sample_id", - covars = c("age"), - min_ncells = NULL)) +test_that( + "warn for non-syntactic var_registration", + expect_warning(registration_pseudobulk(sce, + var_registration = "cluster_l", + var_sample_id = "sample_id", + covars = c("age"), + min_ncells = NULL + )) ) - diff --git a/tests/testthat/test-registration_wrapper.R b/tests/testthat/test-registration_wrapper.R index ff6e8de0..16e3bdee 100644 --- a/tests/testthat/test-registration_wrapper.R +++ b/tests/testthat/test-registration_wrapper.R @@ -40,12 +40,13 @@ test_that( ## catagorical var as int sce$cluster_int <- sample(1:4, ncol(sce), replace = TRUE) # sce$cluster_k <- paste0("k", sce$cluster_int) -sce$cluster_j <- paste0(sce$cluster_int,"j") +sce$cluster_j <- paste0(sce$cluster_int, "j") sce$cluster_l <- sample(c("L-1", "L2/3", "4L", "L5"), ncol(sce), replace = TRUE) table(sce$cluster_j) -test_that("Numeric var_regisration throws warning", +test_that( + "Numeric var_regisration throws warning", expect_warning( registration_wrapper( sce, @@ -56,9 +57,11 @@ test_that("Numeric var_regisration throws warning", gene_name = "gene_name", suffix = "wrapper" ) - )) + ) +) -test_that("Non-Syntactic throws warning", +test_that( + "Non-Syntactic throws warning", expect_warning( registration_wrapper( sce, @@ -69,12 +72,5 @@ test_that("Non-Syntactic throws warning", gene_name = "gene_name", suffix = "wrapper" ) - )) - - - - - - - - + ) +) From eebcdad8505266107562063ad2326faa26fa6d07 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:41:21 -0500 Subject: [PATCH 251/259] v1.19.2 -- merged https://github.com/LieberInstitute/spatialLIBD/pull/92 by @lahuuki which fixes #48 and #72. --- DESCRIPTION | 2 +- NEWS.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 7ff6154e..5293daa1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.19.1 +Version: 1.19.2 Date: 2024-12-12 Authors@R: c( diff --git a/NEWS.md b/NEWS.md index b8413d3d..34bb264d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# spatialLIBD 1.19.2 + +BUG FIXES + +* Merged by @lahuuki. +This fixes https://github.com/LieberInstitute/spatialLIBD/issues/72 and +https://github.com/LieberInstitute/spatialLIBD/issues/48 by making +`registration_pseudobulk()` more robust. + # spatialLIBD 1.19.1 NEW FEATURES From 8b28d794766827423da631a08b90faefedcf93d6 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:54:36 -0500 Subject: [PATCH 252/259] Resolve https://github.com/LieberInstitute/spatialLIBD/issues/90 --- R/add_key.R | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/R/add_key.R b/R/add_key.R index ce851b66..8dab3a32 100644 --- a/R/add_key.R +++ b/R/add_key.R @@ -42,14 +42,17 @@ add_key <- function(spe, overwrite = TRUE) { message( "Overwriting 'spe$key'. Set 'overwrite = FALSE' if you do not want to overwrite it." ) - } else { - stop( - "'spe$key' already exists. Set 'overwrite = TRUE' if you want to replace it.", + spe$key <- paste0(colnames(spe), "_", spe$sample_id) + stopifnot(!any(duplicated(spe$key))) + } else if (any(duplicated(spe$key))) { + warning( + "'spe$key' already exists and is not unique. Set 'overwrite = TRUE' to replace 'spe$key' with unique values.", call. = FALSE ) } + } else { + spe$key <- paste0(colnames(spe), "_", spe$sample_id) + stopifnot(!any(duplicated(spe$key))) } - spe$key <- paste0(colnames(spe), "_", spe$sample_id) - stopifnot(!any(duplicated(spe$key))) return(spe) } From 4607fa7cc0523886360384e25204a0a352cc810d Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 14:56:55 -0500 Subject: [PATCH 253/259] v1.19.3 -- resolved https://github.com/LieberInstitute/spatialLIBD/issues/90 reported by @lahuuki and @manishabarse. --- DESCRIPTION | 2 +- NEWS.md | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5293daa1..d527ed43 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: spatialLIBD Title: spatialLIBD: an R/Bioconductor package to visualize spatially-resolved transcriptomics data -Version: 1.19.2 +Version: 1.19.3 Date: 2024-12-12 Authors@R: c( diff --git a/NEWS.md b/NEWS.md index 34bb264d..1dc4a516 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# spatialLIBD 1.19.3 + +BUG FIXES + +* Resolved which made +`add_key()` too strict and would create issues with `export_cluster()`. Reported +by @lahuuki and @manishabarse. + # spatialLIBD 1.19.2 BUG FIXES @@ -5,7 +13,8 @@ BUG FIXES * Merged by @lahuuki. This fixes https://github.com/LieberInstitute/spatialLIBD/issues/72 and https://github.com/LieberInstitute/spatialLIBD/issues/48 by making -`registration_pseudobulk()` more robust. +`registration_pseudobulk()` more robust. The original issues were reported by +@boyiguo1 and @berniejmulvey. # spatialLIBD 1.19.1 From 7f2341b3a5fd5cc25ae77d847231fe7f6812c795 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 15:42:42 -0500 Subject: [PATCH 254/259] Attempt to fix missing citation info on the multi_gene_plots vignette MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From https://bioconductor.org/checkResults/devel/data-experiment-LATEST/spatialLIBD/nebbiolo1-buildsrc.html ``` * creating vignettes ... ERROR --- re-building ‘TenX_data_download.Rmd’ using rmarkdown --- finished re-building ‘TenX_data_download.Rmd’ --- re-building ‘guide_to_spatial_registration.Rmd’ using rmarkdown --- finished re-building ‘guide_to_spatial_registration.Rmd’ --- re-building ‘multi_gene_plots.Rmd’ using rmarkdown Quitting from lines 340-345 (multi_gene_plots.Rmd) Error: processing vignette 'multi_gene_plots.Rmd' failed with diagnostics: subscript out of bounds --- failed re-building ‘multi_gene_plots.Rmd’ --- re-building ‘spatialLIBD.Rmd’ using rmarkdown --- finished re-building ‘spatialLIBD.Rmd’ SUMMARY: processing the following file failed: ‘multi_gene_plots.Rmd’ ``` --- vignettes/multi_gene_plots.Rmd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vignettes/multi_gene_plots.Rmd b/vignettes/multi_gene_plots.Rmd index 6a3dda43..41d3eac0 100644 --- a/vignettes/multi_gene_plots.Rmd +++ b/vignettes/multi_gene_plots.Rmd @@ -45,8 +45,9 @@ library("RefManageR") ## Write bibliography information bib <- c( R = citation(), - MatrixGenerics = citation("MatrixGenerics")[1], + BiocStyle = citation("BiocStyle")[1], knitr = citation("knitr")[3], + MatrixGenerics = citation("MatrixGenerics")[1], RColorBrewer = citation("RColorBrewer")[1], RefManageR = citation("RefManageR")[1], rmarkdown = citation("rmarkdown")[1], From 0474fc71e564d65e63451b6822cfdad009bfab33 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Thu, 12 Dec 2024 15:44:58 -0500 Subject: [PATCH 255/259] Resolve an R CMD CHECK note from https://github.com/LieberInstitute/spatialLIBD/actions/runs/12303813508/job/34339808466#step:20:82 --- R/app_server.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/app_server.R b/R/app_server.R index 0d40265c..425e7e0b 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -1488,7 +1488,7 @@ app_server <- function(input, output, session) { clusters = rownames(static_layer_external_tstat()) ), reference_colors = get_colors( - libd_layer_colors, + spatialLIBD::libd_layer_colors, clusters = colnames(static_layer_external_tstat()) ) ) From d00047890a5bdec50acba5529d5fc8040d6ac016 Mon Sep 17 00:00:00 2001 From: lcolladotor Date: Fri, 13 Dec 2024 14:07:43 -0500 Subject: [PATCH 256/259] edit GHA to enable macOS tests by installing curl from source; similar to visiumStitched --- .github/workflows/check-bioc.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index c46db55d..4350463b 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -53,7 +53,7 @@ jobs: matrix: config: - { os: ubuntu-latest, r: '4.4', bioc: '3.20', cont: "bioconductor/bioconductor_docker:RELEASE_3_20", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } - # - { os: macOS-latest, r: '4.4', bioc: '3.20'} + - { os: macOS-latest, r: '4.4', bioc: '3.20'} - { os: windows-latest, r: '4.4', bioc: '3.20'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent @@ -143,6 +143,17 @@ jobs: ## Required for tcltk brew install xquartz --cask + ## Latest curl + brew install curl pkg-config + + - name: Install macOS curl from source + if: matrix.config.os == 'macOS-latest' + run: | + message(paste('****', Sys.time(), 'installing curl from source ****')) + Sys.setenv(PKG_CONFIG_PATH="/opt/homebrew/opt/curl/lib/pkgconfig:/usr/local/opt/curl/lib/pkgconfig") + install.packages("curl", type = "source") + shell: Rscript {0} + - name: Install Windows system dependencies if: runner.os == 'Windows' run: | From 606924ecca397efdb7f5f303f680faf29dd81a58 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 13 Dec 2024 15:27:30 -0500 Subject: [PATCH 257/259] Update gene_set_enrichment_plot() to use ComplexHeatmap & annotations, improve docs --- R/gene_set_enrichment_plot.R | 330 +++++++++++++++++++++++++---------- 1 file changed, 241 insertions(+), 89 deletions(-) diff --git a/R/gene_set_enrichment_plot.R b/R/gene_set_enrichment_plot.R index 4ccbfcbc..2fc5338c 100644 --- a/R/gene_set_enrichment_plot.R +++ b/R/gene_set_enrichment_plot.R @@ -1,30 +1,47 @@ -#' Plot the gene set enrichment results +#' Plot the gene set enrichment results with ComplexHeatmap #' #' This function takes the output of [gene_set_enrichment()] and creates a -#' heatmap visualization of the results. +#' ComplexHeatmap visualization of the results. Fill of the heatmap represents +#' the -log10(p-val), Odds-ratios are printed for test that pass specified +#' significance threshold `ORcut`. +#' +#' Includes functionality to plot the size of the input gene sets as barplot +#' annotations. #' #' @param enrichment The output of [gene_set_enrichment()]. #' @param xlabs A vector of names in the same order and length as -#' `unique(enrichment$ID)`. Gets passed to [layer_matrix_plot()]. +#' `unique(enrichment$ID)`. #' @param PThresh A `numeric(1)` specifying the P-value threshold for the #' maximum value in the `-log10(p)` scale. #' @param ORcut A `numeric(1)` specifying the P-value threshold for the #' minimum value in the `-log10(p)` scale for printing the odds ratio values -#' in the cells of the resulting plot. +#' in the cells of the resulting plot. Defaults to 3 or p-val < 0.001. #' @param enrichOnly A `logical(1)` indicating whether to show only odds ratio #' values greater than 1. -#' @param layerHeights A `numeric()` vector of length equal to -#' `length(unique(enrichment$test)) + 1` that starts at 0 specifying where -#' to plot the y-axis breaks which can be used for re-creating the length of -#' each brain layer. Gets passed to [layer_matrix_plot()]. -#' @param mypal A vector with the color palette to use. Gets passed to -#' [layer_matrix_plot()]. -#' @param cex Passed to [layer_matrix_plot()]. +#' @param mypal A `character` vector with the color palette to use. Colors will +#' be in order from 0 to lowest P-val `max(-log(enrichment$Pval))`. Defaults to +#' white, yellow, red pallet. +#' @param plot_SetSize_bar A `logical(1)` indicating whether to plot SetSize +#' from `enrichment` as an `anno_barplot` at the top of the heatmap. +#' @param gene_list_length Optional named `numeric` vector indicating the length +#' of the `gene_list` used to calculate `enrichment`, if inclided and +#' `plot_setSize_bar = TRUE` then the top `anno_barplot` will show the `SetSize` +#' and the difference from the length of the input gene_list. +#' #' @param model_sig_length Optional named `numeric` vector indicating the +#' number of significant genes in `modeling_results` used to calculate +#' `enrichment`. If included `anno_barplot` will be added to rows. +#' #' @param model_colors named `character` vector of colors, Adds colors to +#' row annotations. +#' #' @param ... Additional parameters passed to +#' [ComplexHeatmap::Heatmap()][ComplexHeatmap::Heatmap()]. #' -#' @return A plot visualizing the gene set enrichment -#' odds ratio and p-value results. +#' @return A ([Heatmap-class][ComplexHeatmap::Heatmap-class]) visualizing the +#' gene set enrichment odds ratio and p-value results. #' @export #' @importFrom stats reshape +#' @importFrom circlize colorRamp2 +#' @importFrom ComplexHeatmap columnAnnotation rowAnnotation Heatmap anno_barplot +#' #' @family Gene set enrichment functions #' @author Andrew E Jaffe, Leonardo Collado-Torres #' @seealso layer_matrix_plot @@ -45,7 +62,7 @@ #' ) #' #' ## Format them appropriately -#' asd_sfari_geneList <- list( +#' asd_safari_geneList <- list( #' Gene_SFARI_all = asd_sfari$ensembl.id, #' Gene_SFARI_high = asd_sfari$ensembl.id[asd_sfari$gene.score < 3], #' Gene_SFARI_syndromic = asd_sfari$ensembl.id[asd_sfari$syndromic == 1] @@ -58,98 +75,233 @@ #' #' ## Compute the gene set enrichment results #' asd_sfari_enrichment <- gene_set_enrichment( -#' gene_list = asd_sfari_geneList, +#' gene_list = asd_safari_geneList, #' modeling_results = modeling_results, #' model_type = "enrichment" #' ) #' #' ## Visualize the gene set enrichment results -#' ## with a custom color palette +#' +#' ## Default plot +#' gene_set_enrichment_plot( +#' enrichment = asd_sfari_enrichment +#' ) +#' +#' ## Use a custom green color palette & use shorter gene set names (x-axis labels) +#' gene_set_enrichment_plot( +#' asd_sfari_enrichment, +#' xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), +#' mypal = c("white",RColorBrewer::brewer.pal(9, "BuGn")) +#' ) +#' +#' ## Add bar plot annotations for SetSize of model genes in the gene_lists +#' gene_set_enrichment_plot( +#' asd_sfari_enrichment, +#' xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), +#' plot_SetSize_bar = TRUE +#' ) +#' +#' ## Add stacked bar plot annotations showing SetSize and difference from the +#' ## length of the input gene_list #' gene_set_enrichment_plot( #' asd_sfari_enrichment, #' xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), -#' mypal = c( -#' "white", -#' grDevices::colorRampPalette( -#' RColorBrewer::brewer.pal(9, "BuGn") -#' )(50) -#' ) +#' plot_SetSize_bar = TRUE, +#' gene_list_length = lapply(asd_safari_geneList, length) +#' ) +#' +#' ## add bar plot annotations for number of enriched genes from layers +#' if (!exists("sce_layer")) sce_layer <- fetch_data(type = "sce_layer") +#' sig_genes <- sig_genes_extract( +#' modeling_results = modeling_results, +#' model = "enrichment", +#' sce_layer = sce_layer, +#' n = nrow(sce_layer) +#' ) +#' +#' sig_genes <- sig_genes[sig_genes$fdr < 0.1,] +#' n_sig_model <- as.list(table(sig_genes$test)) +#' +#' ## add barplot with n significant genes from modeling +#' gene_set_enrichment_plot( +#' asd_sfari_enrichment, +#' xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), +#' plot_SetSize_bar = TRUE, +#' model_sig_length = n_sig_model #' ) #' -#' ## Specify the layer heights so it resembles more the length of each -#' ## layer in the brain +#'## add color annotaions #' gene_set_enrichment_plot( #' asd_sfari_enrichment, #' xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), -#' layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), +#' plot_SetSize_bar = TRUE, +#' model_colors = libd_layer_colors #' ) +#' +#' ## add barplot with n significant genes from modeling filled with model color +#' gene_set_enrichment_plot( +#' asd_sfari_enrichment, +#' xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), +#' plot_SetSize_bar = TRUE, +#' model_sig_length = n_sig_model, +#' model_colors = libd_layer_colors +#' ) +#' gene_set_enrichment_plot <- - function(enrichment, + function( + enrichment, xlabs = unique(enrichment$ID), PThresh = 12, ORcut = 3, enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c( - "white", - grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "YlOrRd"))(50) - ), - cex = 1.2) { - ## Re-order and shorten names if they match our data - if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { - enrichment$test <- - factor(gsub("ayer", "", enrichment$test), levels = rev(c(paste0( - "L", seq_len(6) - ), "WM"))) - } - - ## Check inputs - stopifnot(is(enrichment, "data.frame")) - stopifnot(all(c("ID", "test", "OR", "Pval") %in% colnames(enrichment))) - stopifnot(length(layerHeights) == length(unique(enrichment$test)) + 1) - stopifnot(ORcut <= PThresh) - stopifnot(length(xlabs) == length(unique(enrichment$ID))) - - ## Convert to -log10 scale and threshold the pvalues - enrichment$log10_P_thresh <- - round(-log10(enrichment$Pval), 2) - enrichment$log10_P_thresh[which(enrichment$log10_P_thresh > PThresh)] <- - PThresh - - ## Change some values for the plot - if (enrichOnly) { - enrichment$log10_P_thresh[enrichment$OR < 1] <- 0 - } - enrichment$OR_char <- as.character(round(enrichment$OR, 2)) - enrichment$OR_char[enrichment$log10_P_thresh < ORcut] <- "" - - ## Make into wide matrices - make_wide <- function(var = "OR_char") { - res <- - reshape( - enrichment, - idvar = "ID", - timevar = "test", - direction = "wide", - drop = colnames(enrichment)[!colnames(enrichment) %in% c("ID", "test", var)], - sep = "_mypattern_" - )[, -1, drop = FALSE] - colnames(res) <- - gsub(".*_mypattern_", "", colnames(res)) - rownames(res) <- unique(enrichment$ID) - res <- res[, levels(as.factor(enrichment$test))] - t(res) - } - wide_or <- make_wide("OR_char") - wide_p <- make_wide("log10_P_thresh") - - layer_matrix_plot( - matrix_values = wide_p, - matrix_labels = wide_or, - xlabs = xlabs, - layerHeights = layerHeights, - mypal = mypal, - cex = cex, - mar = c(12, 4 + (max(nchar(rownames(wide_p))) %/% 3) * 0.5, 4, 2) + 0.1 - ) + mypal = c("white", RColorBrewer::brewer.pal(9, "YlOrRd")), + plot_SetSize_bar = FALSE, + gene_list_length = NULL, + model_sig_length = NULL, + model_colors = NULL, + ... + ){ + ## Re-order and shorten names if they match our data + if (all(unique(enrichment$test) %in% c("WM", paste0("Layer", seq_len(6))))) { + enrichment$test <- + factor(gsub("ayer", "", enrichment$test), levels = rev(c(paste0( + "L", seq_len(6) + ), "WM"))) } + + ## Check inputs + stopifnot(is(enrichment, "data.frame")) + stopifnot(all(c("ID", "test", "OR", "Pval") %in% colnames(enrichment))) + stopifnot(ORcut <= PThresh) + stopifnot(length(xlabs) == length(unique(enrichment$ID))) + + ## Convert to -log10 scale and threshold the pvalues + enrichment$log10_P_thresh <- + round(-log10(enrichment$Pval), 2) + enrichment$log10_P_thresh[which(enrichment$log10_P_thresh > PThresh)] <- + PThresh + + ## Change some values for the plot + if (enrichOnly) { + enrichment$log10_P_thresh[enrichment$OR < 1] <- 0 + } + enrichment$OR_char <- as.character(round(enrichment$OR, 2)) + enrichment$OR_char[enrichment$log10_P_thresh < ORcut] <- "" + + ## sub xlabs labels + if(!is.null(gene_list_length)){ + stopifnot(setequal(names(gene_list_length), unique(enrichment$ID))) + gene_list_length <- gene_list_length[unique(enrichment$ID)] + names(gene_list_length) <- xlabs + } + + for(i in seq(length(xlabs))){ + enrichment$ID <- gsub(unique(enrichment$ID)[[i]], xlabs[[i]], enrichment$ID) + } + + ## Make into wide matrices + make_wide <- function(var = "OR_char") { + res <- + reshape( + enrichment, + idvar = "ID", + timevar = "test", + direction = "wide", + drop = colnames(enrichment)[!colnames(enrichment) %in% c("ID", "test", var)], + sep = "_mypattern_" + )[, -1, drop = FALSE] + colnames(res) <- + gsub(".*_mypattern_", "", colnames(res)) + rownames(res) <- unique(enrichment$ID) + res <- res[, levels(as.factor(enrichment$test))] + t(res) + } + wide_or <- make_wide("OR_char") + wide_p <- make_wide("log10_P_thresh") + + ## define color pallet + mypal = circlize::colorRamp2(breaks = seq(0, max(wide_p), length.out = length(mypal)), + colors = mypal) + + ## Add gene count annotations + enrichment_setsize <- unique(enrichment[,c("ID", "SetSize")]) + + ## COL annotations + if(plot_SetSize_bar){ + + if(!is.null(gene_list_length)){ + stopifnot(all(colnames(wide_p) %in% names(gene_list_length))) + enrichment_setsize$SetInput <- unlist(gene_list_length[enrichment_setsize$ID]) + enrichment_setsize$Diff <- enrichment_setsize$SetInput - enrichment_setsize$SetSize + } + + rownames(enrichment_setsize) <- enrichment_setsize$ID + enrichment_setsize$ID <- NULL + enrichment_setsize$SetInput <- NULL ## only plot SetSize + Diff + + col_gene_anno <- ComplexHeatmap::columnAnnotation( + `SetSize` = ComplexHeatmap::anno_barplot(enrichment_setsize) + ) + + } else col_gene_anno <- NULL + + if(!is.null(model_colors)){ + ## shorten names if they match HumanPilot data + if (all(c("WM", paste0("Layer", seq_len(6))) %in% names(model_colors))) { + names(model_colors) <-gsub("ayer", "", names(model_colors)) + }} + + + ## ROW annotations + if(!is.null(model_sig_length)){ ## add row barplot annotation + + ## shorten names if they match HumanPilot data + if (all(names(model_sig_length) %in% c("WM", paste0("Layer", seq_len(6))))) { + names(model_sig_length) <-gsub("ayer", "", names(model_sig_length)) + } + + stopifnot(all(rownames(wide_p) %in% names(model_sig_length))) + model_sig_length <- t(data.frame(model_sig_length)) + + if(!is.null(model_colors)){ ## barplot with colors + row_gene_anno <- ComplexHeatmap::rowAnnotation( + `n\nmodel sig` = ComplexHeatmap::anno_barplot(model_sig_length[rownames(wide_p), ], + gp = gpar(fill = model_colors[rownames(wide_p)]) + ) + # annotation_label = anno_title_row + + ) + } else { ## barplot no colors + row_gene_anno <- ComplexHeatmap::rowAnnotation( + `model sig` = ComplexHeatmap::anno_barplot(model_sig_length[rownames(wide_p), ]) + # annotation_label = anno_title_row + ) + } + + } else if(!is.null(model_colors)){ ## only apply color annotation + + stopifnot(all(rownames(wide_p) %in% names(model_colors))) + model_colors <- model_colors[rownames(wide_p)] + + row_gene_anno <- ComplexHeatmap::rowAnnotation( + " " = rownames(wide_p), + col = list(" " = model_colors), + show_legend = FALSE + ) + + }else row_gene_anno <- NULL + + ComplexHeatmap::Heatmap(wide_p, + col = mypal, + name = "-log10(p-val)", + rect_gp = grid::gpar(col = "black", lwd = 1), + cluster_rows = FALSE, + cluster_columns = FALSE, + right_annotation = row_gene_anno, + top_annotation = col_gene_anno, + cell_fun = function(j, i, x, y, width, height, fill) { + grid::grid.text(wide_or[i, j], x, y, gp = grid::gpar(fontsize = 10)) + }, + ... + ) + } From ed78c9c44af093fc338d68e508b8db71730f3a46 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 13 Dec 2024 15:28:13 -0500 Subject: [PATCH 258/259] Add ComplexHeatmap::anno_barplot to NAMESPACE --- NAMESPACE | 1 + man/gene_set_enrichment_plot.Rd | 121 ++++++++++++++++++++++++-------- 2 files changed, 93 insertions(+), 29 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 10d3d368..06db229f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -57,6 +57,7 @@ import(shiny) importFrom(AnnotationHub,query) importFrom(BiocGenerics,which) importFrom(ComplexHeatmap,Heatmap) +importFrom(ComplexHeatmap,anno_barplot) importFrom(ComplexHeatmap,columnAnnotation) importFrom(ComplexHeatmap,rowAnnotation) importFrom(DT,DTOutput) diff --git a/man/gene_set_enrichment_plot.Rd b/man/gene_set_enrichment_plot.Rd index 80ad58e3..ed55f358 100644 --- a/man/gene_set_enrichment_plot.Rd +++ b/man/gene_set_enrichment_plot.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/gene_set_enrichment_plot.R \name{gene_set_enrichment_plot} \alias{gene_set_enrichment_plot} -\title{Plot the gene set enrichment results} +\title{Plot the gene set enrichment results with ComplexHeatmap} \usage{ gene_set_enrichment_plot( enrichment, @@ -10,47 +10,63 @@ gene_set_enrichment_plot( PThresh = 12, ORcut = 3, enrichOnly = FALSE, - layerHeights = c(0, seq_len(length(unique(enrichment$test)))) * 15, - mypal = c("white", (grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, - "YlOrRd")))(50)), - cex = 1.2 + mypal = c("white", RColorBrewer::brewer.pal(9, "YlOrRd")), + plot_SetSize_bar = FALSE, + gene_list_length = NULL, + model_sig_length = NULL, + model_colors = NULL, + ... ) } \arguments{ \item{enrichment}{The output of \code{\link[=gene_set_enrichment]{gene_set_enrichment()}}.} \item{xlabs}{A vector of names in the same order and length as -\code{unique(enrichment$ID)}. Gets passed to \code{\link[=layer_matrix_plot]{layer_matrix_plot()}}.} +\code{unique(enrichment$ID)}.} \item{PThresh}{A \code{numeric(1)} specifying the P-value threshold for the maximum value in the \code{-log10(p)} scale.} \item{ORcut}{A \code{numeric(1)} specifying the P-value threshold for the minimum value in the \code{-log10(p)} scale for printing the odds ratio values -in the cells of the resulting plot.} +in the cells of the resulting plot. Defaults to 3 or p-val < 0.001.} \item{enrichOnly}{A \code{logical(1)} indicating whether to show only odds ratio values greater than 1.} -\item{layerHeights}{A \code{numeric()} vector of length equal to -\code{length(unique(enrichment$test)) + 1} that starts at 0 specifying where -to plot the y-axis breaks which can be used for re-creating the length of -each brain layer. Gets passed to \code{\link[=layer_matrix_plot]{layer_matrix_plot()}}.} +\item{mypal}{A \code{character} vector with the color palette to use. Colors will +be in order from 0 to lowest P-val \code{max(-log(enrichment$Pval))}. Defaults to +white, yellow, red pallet.} -\item{mypal}{A vector with the color palette to use. Gets passed to -\code{\link[=layer_matrix_plot]{layer_matrix_plot()}}.} +\item{plot_SetSize_bar}{A \code{logical(1)} indicating whether to plot SetSize +from \code{enrichment} as an \code{anno_barplot} at the top of the heatmap.} -\item{cex}{Passed to \code{\link[=layer_matrix_plot]{layer_matrix_plot()}}.} +\item{gene_list_length}{Optional named \code{numeric} vector indicating the length +of the \code{gene_list} used to calculate \code{enrichment}, if inclided and +\code{plot_setSize_bar = TRUE} then the top \code{anno_barplot} will show the \code{SetSize} +and the difference from the length of the input gene_list. +#' @param model_sig_length Optional named \code{numeric} vector indicating the +number of significant genes in \code{modeling_results} used to calculate +\code{enrichment}. If included \code{anno_barplot} will be added to rows. +#' @param model_colors named \code{character} vector of colors, Adds colors to +row annotations. +#' @param ... Additional parameters passed to +\code{\link[ComplexHeatmap:Heatmap]{ComplexHeatmap::Heatmap()}}.} } \value{ -A plot visualizing the gene set enrichment -odds ratio and p-value results. +A (\link[ComplexHeatmap:Heatmap-class]{Heatmap-class}) visualizing the +gene set enrichment odds ratio and p-value results. } \description{ This function takes the output of \code{\link[=gene_set_enrichment]{gene_set_enrichment()}} and creates a -heatmap visualization of the results. +ComplexHeatmap visualization of the results. Fill of the heatmap represents +the -log10(p-val), Odds-ratios are printed for test that pass specified +significance threshold \code{ORcut}. } \details{ +Includes functionality to plot the size of the input gene sets as barplot +annotations. + Check https://github.com/LieberInstitute/HumanPilot/blob/master/Analysis/Layer_Guesses/check_clinical_gene_sets.R to see a full script from where this family of functions is derived from. @@ -68,7 +84,7 @@ asd_sfari <- utils::read.csv( ) ## Format them appropriately -asd_sfari_geneList <- list( +asd_safari_geneList <- list( Gene_SFARI_all = asd_sfari$ensembl.id, Gene_SFARI_high = asd_sfari$ensembl.id[asd_sfari$gene.score < 3], Gene_SFARI_syndromic = asd_sfari$ensembl.id[asd_sfari$syndromic == 1] @@ -81,31 +97,78 @@ if (!exists("modeling_results")) { ## Compute the gene set enrichment results asd_sfari_enrichment <- gene_set_enrichment( - gene_list = asd_sfari_geneList, + gene_list = asd_safari_geneList, modeling_results = modeling_results, model_type = "enrichment" ) ## Visualize the gene set enrichment results -## with a custom color palette + +## Default plot +gene_set_enrichment_plot( + enrichment = asd_sfari_enrichment +) + +## Use a custom green color palette & use shorter gene set names (x-axis labels) +gene_set_enrichment_plot( + asd_sfari_enrichment, + xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), + mypal = c("white",RColorBrewer::brewer.pal(9, "BuGn")) +) + +## Add bar plot annotations for SetSize of model genes in the gene_lists +gene_set_enrichment_plot( + asd_sfari_enrichment, + xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), + plot_SetSize_bar = TRUE +) + +## Add stacked bar plot annotations showing SetSize and difference from the +## length of the input gene_list gene_set_enrichment_plot( asd_sfari_enrichment, xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), - mypal = c( - "white", - grDevices::colorRampPalette( - RColorBrewer::brewer.pal(9, "BuGn") - )(50) - ) + plot_SetSize_bar = TRUE, + gene_list_length = lapply(asd_safari_geneList, length) ) -## Specify the layer heights so it resembles more the length of each -## layer in the brain +## add bar plot annotations for number of enriched genes from layers +if (!exists("sce_layer")) sce_layer <- fetch_data(type = "sce_layer") +sig_genes <- sig_genes_extract( + modeling_results = modeling_results, + model = "enrichment", + sce_layer = sce_layer, + n = nrow(sce_layer) +) + +sig_genes <- sig_genes[sig_genes$fdr < 0.1,] +n_sig_model <- as.list(table(sig_genes$test)) + +## add barplot with n significant genes from modeling gene_set_enrichment_plot( asd_sfari_enrichment, xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), - layerHeights = c(0, 40, 55, 75, 85, 110, 120, 135), + plot_SetSize_bar = TRUE, + model_sig_length = n_sig_model ) + +## add color annotaions +gene_set_enrichment_plot( + asd_sfari_enrichment, + xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), + plot_SetSize_bar = TRUE, + model_colors = libd_layer_colors +) + +## add barplot with n significant genes from modeling filled with model color +gene_set_enrichment_plot( + asd_sfari_enrichment, + xlabs = gsub(".*_", "", unique(asd_sfari_enrichment$ID)), + plot_SetSize_bar = TRUE, + model_sig_length = n_sig_model, + model_colors = libd_layer_colors +) + } \seealso{ layer_matrix_plot From 3fa0e524bd06e7ecef9f79062ed9ecf69e13d4c2 Mon Sep 17 00:00:00 2001 From: Louise Huuki Date: Fri, 13 Dec 2024 15:41:01 -0500 Subject: [PATCH 259/259] Add documentation for gene_set_enrichment output table --- R/gene_set_enrichment.R | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/R/gene_set_enrichment.R b/R/gene_set_enrichment.R index 1accea28..0d021144 100644 --- a/R/gene_set_enrichment.R +++ b/R/gene_set_enrichment.R @@ -15,6 +15,16 @@ #' #' @return A table in long format with the enrichment results using #' [stats::fisher.test()]. +#' * `OR` odds ratio. +#' * `Pval` p-value for `fisher.test()`. +#' * `test` group or layer in the `modeling_results`. +#' * `NumSig` Number of genes from the gene set present in `modeling_results` & +#' with `fdr < fdr_cut` and `t_stat > 0` (unless reverse = TRUE) for `test` in +#' modeling results. +#' * `SetSize` Number of genes from `modeling_results` present in `gene_set`. +#' * `ID` name of gene set. +#' * `model_type` record of input model type from `modeling results`. +#' * `fdr_cut` record of input `frd_cut`. #' #' @export #' @importFrom stats fisher.test

ewE|J{8iYD-MV7r;)X~`L&t0%+5^7Y#__VaDB^u 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