基因集变异分析(GSVA)

软件:

  • GSEAbase
  • GSVA
  • limma
  • Seurat

首先,针对某个细胞类型继续细分其细胞亚型:

  1. library(Seurat)
  2. library(GSEABase)
  3. library(Biobase)
  4. library(genefilter)
  5. library(limma)
  6. library(RColorBrewer)
  7. library(GSVA)
  8. library(dplyr)
  9. ###读入Seurat对象
  10. Seurat.obj<-readRDS("seurat.rds")
  11. DefaultAssay(Seurat.obj) <- "integrated"
  12. #提取第三个cluster或者加入你定义了细胞类型,则为该细胞名称
  13. sub <- subset(Seurat.obj, idents = "3")
  14. ##为该细胞组定义身份(stim为case-control分组依据,名称来自于官网)
  15. Idents(sub) <- "stim"
  16. ##再跑一次高解析度的聚类,分出细胞亚类
  17. sub<-ScaleData(sub, verbose = FALSE)
  18. sub<-RunPCA(sub,npcs=30,verbose = FALSE)
  19. sub<-RunUMAP(sub, reduction = "pca", dims = 1:20)
  20. sub<-FindNeighbors(sub, reduction = "pca", dims = 1:20)
  21. sub <- FindClusters(sub, resolution = 0.2)
  22. ###保存该对象
  23. saveRDS(sub,"sub_cluster.rds")
  24. ##可以把身份加上case-control和聚类双重信息
  25. sub$celltype.case<-paste(Idents(sub),sub$stim,sep="_")
  26. sub$celltype<-Idents(sub)
  27. Idents(sub)<-"celltype.case"

接着,做 GSVA 分析,获取 GSVA 矩阵,做 GSVA 分析可以参考传统 bulk-RNA 分析的方法

这里还需要注意几个问题:

  • 处理普通 RNA 数据需要预先过滤,但是单细胞数据取自 Seurat 对象,已经预先过滤好了
  • 如果输入是原始 counts 值,需要设置参数kcdf="Possion",但如果是 TPM 值,默认就好,因为我们输入是标准化后的数据,所以用默认参数
  • 默认参数mx.diff=TURE,结果是一个类似于负二项分布,因为后面要做差异分析,所以需要使用该参数,如果设置mx.diff=FALSE,则为高斯分布
  1. ##读取Geneset
  2. #(http://software.broadinstitute.org/gsea/msigdb/download_file.jsp?filePath=/resources/msigdb/7.0/h.all.v7.0.symbols.gmt)
  3. geneSets <- getGmt("h.all.v7.0.symbols.gmt")
  4. ##获取表达矩阵,这里选择标准化后但没有均一化的数据
  5. expMat<-GetAssayData(sub,slot="data")
  6. mydata<-as.matrix(expMat)
  7. ##提供列注释
  8. annotation_col<-data.frame(Type=Idents(sub))
  9. ##运行GSVA,返回二项式分布的结果
  10. res_es <- gsva(mydata, geneSets, min.sz=10, max.sz=500, verbose=FALSE, parallel.sz=8)

然后,使用 limma 线性模型分析新表达矩阵的差异,寻找 case-control 差异通路

  1. ##设置分组
  2. grouP<-as.factor(annotation_col$Type)
  3. desigN <- model.matrix(~ grouP + 0)
  4. rownames(desigN)<-colnames(mydata)
  5. #head(desigN)
  6. #这里需要手动构建差异矩阵,我这里用每个亚类的case和control比较,寻找其中的差异
  7. comparE <- makeContrasts(clu1=grouP0_case-grouP0_control,clu2=grouP1_case-grouP1_control,clu3=grouP2_case-grouP2_control,levels=desigN)
  8. #构建线性模型
  9. fiT <- lmFit(res_es, desigN)
  10. fiT2 <- contrasts.fit(fiT, comparE)
  11. fiT3 <- eBayes(fiT2)
  12. #这里获取一步ANNOVA检验获取的不同分组的log2FC,可以用来构造热图
  13. Diff<-topTableF(fiT3,adjust="BH",p.value=0.05,num=50)
  14. write.table(Diff,"diff_path.txt",sep="\t",quote=FALSE)

然后绘图

  1. library(pheatmap)
  2. library(dplyr)
  3. data<-read.table("diff_path.txt",sep="\t",stringsAsFactors = FALSE,header = TRUE,check.names = FALSE)
  4. data$name<-rownames(data)
  5. data<-tbl_df(data)
  6. ##提取cluster对应的log2FC
  7. data<-select(data,name,0,1,2)
  8. data<-as.data.frame(data)
  9. nn<-gsub("HALLMARK_","",data$name)
  10. nn<-tolower(gsub("_"," ",nn))
  11. rownames(data)<-nn
  12. data<-data[,-1]
  13. pheatmap(haha,color = colorRampPalette(c("navy", "white", "firebrick3"))(100),angle_col = 45)

