Closed ixxmu closed 2 weeks ago
咱就是说,这个笔记可不得了,汇总了#单细胞细节十六篇文章的内容
所以呢,这个字数呀是比较多的。但是正因为字数多,所以这个笔记非常之详细!也是从系列推文内容的学习中,明白了如果详细解析一篇文章,可以得到这么多的知识点!
果然是单细胞的细节!每一个细节都值得学习和思考!
指定了一个基因需要在至少多少个细胞中表达(即检测到的表达量大于0)的最小细胞数。例如,如果设置 min.cells = 5
,那么只有那些在至少5个细胞中表达的基因才会被保留在最终的表达矩阵中。这个过滤步骤有助于去除那些可能由于随机噪声或测序误差而在极少数细胞中被检测到的基因,这些基因不太可能对生物学解释有贡献
指定了细胞需要表达的最小基因数。例如,如果设置 min.features = 300
,那么只有表达超过300个基因的细胞才会被保留在分析中。这个过滤步骤有助于去除那些测序深度不足或质量较低的细胞,这些细胞可能无法提供足够的生物学信息,或者可能代表了技术或生物学上的异常情况。
使用这些过滤参数的目的是从原始数据中移除不可靠或不相关的信息,从而提高后续分析(如聚类、差异表达分析等)的准确性和可解释性。过滤后的数据集应该更加聚焦于生物学上有意义的变异,减少分析结果中的假阳性。
一般比较宽松,不设置过滤的上限,但是有些数据比较特殊或者过滤完发现结果质量不好,可以重新调整一下质控标准
min.features = 300 是规定了细胞的下限,它就是计算得到的nFeature_RNA值,如果这个值过低说明细胞质量肯定是不行,但是过高也不是好事,因为有可能是双细胞。但是如果是处于细胞增殖状态的细胞或者恶性的肿瘤细胞,它的nFeature_RNA值本来就会很高。所以我们很少会设置nFeature_RNA值的上限
3个常见的过滤参数及其意义:
代表每个细胞中检测到的基因特征(如基因或转录本)的数量。过滤掉低的nFeature_RNA
值可以帮助去除那些测序深度不够或背景噪声较高的细胞。
nCount_RNA
过低的细胞可以排除那些可能由于技术原因导致数据不足的细胞。tmp=subset(sce.all.filt,subset = percent_mito < 20 &
#nCount_RNA <10000 &
nFeature_RNA <5000 &
nFeature_RNA>200)
percent_mito < 20:过滤掉线粒体基因表达占比超过20%的细胞,这有助于去除可能由于细胞应激或损伤而异常表达线粒体基因的细胞。
nFeature_RNA < 5000
:过滤掉表达特征数超过5000的细胞。这可能是为了去除高表达细胞,它们可能代表了技术异常或生物学上的异常状态,如细胞周期的某些阶段。
nFeature_RNA > 20
:过滤掉表达特征数少于200的细胞,这有助于去除测序深度不足或背景噪声较高的细胞。
过滤基因的操作就是单细胞转录组标准流程里面的降维聚类分群环节的降维,通过筛选高变基因以及PCA降维对基因进行过滤
单细胞亚群主要是肿瘤微环境里面的3大亚群,就是上皮细胞和免疫细胞,以及间质细胞。
GSE176078乳腺癌数据细胞分群,以及基于marker基因进行归一化后降维聚类分群
如果我们本来就是要做有监督的分析,比如降维聚类分群后想把不同单细胞亚群泾渭分明的区分开, 那么就可以在数据前期处理做有监督的挑选,比如我们仅仅是挑选那些不同单细胞亚群的特异性高表达量基因去做降维聚类分群。
load('check-by-celltype/qc-_marker_cosg.Rdata')
cg=unique(as.character(unlist(marker_cosg$names)))
input_sce <- ScaleData(input_sce,features = cg)
input_sce <- RunPCA(input_sce, features = cg)
seuratObj <- RunHarmony(input_sce, "orig.ident")
names(seuratObj@reductions)
seuratObj <- RunUMAP(seuratObj, dims = 1:15,
reduction = "harmony")
p = DimPlot(seuratObj,reduction = "umap",label=T,group.by = 'celltype' ) ;p
ggsave(filename='umap-by-cosg-genes-by-celltype.pdf',plot = p)
上面的上皮细胞会混入一点点到SMC里面,其实这部分上皮细胞就是乳腺basal上皮细胞,它强烈的具有平滑肌的特征
细胞周期是细胞生长、复制DNA并分裂为两个新细胞的过程。细胞周期主要分为四个阶段:G1期(生长期)、S期(合成期)、G2期(准备期)和M期(分裂期):
第一层次降维聚类分群中单独命名了一个细胞增殖亚群,如果看它的top10的特异性基因,是可以比较清晰的看到我们的定义的cycle细胞亚群主要是t细胞和b细胞的混合体。而其他很多癌症单细胞数据,主要是肿瘤细胞会有恶性增殖的现象
抽样后细胞聚类还是和原始的一样
细胞周期计算靠CellCycleScoring函数:
s.genes <- str_to_upper(cc.genes$s.genes)
g2m.genes <- str_to_upper(cc.genes$g2m.genes)
s.genes;g2m.genes
sce=sce.all.int
sce <- CellCycleScoring(sce,
s.features = s.genes,
g2m.features = g2m.genes,
set.ident = TRUE)
colnames(sce@meta.data)
p1=VlnPlot(sce,features = "S.Score" ,pt.size = 0,group.by = 'celltype') +NoLegend()
p2=VlnPlot(sce,features = "G2M.Score" ,pt.size = 0,group.by = 'celltype')+NoLegend()
p1+p2
table(sce$Phase,sce$celltype)
cycle的亚群很明显主要是t细胞,但是它细胞周期打分就非常高
# 回归"S.Score","G2M.Score"
input_sce <- ScaleData(sce, features = rownames(sce),
vars.to.regress = c("S.Score","G2M.Score") )
input_sce<-RunPCA(input_sce )
p1=DimPlot(input_sce,reduction="pca") + DimPlot(sce,reduction="pca")
p2=DimPlot(input_sce,reduction="pca",group.by='celltype') + DimPlot(sce.all.int,reduction="pca") +NoLegend()
p1/p2
seuratObj<-RunHarmony(input_sce,"orig.ident")
names(seuratObj@reductions)
seuratObj<-RunUMAP(seuratObj,dims=1:15,
reduction="harmony")
p=DimPlot(seuratObj,reduction="umap",label=T,group.by='celltype');p
基于ScaleData函数对"S.Score","G2M.Score"回归后,确实是影响了表达量矩阵以及后面的pca分析
但是这个操作并不会把cycle细胞亚群给打散到其它单细胞亚群,如下所示这个cycle细胞亚群仍然是自己聚集在一起
因为这个数据集中定义的cycle细胞亚群主要是t细胞和b细胞的混合体,所以其实这个cycle细胞亚群确实是被打散到其它单细胞亚群,不过是分散到t细胞和b细胞的亚群里面。
rm(list=ls())
options(stringsAsFactors = F)
source('../../scRNA_scripts/lib.R')
set.seed(123456789)
###### step1:导入数据 ######
sce.all.int = readRDS('../../2-harmony/sce.all_int.rds')
colnames(sce.all.int@meta.data)
load('../../phe.Rdata')
table(phe$celltype)
# 因为前面的b细胞和浆细胞被我拆开命名,所以这个时候细分子集需要把两个都提取到
choose_cellIds=rownames(phe)[phe$celltype %in% c('Bcells','plasma') ]
sce.all=sce.all.int[,choose_cellIds]
sce.all=CreateSeuratObject(
counts = sce.all@assays$RNA$counts,
meta.data = sce.all@meta.data
)
在选择某个细胞亚群进行细分的时候,会遇到混入别的细胞亚群的情况,比如在选了B细胞亚群细分的时候,混入了少量T细胞
如果成纤维细胞亚群中混入了平滑肌细胞(Smooth Muscle Cells, SMCs)和周细胞(Pericytes),这个混合的单细胞亚群可以被称为“混合间充质细胞群”(Mixed Mesenchymal Cell Cluster)或“血管相关间充质细胞群”(Vascular-Associated Mesenchymal Cell Cluster),具体命名取决于细胞的来源和所处的组织微环境。
以下是一些可能的命名方式:
我们默认使用的是RNA_snn_res.0.1,很简单的提高一下分辨率到RNA_snn_res.0.5,就可以看到b细胞4大亚群其实是可以裂变的
在张泽民老师的单细胞文章:《Pan-cancer single-cell dissection reveals phenotypically distinct B cell subtypes》就是针对这些更细致的b细胞亚群进行了解释
如果没有生物学背景,仅仅是靠每个人在自己的数据集里面去定义,会出现各种千奇百怪的亚群,而且大多数都很难复现出来。
胃癌单细胞数据集GSE163558对应的文献“Revealing the transcriptional heterogeneity of organ-specific metastasis in human gastric cancer using single-cell RNA Sequencing”,**作者首先是默认第一层次降维聚类分群里面的成纤维细胞是纯粹的成纤维。然后就细分成为了 iCAF和myCAF **
“Classifying cancer-associated fibroblasts-The good, the bad, and the target”的文章,通过单细胞表型和CAF在不同癌症类型中的空间位置来简化和标准化CAF的分类。分类包括以下的9个caf类型:
这一分类系统为理解CAF的功能多样性及其作为癌症治疗潜在靶点提供了框架。通过基于表型和位置定义清晰的类别,研究人员可以更好地研究CAF在不同癌症背景下的作用,并开发调节其活性的策略。
正常组织的成纤维细胞和肿瘤相关成纤维细胞(CAF),是两种在组织结构和功能上具有重要作用的细胞类型,成纤维细胞在正常组织中发挥结构和修复作用,而CAF在肿瘤微环境中具有更复杂的功能,包括促进肿瘤生长和调节免疫反应。
cal_table = function(x,y,prefix ){
# x = phe$orig.ident
# y = phe$celltype
library(sur)
library(reshape2)
tbl = table(x,y)
pdf(paste0(prefix,'-table.pdf'),width = 10,height = 10)
gplots::balloonplot( tbl )
dev.off()
df = dcast(as.data.frame(tbl),x~y)
head(df)
write.csv( df ,paste0(prefix,'-table.csv'))
# ptb = round(sur::percent.table(x,y),2)
ptb = round(100*tbl/rowSums(df[,-1]),2)
pdf(paste0(prefix,'-percent-table.pdf'),width = 10,height = 10)
gplots::balloonplot( ptb )
dev.off()
write.csv( dcast(as.data.frame(ptb),x~y) ,paste0(prefix,'-percent-table.csv'))
}
cal_table(phe$orig.ident,phe$celltype,prefix = 'celltype-vs-orig.ident')
cal_table(phe$group,phe$celltype,prefix = 'celltype-vs-group')
cal_table(phe$group,phe$seurat_clusters,prefix = 'seurat_clusters-vs-group')
cal_table(phe$group,phe$RNA_snn_res.0.8,prefix = 'RNA_snn_res.0.8-vs-group')
x='celltype';y='group'
plot_data <- data.frame(table(phe[, y ],
phe[, x ]))
head(plot_data)
plot_data$Total <- apply(plot_data,1,function(x)sum(plot_data[plot_data$Var1 == x[1],3]))
plot_data <- plot_data %>% mutate(Percentage = round(Freq/Total,3) * 100)
colnames(plot_data) <- c("group","cluster","Freq","Total","Percentage")
head(plot_data)
ggplot(plot_data,aes(group,Percentage,group= cluster,color =cluster))+geom_point(size=4)+
geom_line(position = position_dodge(0.1),cex=2)+theme_bw()+theme_test(base_size = 30)
ggsave("celltype-vs-group-percent-plot.pdf",width = 9,height = 7)
sce.all = readRDS('./2-harmony/sce.all_int.rds')
sp='human'
load('./phe.Rdata')
identical(rownames(phe) , colnames(sce.all))
sce.all@meta.data = phe
sel.clust = "celltype"
sce.all <- SetIdent(sce.all, value = sel.clust)
table(sce.all@active.ident)
DimPlot(sce.all)
# v4 是 AverageExpression
av <-AggregateExpression(sce.all ,
group.by = c("orig.ident","celltype"),
assays = "RNA")
av=as.data.frame(av[[1]])
head(av) # 可以看到是整数矩阵
#write.csv(av,file = 'AverageExpression-0.8.csv')
cg=names(tail(sort(apply(log(av+1), 1, sd)),1000))
df =cor(as.matrix(log(av[cg,]+1)))
ac=as.data.frame(str_split(colnames(df),'_',simplify = T))
rownames(ac)=colnames(df)
pheatmap::pheatmap(df ,
show_colnames = F,show_rownames = F,
annotation_col = ac,
filename = 'cor_celltype-vs-orig.ident.pdf' )
dev.off()
save(av,file = 'av_for_pseudobulks.Rdata')
GSE206785胃癌单细胞数据集
不同单细胞亚群之间的这个差异仍然是最大的,其次是各个亚群里面的样品差异或者分组差异
如果忽略了不同样品其实是由不同的单细胞亚群组成的, 那么它们这些样品虽然说来源于两个很明显的分组,癌症组织和正常组织,它们其实并不会泾渭分明
拷贝数变化是许多恶性肿瘤的共同特征,但它们并不是唯一的分子机制。肿瘤细胞可能通过多种机制获得恶性表型,包括基因组、转录组、蛋白质组和代谢组层面的变化,以及表观遗传调控和肿瘤微环境的影响。这些复杂的生物学过程共同促进了肿瘤的发生、发展和异质性。
目前的最佳实践是依据单细胞转录组表达量矩阵来推断染色体级别的拷贝数变化情况,一般来说, 典型的恶性肿瘤上皮细胞会出现大面积的染色体扩增和缺失的。
胃癌单细胞数据集GSE163558的单细胞转录组在降维聚类分群后,针对里面的上皮细胞进行恶性推断的时候,就放弃了拷贝数方法。使用的是类似于标记基因表达的策略
重新载入上皮细胞的亚群,对亚群进行打分和可视化
虽然对每个上皮细胞都是进行了inferCNV打分,但实际上我们并没有使用这个inferCNV打分来探索最佳阈值去划分细胞的恶性与否!
我们是先分组,然后看不同组之间的inferCNV打分的差异情况来划分正常和对照的组,并不是针对具体的每个单细胞在进行判断!
胃癌文章中去tcga数据库里面定位到胃癌的转录组测序数据集,然后根据分组做癌症和癌旁的差异分析后,拿到上下调各自的top50基因列表去单细胞表达量矩阵里面打分!
文献的附件里面有这些基因的名字,所以可以基于这些基因名字去我们的单细胞转录组表达量矩阵里面进行打分
sce.all.int = readRDS('2-harmony/sce.all_int.rds')
sce.all.int
f='phe.Rdata'
load(f)
colnames(phe)
sce.all.int=sce.all.int[,colnames(sce.all.int) %in% rownames(phe)]
identical(colnames(sce.all.int), rownames(phe))
sce.all.int$celltype = phe$celltype
th = theme(axis.text.x=element_text(angle=45,hjust = 1))
table(sce.all.int$celltype)
DimPlot(sce.all.int,group.by = 'celltype',
repel = T,label = T)
# 文章里面的 tcga的转录组差异top50基因
up='IBSP CST4 HOXC9 FEZF1 HOXA11 RDH8 ALPP HOXC10 MAGEA12 TAS2R38 EVX1 CCL7 C5orf46 DMBX1 HOXC13 FGF19 MAGEA6 HOXC12 R3HDML ALPG MMP8 MAGEA3 HOXC11 PRAC2 SP8 DCSTAMP CST1 PIWIL1 KRTAP4-1 CSF2 CSAG3 ACTL8 HOXC8 BAAT'
up=trimws(strsplit(up,' ')[[1]]);up
down='SLC5A7 PCSK2 DCAF12L1 SLC7A3 GCG CHIA RPRM PLP1 PTF1A KIAA0408 NR0B1 PEBP4 CCKBR LGI3 HSPB3 PLD5 CCKAR SYT4 NUPR2'
down=trimws(strsplit(down,' ')[[1]]);down
使用Seurat::AddModuleScore函数进行打分:
gene_vector=list(up=up,down=down)
sc_dataset <- Seurat::AddModuleScore(sce.all.int,
features = gene_vector)
#signature.names <- paste0(names(gene_vector), "_UCell")
options(repr.plot.width=6, repr.plot.height=4)
colnames(sc_dataset@meta.data)
table(sc_dataset$orig.ident)
Idents(sc_dataset)
p1=VlnPlot(sc_dataset, features = 'Cluster1',
group.by = "orig.ident",pt.size = 0 ) + NoLegend() ;p1
FeaturePlot(sc_dataset,'Cluster1')
p2=VlnPlot(sc_dataset, features = 'Cluster2',
group.by = "orig.ident",pt.size = 0 ) + NoLegend() ;p2
FeaturePlot(sc_dataset,'Cluster2')
p1+p2
可以比较清晰的看到了文献里面的上调基因在所有的癌症样品里面的打分都比较高,但是在NT1这个正常样品里面就打分很低 (下图的上半部分小提琴图),文献里面的下调基因在NT1这个正常样品里面就打分很高(上图的下半部分小提琴图)。
使用了上调基因打分减去下调基因的打分,取一个 0.02的阈值,来划分正常细胞和恶性细胞。但是这个打分也是很难完美的区分正常细胞和恶性细胞,因为那个NT1 正常样品里面的上皮细胞理论上都是正常的,被这个算法误判了大部分。
通过差异分析,研究者可以识别在癌症组织中特异性表达的基因,这些基因可能在肿瘤的发生、发展、转移和预后中发挥重要作用。进一步的研究可以探索这些差异表达基因的功能,为癌症的诊断和治疗提供潜在的靶点。
https://mp.weixin.qq.com/s/48aVJv41p32WnGnNEInazQ