edward130603 / BayesSpace

Bayesian model for clustering and enhancing the resolution of spatial gene expression experiments.
http://edward130603.github.io/BayesSpace
Other
111 stars 22 forks source link

seurat_cluster_DE function #123

Open mtrussart opened 6 months ago

mtrussart commented 6 months ago

Hi,

I was looking into the vignette script you provided for the Thrane melanoma dataset and especially how to do the DE analysis using the seurat_cluster_DE function (http://www.ezstatconsulting.com/BayesSpace/articles/ji_SCC.html). I would like to know if with the updated version of Seurat whether the "sobj@assays$Spatial@data" is now replaced by sobj@assays$Spatial@counts?

Thanks a lot, Marie

edward130603 commented 6 months ago

Hi Marie, the counts slot in SingleCellExperiment and counts layer in Seurat are the same. Same for the logcounts slot in SCE and data layer in Seurat. Since we are using the normalized data (logcounts) for DE analysis, it should still be @data I believe. Hope that answers your question. If not, let me know the specific line of code or error/warning message you are getting. -Edward

mtrussart commented 6 months ago

Hi Edward, thanks for your fast reply. Yes I get an error with the @data of seurat@assays$Spatial@data in the seurat_cluster_DE function as there is no such data in the Spatial assay but instead a counts defined at the beginning of the function : seurat <- Seurat::[CreateSeuratObject]((counts=logcounts, assay='Spatial',meta.data=as.data.frame)

As far as I understand, the @data argument is created within the Seurat normalisation function but in this case you don't apply this normalisation, rather the counts assay is defined as the logcounts of the sce and then the DE is performed on those. If that's correct, then the sobj@assays$Spatial@data should be replaced by sobj@assays$Spatial@counts, right?

Thanks a lot, Marie

edward130603 commented 6 months ago

Yes, sorry for the mistake, thanks for pointing it out! We will need to update our vignettes.

You can set the counts slot of the Seurat object to be the same as the counts slot of the SCE, and then apply Seurat normalization to generate the data slot before running the marker detection function.

dphelzer commented 1 week ago

Just wanted to leave the updated script for anyone facing this issue. Thanks for the great tool!

seurat_cluster_DE <- function(sce, clusters = NULL, n_markers = 6) {
  ## Convert SCE to seurat object and use BayesSpace cluster as identifier
  seurat <- Seurat::CreateSeuratObject(counts = logcounts(sce),
                                       assay = 'Spatial',
                                       meta.data = as.data.frame(colData(sce)))
  seurat <- Seurat::SetIdent(seurat, value = "spatial.cluster")

  ## Subset to specified clusters
  if (!is.null(clusters)) {
    seurat <- subset(seurat, spatial.cluster %in% clusters)
    #palette <- palette[clusters] # function was failing at this step, so I commented it out
  }

  ## populate data slot
  seurat@assays$Spatial$data <- seurat@assays$Spatial$counts # FindAllMarkers was not working 
                                                             # since in V5 it seems like it will default to looking
                                                             # at the "data" slot, which as mentioned is not
                                                             # populated
  # I populated the "data" slot with the exact same values from the "counts" slot, which 
  # are normalized via the BayesSpace vignette

  ## Scale data
  seurat@assays$Spatial$scale.data <-
    seurat@assays$Spatial$counts %>% as.matrix %>% t %>% scale %>% t

  ## Select top n markers from each cluster (by log fold change)
  top_markers <- Seurat::FindAllMarkers(seurat, assay = "Spatial", slot = "data",
                                        group.by = "spatial.cluster",
                                        logfc.threshold = 1, only.pos = T, # can change fc threshold
                                        test.use = "MAST") %>% # input desired test
    group_by(cluster) %>% 
    top_n(n_markers, avg_log2FC) ## updated to "log2FC" since before it was "log_FC" 
                                  # which no longer worked with Seurat V5

  ## Plot expression of markers
  Seurat::DoHeatmap(seurat, features = top_markers$gene, slot = "scale.data",
                    group.by = "spatial.cluster", 
                    #group.colors = palette, # commented out since it wasn't functional before
                    angle = 0, size = 4, label = F, raster = F) + 
    guides(col = F) & scale_fill_gradientn(colors = rev(RColorBrewer::brewer.pal(n = 8, name = "RdBu"))) &
    theme(axis.title = element_text(face = "bold.italic"))
}

seurat_cluster_DE(sce, c(1:6))