然后,使用 limma 构建不同分组,分别对比不同 cluster 之间的差异通路

  1. ##因为要使用cluster区别差异,所以先恢复细胞类型定义
  2. Idents(sub)<-"celltype"
  3. annotation_col<-data.frame(Type=Idents(sub))
  4. some_cluster<-annotation_col
  5. some_cluster$Type<-as.character(some_cluster$Type)
  6. #把0-clu的定义一组,不是0-clu的定义为另外的组
  7. some_cluster$Type[which(some_cluster$Type!="0")]<-"control"
  8. some_cluster$Type[which(some_cluster$Type="0")]<-"case"
  9. #构建分组矩阵
  10. grouP<-as.factor(some_cluster$Type)
  11. desigN <- model.matrix(~ grouP + 0)
  12. rownames(desigN)<-colnames(mydata)
  13. comparE <- makeContrasts(grouPcase-grouPcontrol,levels=desigN)
  14. #构建线性模型
  15. fiT <- lmFit(res_es, desigN)
  16. fiT2 <- contrasts.fit(fiT, comparE)
  17. fiT3 <- eBayes(fiT2)
  18. #提取差异通路
  19. Diff<-topTable(fiT3,p.value=0.05,num=Inf)
  20. some_diff<-Diff
  21. some_diff<-Diff['t']
  22. colnames(some_diff)<-"0"
  23. ##这里因为有多个分组互相比较,最后需要整合不同分组的t-value表,使用merge
  24. some_diff$name<-rownames(some_diff)
  25. fin<-merge(some_diff,fin,by="name")
  26. write.table(fin,"diff_path.txt",sep="\t",quote=FALSE,row.names=FALSE)

以上完成后,获取的差异通路信息可以通过画热图的方式展示,画图和前面一致

TF 转录因子分析

