Skip to content

Commit

Permalink
Merge pull request #9 from atuldeshpande/main
Browse files Browse the repository at this point in the history
Merging software updates from atuldeshpande/SpaceMarkers
  • Loading branch information
dimalvovs authored Jul 16, 2024
2 parents 27811f7 + 5b317df commit d3b5391
Show file tree
Hide file tree
Showing 45 changed files with 5,428 additions and 489 deletions.
5 changes: 5 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Dockerfile
.gitignore
.github
.dockerignore
/vignettes/test-args.Rmd
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pat.txt
.DS_Store
.github
11 changes: 11 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Shows how the r-build-check.yml can be called from another repository.
name: build-check
on:
pull_request:
branches:
- 'devel'
- 'main'
workflow_dispatch:
jobs:
build-check:
uses: FertigLab/actions/.github/workflows/[email protected]
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

# RStudio files
.Rproj.user/
SpaceMarkers.Rproj

# produced vignettes
vignettes/*.html
Expand All @@ -37,3 +38,16 @@ vignettes/*.pdf

# R Environment Variables
.Renviron
.DS_Store
tests/testthat/.DS_Store
tests/testthat/testdata/.DS_Store
vignettes/.DS_Store

# GitHub directories
.github/

# Images
*.png

# GH token
pat.txt
65 changes: 54 additions & 11 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,15 +1,58 @@
Package: SpaceMarkers
Type: Package
Package: SpaceMarkers
Title: Spatial Interaction Markers
Version: 0.1.0
Author: Atul Deshpande [aut, cre],
Ludmila Danilova [ctb]
Maintainer: Ludmila Danilova <[email protected]>
Description: An R/Bioconductor software tool to identify genes associated with latent space interactions in spatial transcriptomics.
Depends: ape, dplyr, hdf5r, jsonlite, matrixStats, matrixTests, pracma, rstatix, spatstat
Imports: Matrix, qvalue, spatstat.core, spatstat.geom, stats, utils
License: MIT + file LICENSE
Version: 0.99.8
Authors@R: c(
person(given = "Atul", family = "Deshpande", email = "[email protected]", role = c("aut", "cre"), comment = c(ORCID="0000-0001-5144-6924")),
person(given = "Ludmila", family = "Danilova", email = "[email protected]", role = "ctb"),
person(given = "Dimitrijs", family = "Lvovs", email = "[email protected]", role = "ctb")
)
BugReports: https://github.com/atuldeshpande/SpaceMarkers/issues
URL: https://github.com/atuldeshpande/SpaceMarkers
Description: Spatial transcriptomic technologies have helped to resolve the connection
between gene expression and the 2D orientation of tissues relative to each other.
However, the limited single-cell resolution makes it difficult to highlight the most
important molecular interactions in these tissues. SpaceMarkers, R/Bioconductor software,
can help to find molecular interactions, by identifying genes associated with latent space
interactions in spatial transcriptomics.
Depends:
R (>= 4.4.0)
biocViews: SingleCell, GeneExpression, Software, Spatial, Transcriptomics
Imports:
matrixStats,
matrixTests,
rstatix,
spatstat.explore,
spatstat.geom,
ape,
hdf5r,
jsonlite,
Matrix,
qvalue,
stats,
utils,
methods
Suggests:
data.table,
devtools,
dplyr,
ggplot2,
hrbrthemes,
knitr,
RColorBrewer,
cowplot,
readbitmap,
rjson,
rmarkdown,
BiocStyle,
testthat (>= 3.0.0),
viridis,
CoGAPS
VignetteBuilder:
knitr
Config/testthat/edition: 3
Encoding: UTF-8
LazyData: true
LazyData: false
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.2
RoxygenNote: 7.3.1
License: MIT + file LICENSE
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#generated from 69d000eee2de41886a5732a1436be4a98f080dcf
# --platform=linux/amd64 to avoid 'no match for platform in the manifest' on M1
FROM rocker/tidyverse:4

COPY . /spacemarkers
WORKDIR /spacemarkers

RUN sudo apt-get update -y && \
apt-get upgrade -y && \
apt-get install libhdf5-dev build-essential patch -y

RUN Rscript -e 'devtools::install_deps()'

#https://github.com/r-lib/devtools/issues/2395
RUN Rscript -e 'devtools::install()'

#optoional packages - for vizualization
RUN Rscript -e 'install.packages("patchwork");\
install.packages("ggplot2");\
install.packages("dplyr");\
install.packages("DT");\
install.packages("Matrix");\
install.packages("jsonlite");\
install.packages("pheatmap");\
install.packages("RColorBrewer")'
23 changes: 2 additions & 21 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,21 +1,2 @@
MIT License

Copyright (c) 2022 atuldeshpande

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
YEAR: 2024
COPYRIGHT HOLDER: SpaceMarkers authors
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# MIT License

Copyright (c) 2024 SpaceMarkers authors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
30 changes: 19 additions & 11 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
# Generated by roxygen2: do not edit by hand

export(getInteractingGenes)
export(getSpatialFeatures)
export(getSpatialParameters)
export(load10XCoords)
export(load10XExpr)
import(ape)
import(dplyr)
import(hdf5r)
import(jsonlite)
import(matrixStats)
import(matrixTests)
import(pracma)
import(rstatix)
import(spatstat)
import(stats)
import(utils)
importFrom(Matrix,sparseMatrix)
importFrom(ape,Moran.I)
importFrom(hdf5r,h5file)
importFrom(jsonlite,read_json)
importFrom(matrixStats,count)
importFrom(matrixTests,row_kruskalwallis)
importFrom(methods,slot)
importFrom(qvalue,qvalue)
importFrom(rstatix,filter)
importFrom(spatstat.explore,Smooth)
importFrom(spatstat.geom,marks)
importFrom(spatstat.geom,owin)
importFrom(spatstat.geom,ppp)
importFrom(stats,dist)
importFrom(stats,lag)
importFrom(stats,pnorm)
importFrom(stats,sd)
importFrom(utils,read.csv)
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SpaceMarkers 0.1.0

* Added a `NEWS.md` file to track changes to the package.
29 changes: 29 additions & 0 deletions R/data.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#' Optimal paramters of 5 patterns from CoGAPS.
#'
#' A dataset with the optimal width of the gaussian distribution (sigmaOpt) and
#' the outlier threshold around the set of spots (thresOpt) for each pattern
#' obtained from CoGAPS. CoGAPS was ran on spatial transcriptomic data from a
#' breast cancer sample.
#'
#' @name optParams
#' @format A data frame with 2 rows and 5 columns:
#' \describe{
#' \item{Pattern_1}{immune cell pattern paramters }
#' \item{Pattern_2}{Disp.1 parameters}
#' \item{Pattern_3}{intraductal carcinoma (DCIS) parameters }
#' \item{Pattern_4}{Disp.2 parameters }
#' \item{Pattern_5}{invasive carcinoma lesion pattern paramters }
#' }
#' @return A matrix of optimal parameters for patterns identified by CoGAPS
NULL

#' Curated Genes for example purposes
#'
#' A vector with genes selected based on previous runs of SpaceMarkers on the
#' Visium 10x breast ductal carcinoma spatial transcriptomics dataset
#'
#' @name curated_genes
#' @format A vector with 114 pre-selected genes
#' @return a vector of genes
NULL

129 changes: 129 additions & 0 deletions R/find_genes_of_interest.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#' @importFrom matrixTests row_kruskalwallis
#' @importFrom rstatix filter
#' @importFrom matrixStats count
#' @importFrom stats lag dist pnorm sd
#' @importFrom qvalue qvalue
## author: Atul Deshpande
## email: [email protected]

row.dunn.test <- function(in.data,region){
region <- factor(region)
pattern1 <- levels(region)[2]
pattern2 <- levels(region)[3]
in.ranks <- matrixStats::rowRanks(in.data,cols = !is.na(region),
ties.method = "average")
rsub <- region[!is.na(region)]

N <- length(rsub)
N1 <- sum(rsub==pattern1)
N2 <- sum(rsub==pattern2)
NI <- sum(rsub=="Interacting")

tiesStat <- apply(in.ranks,1,function(rr) sum(table(rr)^3-table(rr)))
tiesStat2 <- sqrt(1 - tiesStat/N/(N-1)/(N+1))

SEI1 <- sqrt(N*(N+1)/12*(1/NI+1/N1))
SEI2 <- sqrt(N*(N+1)/12*(1/NI+1/N2))
SE12 <- sqrt(N*(N+1)/12*(1/N1+1/N2))

mInt<- apply(in.ranks[,rsub=="Interacting"],1,mean)
mP1<- apply(in.ranks[,rsub==pattern1],1,mean)
mP2<- apply(in.ranks[,rsub==pattern2],1,mean)

zP1_Int <- (mP1-mInt)/SEI1/tiesStat2
zP2_Int <- (mP2-mInt)/SEI2/tiesStat2
zP2_P1 <- (mP2-mP1)/SE12/tiesStat2
zVals <-cbind(zP1_Int,zP2_Int,zP2_P1)

pval_1_Int <- ifelse(2*(pnorm(zP1_Int,lower.tail = TRUE))
<=1,2*(pnorm(zP1_Int,lower.tail = TRUE)),1)
pval_2_Int <- ifelse(2*(pnorm(zP2_Int,lower.tail = TRUE))
<=1,2*(pnorm(zP2_Int,lower.tail = TRUE)),1)
pval_2_1 <- ifelse(zP2_P1>0,2*(pnorm(zP2_P1,lower.tail = FALSE)),
2*(pnorm(zP2_P1,lower.tail = TRUE)))
pvals<-cbind(pval_1_Int,pval_2_Int,pval_2_1)
return(cbind(zVals,pvals))
}

#===================
#' find_genes_of_interest
#' Identify genes associated with pattern interaction.

#' This function identifies genes exhibiting significantly higher values of
#' testMat in the Interaction region of the two
#' patterns compared #' to regions with exclusive influence from either
#' pattern. It uses Kruskal-Wallis test followed by
#' posthoc analysis using Dunn's Test to identify the genes.
#'
#' @usage
#' find_genes_of_interest(
#' testMat,
#' goodGenes = NULL,
#' region,
#' fdr.level = 0.05,
#' analysis = c("enrichment", "overlap")
#' )
#' @param testMat A matrix of counts with cells as columns and genes as rows
#' @param goodGenes A vector of user specified genes expected to interact
#' a priori. The default for this is NULL as the function can find these genes
#' itself
#' @param region A data frame of the reference pattern regions that overlap
#' with the other patterns
#' @param fdr.level False Discovery Rate. The default value is 0.05.
#' @param analysis a character string that specifies the type of analysis to
#' carry out, whether overlap or enrichment.
#'
#' @return a list of genes exhibiting significantly higher values of testMat in
#' the Interaction region of the two #' patterns compared to regions with
#' exclusive influence from either pattern.



find_genes_of_interest<-function(
testMat,goodGenes=NULL,region, fdr.level=0.05,
analysis=c("enrichment","overlap")) {
region <- factor(region)
patnames <- levels(region)[which(levels(region)!="Interacting")]
pattern1 <- patnames[1]
pattern2 <- patnames[2]
if (!is.null(goodGenes)){
subset_goodGenes <- intersect(rownames(testMat),goodGenes)
testMat <- testMat[subset_goodGenes,]
}
res_kruskal<- matrixTests::row_kruskalwallis(x=as.matrix(testMat),g=region)
qq <- qvalue::qvalue(res_kruskal$pvalue,fdr.level = fdr.level,
pfdr = FALSE, pi0 = 1)
res_kruskal <- cbind(res_kruskal,p.adj = qq$qvalues)
res_dunn_test <- row.dunn.test(as.matrix(testMat),region)
rownames(res_dunn_test) <- rownames(res_kruskal)
ind <- rownames(res_kruskal[which(res_kruskal$p.adj<fdr.level),])
qDunn <- qvalue::qvalue(res_dunn_test[,4:6],
fdr.level = fdr.level, pfdr = FALSE, pi0 = 1)
qq<-qvalue::qvalue(
res_dunn_test[ind,4:6],fdr.level=fdr.level,pfdr=FALSE,pi0 = 1)
qDunn$qvalues[ind,] <- qq$qvalue
res_dunn_test <- cbind(res_dunn_test,qDunn$qvalues)
colnames(res_dunn_test)[7:9] <- paste0(colnames(res_dunn_test)[7:9],".adj")
interact_patt1 <- res_dunn_test[ind,"pval_1_Int.adj"]<fdr.level
interact_patt2 <- res_dunn_test[ind,"pval_2_Int.adj"]<fdr.level
interacting_over_both_patterns <- interact_patt1 & interact_patt2
not_pattern1_diff_pattern2 <- res_dunn_test[ind,"pval_2_1.adj"]>=fdr.level
exc_interact_patt1 <- interact_patt1 & not_pattern1_diff_pattern2
exc_interact_patt2 <- interact_patt2 & not_pattern1_diff_pattern2
names(exc_interact_patt2)<-ind
names(exc_interact_patt1)<-names(exc_interact_patt2)
names(interacting_over_both_patterns)<-names(exc_interact_patt1)
interact_genes<-matrix(FALSE,nrow=nrow(res_dunn_test),ncol=2,dimnames=list(
rownames(res_dunn_test),c("Gene",paste0(pattern1,' x ',pattern2))))
interact_genes[,1] <- rownames(interact_genes)
interact_genes[ind[which(exc_interact_patt1)],2]<-paste0("vs",pattern1)
interact_genes[ind[which(exc_interact_patt2)],2]<-paste0("vs",pattern2)
interact_genes[ind[which(interacting_over_both_patterns)],2]<-"vsBoth"
colnames(res_kruskal) <- paste0("KW.",colnames(res_kruskal))
colnames(res_dunn_test) <- paste0("Dunn.",colnames(res_dunn_test))
interact_genes <- cbind(interact_genes,res_kruskal,res_dunn_test)
if (analysis=="overlap"){
interact_genes <-interact_genes[interact_genes[,2]!="FALSE",]
}
return(list(interact_genes))
}
Loading

0 comments on commit d3b5391

Please sign in to comment.