按照 SCENIC 的官方教程,跑完整个流程(这里耗时很长,所以不能直接跑,要提交作业活着 screen,避免中间间断
SCENIC 基因互作数据库需要提前下载,人类的一共两个,每个 1.2G
hg19-500bp-upstream-7species.mc9nr.feather
hg19-tss-centered-10kb-7species.mc9nr.feather

  1. library(Seurat)
  2. library(SCENIC)
  3. #读取对象
  4. endo<-readRDS("sub_cluster.rds")
  5. DefaultAssay(endo) <- "integrated"
  6. endo$celltype.case<-paste(Idents(endo),endo$stim,sep="_")
  7. endo$celltype<-Idents(endo)
  8. Idents(endo)<-"celltype.case"
  9. ##生成亚型分类信息
  10. cellInfo<-data.frame(CellType=Idents(endo))
  11. #提取表达矩阵
  12. exprMat<-GetAssayData(endo,slot="data")
  13. exprMat<-as.matrix(exprMat)
  14. ##很关键,很多中间数据都保存在这里面,不要乱改名字
  15. dir.create("int")
  16. saveRDS(cellInfo, file="int/cellInfo.Rds")
  17. org="hgnc" # or hgnc, or dmel
  18. ##这个数据库需要从官网下载
  19. dbDir="/SingleCell/SCENIC/cisTarget_databases"
  20. myDatasetTitle="someproject"
  21. data(defaultDbNames)
  22. dbs <- defaultDbNames[[org]]
  23. scenicOptions <- initializeScenic(org=org, dbDir=dbDir, dbs=dbs, datasetTitle=myDatasetTitle, nCores=4)
  24. scenicOptions@inputDatasetInfo$cellInfo <- "int/cellInfo.Rds"
  25. saveRDS(scenicOptions, file="int/scenicOptions.Rds")
  26. ###过滤参数需要根据你输入的数据格式有所调整
  27. genesKept <- geneFiltering(exprMat, scenicOptions=scenicOptions,minCountsPerGene=3*.01*ncol(exprMat),minSamples=ncol(exprMat)*.01)
  28. exprMat_filtered <- exprMat[genesKept, ]
  29. rm(endo)
  30. runCorrelation(exprMat_filtered, scenicOptions)
  31. runGenie3(exprMat_filtered, scenicOptions)
  32. scenicOptions@settings$verbose <- TRUE
  33. scenicOptions@settings$nCores <- 4
  34. scenicOptions@settings$seed <- 123
  35. runSCENIC_1_coexNetwork2modules(scenicOptions)
  36. runSCENIC_2_createRegulons(scenicOptions)
  37. runSCENIC_3_scoreCells(scenicOptions, exprMat)

接下来,我们已经得到了新的转录调控打分矩阵,需要做的就是继续进行差异分析,我们接下来进行不同细胞亚类型之间的差异分析,从而确认到底是哪些互作专一性影响某个细胞亚类。

  1. library(SCENIC)
  2. library(AUCell)
  3. library(Seurat)
  4. library(limma)
  5. ##这里需要在/int的上级目录
  6. scenicOptions <- readRDS("int/scenicOptions.Rds")
  7. cellInfo<-readRDS("int/cellInfo.Rds")
  8. regulons <- loadInt(scenicOptions, "regulons")
  9. #获取互作基因关系
  10. regulons2 <- loadInt(scenicOptions, "aucell_regulons")
  11. #获取打分矩阵
  12. regulonAUC <- loadInt(scenicOptions, "aucell_regulonAUC")
  13. regulonAUC <- regulonAUC[onlyNonDuplicatedExtended(rownames(regulonAUC)),]
  14. endo<-readRDS("sub_cluster.rds")
  15. ###差异分析,这里使用的方法和前面按照不同cluster分组的方法一致
  16. annotation_col<-data.frame(Type=Idents(endo))
  17. some_clu<-annotation_col
  18. some_clu$Type<-as.character(some_clu$Type)
  19. some_clu$Type[which(some_clu$Type!="0")]<-"control"
  20. some_clu$Type[which(some_clu$Type=="0")]<-"case"
  21. grouP<-as.factor(some_clu$Type)
  22. desigN <- model.matrix(~ grouP + 0)
  23. rownames(desigN)<-colnames(getAUC(regulonAUC))
  24. comparE <- makeContrasts(grouPcase-grouPcontrol,levels=desigN)
  25. fiT <- lmFit(as.data.frame(getAUC(regulonAUC)), desigN)
  26. fiT2 <- contrasts.fit(fiT, comparE)
  27. fiT3 <- eBayes(fiT2)
  28. Diff<-topTable(fiT3,p.value=0.05,num=50)
  29. some_diff<-Diff
  30. some_diff<-Diff['t']
  31. colnames(some_diff)<-"0"
  32. ###这里依旧按照上面的方法采用merge把不同分组的合并一下然后保存

接下来,我们需要分析下显著差异的某个转录因子所 target 的基因所对应的功能,我们可以使用 Y 叔的clusterprofiler

  1. library(clusterProfiler)
  2. library(org.Hs.eg.db)
  3. library(DOSE)
  4. ##选择junB基因对应的通路
  5. gene<-regulons2$`JUNB (52g)`
  6. id<-bitr(gene, fromType="SYMBOL", toType="ENTREZID",OrgDb="org.Hs.eg.db")
  7. ego<-enrichGO(OrgDb="org.Hs.eg.db", gene = id$ENTREZID,pvalueCutoff = 0.05,readable=TRUE)
  8. ekk<-enrichKEGG(gene=id$ENTREZID,organism='hsa',pvalueCutoff=0.05)
  9. plotdata<-ego@result
  10. plotdata$GeneRatio<-sapply(plotdata$GeneRatio,function(x) eval(parse(text = x)))
  11. write.table(plotdata,"JUNB_ego.txt",sep="\t",row.names=FALSE,quote=FALSE)
  12. plotdata<-ekk@result
  13. plotdata$GeneRatio<-sapply(plotdata$GeneRatio,function(x) eval(parse(text = x)))
  14. write.table(plotdata,"JUNB_ekk.txt",sep="\t",row.names=FALSE,quote=FALSE)

这里可以绘制条形图

接下来,我们还需要把对应的转录因子以及其 targets 对应的 AUCell score 投影到 umap 图上

  1. library(Seurat)
  2. library(ggplot2)
  3. endo<-readRDS("sub_cluster.rds")
  4. ##因为要将转录调控矩阵在聚类图上显示,所以需要将表达矩阵存储到Seurat对象中
  5. #但是因为features数目不对,所以只是替换一下对应的数值
  6. #feature提取依旧使用基因的名字,按照顺序对应就是了
  7. fin<-GetAssayData(endo,slot="data")
  8. fin[1:length(rownames(getAUC(regulonAUC))),]<-getAUC(regulonAUC)
  9. new_endo<-SetAssayData(endo,slot="data",new.data=fin,assay="RNA")
  10. pdf("test3.pdf",width=4,height=4)
  11. FeaturePlot(new_endo,feature="RP4-669L17.10",cols = c("grey", "red"),min.cutoff="q9",slot="data")+theme(title = element_text(face="bold"),text = element_text(face="bold"))+theme(panel.grid.major = element_line(linetype = "blank"), legend.text = element_text(size = 10),panel.grid.minor = element_line(linetype = "blank"), panel.background = element_rect(colour = "black", size = 2, linetype = "solid"))
  12. dev.off()