1. Seurat對象查看當(dāng)前的Assay
pbmc <- Read10X('./filtered_gene_bc_matrices/hg19/')
pbmc <- CreateSeuratObject(pbmc,project = 'pbmc3k',min.cells = 3,min.features = 200)
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
pbmc <- NormalizeData(pbmc) %>% FindVariableFeatures(nfeatures = 2000) %>% ScaleData(vars.to.regress = "percent.mt")
pbmc <- SCTransform(pbmc, vars.to.regress = "percent.mt")
DefaultAssay(pbmc)
#[1] "SCT"
在進(jìn)行了SCTransform操作后,矩陣默認(rèn)會變成SCT矩陣,如果不加設(shè)置,后續(xù)的PCA等操作都是基于SCT矩陣。
修改DefaultAssay:
DefaultAssay(pbmc) <- 'RNA'
DefaultAssay(pbmc)
#[1] "RNA"
2. Seurat使用FindVariables找到高變基因后增刪高變基因
var.gene <- pbmc@assays$RNA@var.features #提取高變基因
pbmc@assays$RNA@var.features <- c(var.gene,c('CD4','CD8'))%>%unique() #增加高變基因
#unique()是為了保證增加的基因不和原有的重復(fù)
3. 不同運行步驟中的文件來源和儲存位置??
PCA輸入的是@scale.data??
因為做PCA的前提是:1. 主成分分析認(rèn)為主元之間彼此正交,樣本呈高斯分布;2. 主成分分析假設(shè)源信號間彼此非正交。
NormalizeData得到的@data矩陣消除了測序文庫差異(對于每個細(xì)胞,將每個基因的count除以總數(shù),然后乘以一個scale.factor, 之后以自然對數(shù)進(jìn)行轉(zhuǎn)換),但得到的矩陣仍然是非高斯分布的。而ScaleData對矩陣進(jìn)行了中心化,得到的@scale.data矩陣結(jié)果接近于高斯分布。RunTSNE和RunUMAP輸入的都是PCA的數(shù)據(jù)(PCA@cell.embedding),輸出結(jié)果保存在各自的數(shù)據(jù)槽 。
FindNeighbors輸入的也是PCA的數(shù)據(jù)(根據(jù)PCA降維結(jié)果判斷哪個細(xì)胞和哪個系細(xì)胞距離更近)。這個函數(shù)構(gòu)建
SNN矩陣
,結(jié)果保存在pbmc@graph下面(輸入的是SCT的PCA得到的是SCT_nn和SCT_snn,輸入RNA的PCA得到RNA_nn和RNA_snn)。Harmony讀入的是PCA(要注意是RNA的pca還是SCT的pca)的數(shù)據(jù),進(jìn)行調(diào)整,在和pca一起保存在reduction下面。其基因數(shù)和PC數(shù)都和PCA一樣。
??:PCA的值是可以被覆蓋的,使用三步法對矩陣進(jìn)行標(biāo)準(zhǔn)化后進(jìn)行PCA后再使用SCT矩陣進(jìn)行標(biāo)準(zhǔn)化,PCA的矩陣變成了SCT的PCA矩陣,原有的PCA矩陣不會保留。后續(xù)的TSNE和UMAP降維圖也和三步法不一樣。
FindClusters輸入的是FindNeighbors的結(jié)果,其運行結(jié)果保存在metadata,使用不同的resolution運行時,每運行一次,meta.data中就會多出一列,記錄不同的resolution的分群結(jié)果。meta.data中的seurat_cluster記錄的是最后一次運行聚類的結(jié)果。
細(xì)胞周期評分用的是@data的數(shù)據(jù)??(經(jīng)log轉(zhuǎn)換后的矩陣Normalize Data),運行的結(jié)果儲存在meta.data中
FindAllMarkers和FindMarkers輸入的是@data的數(shù)據(jù)??
AverageExpression默認(rèn)輸入的也是@data的數(shù)據(jù)??,但可以通過slot參數(shù)來改,比如設(shè)置slot=‘scale.data’
延伸閱讀:https://mp.weixin.qq.com/s/s25DLc-tj0lPAcsPurn89Q差異分析和數(shù)據(jù)整合使用的也是@data的數(shù)據(jù)??,雖然官方更推薦使用@scale.data的數(shù)據(jù),但目前Seurat還不支持。
FindVariableFeatures()輸入的是@counts的數(shù)據(jù)(??不是Normalized-Data也不是Scaled_Data)
參考:https://www.biostars.org/p/406388/
FindVariableFeatures()
就是在細(xì)胞與細(xì)胞間進(jìn)行比較,選擇表達(dá)量差別最大的基因,默認(rèn)情況下,會返回2,000個高可變基因。高可變基因的數(shù)目用于做PCA。
Q:PCA輸入的是scale.data的數(shù)據(jù),scale.data默認(rèn)做的是FindVariableFeatures()找到的高變基因的scale,但是scale.data如果scale了全部基因,做PCA也就是用的全部基因,那FindVariableFeatures()還有什么用?
A:雖然很多教程都提示內(nèi)存足夠的話建議scale所有的基因,但PCA的時候還是要選擇高變基因,否則會引入噪聲。低豐度,變化低的基因,很多都是噪音,如果用全部基因去跑PCA,這種低豐度基因的噪音是沒有辦法通過選擇pc數(shù)去除的。仔細(xì)看Seurat官網(wǎng),雖然它推薦scale全部基因,但是做PCA的時候還是限定了使用高變基因。
https://satijalab.org/seurat/articles/pbmc3k_tutorial.html此外如果使用了SCTransform,默認(rèn)是得到3000個高變基因,Scale的也是高變基因。再下一步直接做RunPCA(),也是默認(rèn)使用高變基因。
4. @data標(biāo)準(zhǔn)化矩陣
和@scale.data 歸一化矩陣
的區(qū)別
單細(xì)胞RNA 測序數(shù)據(jù)中,文庫之間測序覆蓋率的系統(tǒng)差異通常是由細(xì)胞間的cDNA 捕獲或PCR 擴增效率方面的技術(shù)差異引起的,這歸因于用最少的起始材料難以實現(xiàn)一致的文庫制備。標(biāo)準(zhǔn)化旨在消除這些差異(例如長度,GC 含量),以使它們不干擾細(xì)胞之間表達(dá)譜的比較。這樣可以確保在細(xì)胞群體中觀察到的任何異質(zhì)性或差異表達(dá)都是由生物學(xué)而不是技術(shù)偏倚引起的(批次矯正僅在批次之間發(fā)生,并且必須同時考慮技術(shù)偏差和生物學(xué)差異,標(biāo)準(zhǔn)化只需考慮技術(shù)差異)。
軟件Seurat 提供了三種標(biāo)準(zhǔn)化的方法,分別為LogNormalize、CLR、RC,通常情況下我們采用LogNormalize 的方式進(jìn)行標(biāo)準(zhǔn)化,計算公式為:log1p((Feature counts/total counts) ? scale. factor)
歸一化的目的則是使特征具有相同的度量尺度
參考:Seurat的normalization和scaling
5. 關(guān)于有些細(xì)胞屬于同一個cluster但是在umap或者tsne圖上相聚較遠(yuǎn)的問題:UMAP和TSNE是各自的算法在PCA降維的基礎(chǔ)上再進(jìn)行非線形降維,在二維圖上把其各自算法認(rèn)為相近的細(xì)胞聚在一起。但是FindClusters輸入的不是UMAP或TSNE降維的數(shù)據(jù),而是FindNeighbors的數(shù)據(jù),而FindNeighbors輸入的數(shù)據(jù)是PCA降維數(shù)據(jù),是用另外一種算法計算的細(xì)胞之間的距離。因此會出現(xiàn)有些細(xì)胞被認(rèn)為是同一個cluster,但是在umap或者tsne圖上相聚較遠(yuǎn)(尤其是一些散在的,脫離主群的細(xì)胞)
6. marker基因鑒定,查看marker基因的表達(dá)是使用RNA矩陣還是sct矩陣?
這是一個爭議性問題,兩個都可以,目前建議最好使用RNA矩陣。
sct的到的count并不是真實的基因表達(dá)值,而是通過scaledata倒推出來的,它是一個回歸,運算之后的殘差。
7. 關(guān)于FindAllMarks找到的基因
如下圖,先看cluster0的Marker基因:cluster0的差異基因是cluster0的細(xì)胞和剩下的所有的cluster合在一起的細(xì)胞做對比得到的。pct.1是這個基因在cluster0中的表達(dá)比例(S100A8在cluster0的細(xì)胞中的表達(dá)比例是100%),pct.2是這個基因在除了cluster0以外的所有細(xì)胞中的表達(dá)比例(S100A8在除cluster0以外的細(xì)胞中的表達(dá)比例是51.2%)。avg_log2FC是表達(dá)差異倍數(shù),p_val_adj是校正后的p值。
8. 在提取Marker基因時比較好的辦法:因為單細(xì)胞矩陣算出來的結(jié)果,p_val_adj==0的有很多,所以可以先把p_val_adj==0先提出來。再把p_val_adj<0.01的按差異倍數(shù)靠前的20/30/500...(按需要)個基因提出來,然后把兩個矩陣合在一起(取交集)用來做細(xì)胞鑒定。(結(jié)合p值和fc來做篩選效果更好)
top = 30 #可根據(jù)需要調(diào)整
TopMarkers1 <- ClusterMarker %>% filter(p_val_adj == 0) %>% group_by(cluster) %>%
top_n(n = top, wt = avg_log2FC)
TopMarkers2 <- ClusterMarker %>% filter(p_val_adj < 0.01) %>% group_by(cluster) %>%
top_n(n = top, wt = avg_log2FC)
TopMarkers <- rbind(TopMarkers1, TopMarkers2) %>% unique.matrix() %>% arrange(cluster)
write.csv(TopMarkers,'CellType/TopMarkers.csv', row.names=F)
??:提取沒有核糖體和線粒體的marker基因更好。(這些基因?qū)﹁b定沒有幫助)
人的核糖體基因是
RPS/RPL
開頭
人的線粒體基因是MT-
開頭
小鼠的核糖體基因是Rps/Rpl
開頭
小鼠的線粒體基因是mt-
開頭
##人
### 提取沒有線粒體、核糖體的Markers
ClusterMarker_noRibo <- ClusterMarker[!grepl("^RP[SL]", ClusterMarker$gene, ignore.case = F),]
ClusterMarker_noRibo_noMito <- ClusterMarker_noRibo[!grepl("^MT-", ClusterMarker_noRibo$gene, ignore.case = F),]
top = 100 #可根據(jù)需要調(diào)整
TopMarkers1 <- ClusterMarker_noRibo_noMito %>% filter(p_val_adj == 0) %>%
group_by(cluster) %>% top_n(n = top, wt = avg_log2FC)
TopMarkers2 <- ClusterMarker_noRibo_noMito %>% filter(p_val_adj < 0.01) %>%
group_by(cluster) %>% top_n(n = top, wt = avg_log2FC)
ClusterMarker_noRibo_noMito <- rbind(TopMarkers1, TopMarkers2) %>% unique.matrix() %>% arrange(cluster)
write.csv(ClusterMarker_noRibo_noMito,'CellType/TopMarkers_noRibo_noMito.csv', row.names=F)
##小鼠
### 提取沒有線粒體、核糖體的Markers
ClusterMarker_noRibo <- ClusterMarker[!grepl("^Rp[sl]", ClusterMarker$gene, ignore.case = F),]
ClusterMarker_noRibo_noMito <- ClusterMarker_noRibo[!grepl("^mt-", ClusterMarker_noRibo$gene, ignore.case = F),]
有些基因比如Foxp3,對細(xì)胞鑒定很重要,但常常在篩選Marker基因的時候篩選不出來。非負(fù)矩陣分解
可能更好。
參考:過濾線粒體核糖體基因
9. 提取亞群
Idents(pbmc) <- "celltype" #先把celltype設(shè)成Idents(active ident)
CD4T <- subset(pbmc, idents = "CD4_T") #通過idents來提取
tmp <- c("orig.ident", "percent.mt","percent.rb","percent.HB","S.Score",
"G2M.Score","Phase","DF.classifications")
CD4T <- CreateSeuratObject(CD4T@assays$RNA@counts, meta.data = CD4T@meta.data[,tmp])
#metadata保留了,降維聚類結(jié)果沒有保留
??新提取的亞群需要重新進(jìn)行降維聚類(和大群相比,標(biāo)記基因發(fā)生了變化),并重新尋找marker基因,重新分群,注釋。??subset提取子集后,不同樣本間批次校正的信息也被去除,需要重新進(jìn)行批次矯正
參考:Seurat取子集時會用到的函數(shù)和方法??????
10. 取子集后如何去除空子集(還存在這個level,但里面包含的細(xì)胞為0,如何去除)as.factor(as.character())
Idents(CD4T) <- "seurat_clusters"
CD4T.sub <- subset(CD4T, idents = c(0,1,2,3,4,5,6))
CD4T.sub$seurat_clusters <- as.factor(as.character(CD4T.sub$seurat_clusters))
CD4T.sub$celltype <- as.factor(as.character(CD4T.sub$celltype))
saveRDS(CD4T.sub, "CD4T/CD4T.classified.rds")
11. 雙細(xì)胞的預(yù)測和去除如DoubletFinder建議單樣本進(jìn)行,不建議雙樣本一起預(yù)測。除此之外,其他步驟都可以多樣本一起做,質(zhì)控的時候也可以多樣本一起做,但是建議每個樣本都單獨看一看。
12. 單細(xì)胞多樣本整合:merge();多樣本拆分:SplitObject()
scRNA <- merge(scRNAlist[[1]], scRNAlist[2:length(scRNAlist)])
scRNAlist <- SplitObject(scRNA, split.by = "orig.ident")
13. 在做多組數(shù)據(jù)整合,每個組又有多個樣本的時候,最好把單獨的每個樣本當(dāng)成批次,而不是把不同的組當(dāng)成批次。
14. 多核運算
library(future)
options(future.globals.maxSize = 20 * 1024^3)
plan(multisession, workers = 8) #開啟多核運算 (8個核)
plan('sequential') #終止多核運算
參考:單細(xì)胞數(shù)據(jù)分析中future包的使用
15. pbmc3k.final@commands$FindClusters 可以查看FindClusters運行時間和記錄。Seurat是記錄其分析過程的,也可查看command下其他操作
16. 關(guān)于質(zhì)控標(biāo)準(zhǔn):同一組織的最好用同樣的標(biāo)準(zhǔn),不同組織的可以不一樣。不同組織線粒體含量等可能存在差異。
17. 可視化的方法總結(jié)
參考:http://www.lxweimin.com/p/0d1e2c7d21a4
18. circos圖繪制
19. 單細(xì)胞數(shù)據(jù)思維導(dǎo)圖,有利于查看單細(xì)胞數(shù)據(jù)格式。
http://www.lxweimin.com/p/7560f4fd0d77
20. 對于舊版本Seurat對象的更新
scRNA <- UpdateSeuratObject(scRNA)
UpdateSeuratObject {SeuratObject} :Update old Seurat object to accommodate new features
21. 對有些操作需要用到python設(shè)置的情況
Sys.setenv(RETICULATE_PYTHON="/usr/bin/python3")
# ??要根據(jù)自己python3的路徑來設(shè)置,可以在終端使用which python3來查看
22. 單細(xì)胞數(shù)據(jù)做pooling的好處:可以盡量的降低dropout的問題。(dropout就是矩陣中的zero,這些zero實際上并不是0,而是每個液滴里面起始反應(yīng)量太低了。而一般的反轉(zhuǎn)錄效率只能到30%左右,70%的轉(zhuǎn)錄本實際上在反轉(zhuǎn)錄那一步是被丟掉的,這是單細(xì)胞測序一個比較大的問題)。
但是一旦做了pooling,你必須要證明pooling對結(jié)果是沒有影響的(下圖的右面三個圖)。
23. Seurat的VlnPlot中的combine參數(shù),在如下畫三個基因的情況下,設(shè)置成T就畫一張圖,設(shè)置成False,會將三個基因各畫一張圖。
VlnPlot(seuratObj, features = c("Il15", "Cxcl10","Cxcl16"), split.by = "aggregate", pt.size = 0, combine = T)
24. rev()這一步是將橫坐標(biāo)的基因反過來排序
DotPlot(scRNA, features = nichenet_output$top_ligands, cols = "RdYlBu") + RotatedAxis()
DotPlot(seuratObj, features = nichenet_output$top_ligands %>% rev(), cols = "RdYlBu") + RotatedAxis()
這兩個畫出來的圖橫坐標(biāo)基因的順序是相反的(見NicheNet)
25. 堆疊小提琴圖的繪制
完成這個需求有以下幾種實現(xiàn)方法:
1. Seurat包直接就可以實現(xiàn)(stack = T)
2. 通過Seuart->scanpy來實現(xiàn),第一張是Seurat包VlnPlot函數(shù)畫的圖,第二張是scanpy中stacked_violin函數(shù)畫的圖,那么現(xiàn)在問題就變成為Seurat對象到scanpy對象的轉(zhuǎn)換
3. 用R原生函數(shù)實現(xiàn)StackedVlnPlot的方法
4. 使用基于scanpy包衍生的scanyuan包來說實現(xiàn)
5. 使用R包MySeuratWrappers來實現(xiàn)
最簡單的方法1如下:
pbmc = readRDS('pbmc.rds')
markers <- c('CD14','CD68','CD4','CD19','MS4A1','CD79A','GNLY','NKG7','GZMB','CD8A','CD8B','FCGR3A',
'FOXP3','PPBP','FCER1A','CD34')
markers <- CaseMatch(markers, rownames(pbmc))
markers <- as.character(markers)
VlnPlot(pbmc, features = markers, pt.size = 0, group.by = 'cell_type',stack = T)+NoLegend()
- 當(dāng)繪圖需要設(shè)置橫坐標(biāo)順序時,先把Ident設(shè)置為需要繪圖的變量,再使用factor進(jìn)行設(shè)置。
Idents(scRNA) <- 'orig.ident'
My_levels <- c( "con1","con2", "con3", "case1","case2", "case3")
Idents(scRNA) <- factor(Idents(scRNA), levels= My_levels)
如果不設(shè)置level,會按字母順序排列,case會自動排在con前面。
- 在繪制多個質(zhì)控參數(shù)的小提琴圖時,可以先生成一個空list,將每張圖都存成list的一個對象,再使用patchwork包的
wrap_plots
函數(shù)畫成一張圖。
plot.featrures = c("nFeature_RNA", "nCount_RNA", "percent.mt", "percent.HB")
plots = list()
for(i in seq_along(plot.featrures)){
plots[[i]] = VlnPlot(scRNA, pt.size = 0,
features = plot.featrures[i],log = T) + theme.set2 + NoLegend()}
wrap_plots(plots = plots, nrow=2)
ggsave(filename = 'beforeQC9log.pdf', width = 8, height = 6)
- 在進(jìn)行細(xì)胞注釋時,可以使用
recode
函數(shù)
scRNA$celltype <- scRNA$SCT_snn_res.0.3
scRNA$celltype <- recode(scRNA$celltype,
"0" = "CD14_Monocyte",
"1" = "CD14_Monocyte",
"2" = "NK_cell",
"3" = "B_cell",
"4" = "T_cell",
"5" = "T_cell",
"6" = "CD16_Monocyte",
"7" = "Megakaryocyte",
"8" = "NK_cell",
"9" = "T_cell",
"10" = "T_cell",
"11" = "T_cell",
"12" = "T_cell",
"13" = "T_cell",
"14" = "B_cell",
"15" = "DC",
"16" = "Neutrophil",
"17" = "T_cell",
"18" = "Proliferating_lymphocyte",
"19" = "CD14_Monocyte",
"20" = "B_cell")
- 對某一metadata進(jìn)行重命名
#查看meta.data中有哪些內(nèi)容
colnames(scRNA@meta.data)
#meta.data中第13個進(jìn)行重命名
colnames(scRNA@meta.data)[13] <- 'Cytokine_Score'
使用Seurat的RenameIdents
函數(shù)也可以
scRNA <- RenameIdents(scRNA, 'oldIdent'='newIdent')
- 進(jìn)行marker基因繪圖時,使用
CaseMatch
函數(shù)去除不存在的基因。
markers <- c('CD79A','CD79B','MS4A1','CD19','MZB1','GNLY','NKG7','NCAM1','CD3D','CD3E')
markers <- CaseMatch(markers, rownames(scRNA))
markers <- as.character(markers)
-
prop.table
函數(shù),生成細(xì)胞比例表格,用于繪制細(xì)胞比例條形圖
prop.table(x, margin = NULL)
x: table
margin: a vector giving the margins to split by. E.g., for a matrix 1 indicates rows, 2 indicates columns, c(1, 2) indicates rows and columns. When x has named dimnames, it can be a character vector selecting dimension names.
m <- matrix(1:4, 2)
m
# [,1] [,2]
# [1,] 1 3
# [2,] 2 4
proportions(m, 1)
# [,1] [,2]
# [1,] 0.2500000 0.7500000
# [2,] 0.3333333 0.6666667
#根據(jù)orig.ident來計算細(xì)胞百分比
cell.prop<-as.data.frame(prop.table(table(Idents(scRNA), scRNA$orig.ident)))
colnames(cell.prop)<-c("cluster","Group","proportion")
write.csv(cell.prop,row.names = FALSE,file = 'cell_prop_all.csv')
cell.prop$Group <- factor(cell.prop$Group,ordered=TRUE,levels=c("HC1","HC2","HC3","Case1","Case2","Case3"))
ggplot(cell.prop,aes(Group,proportion,fill=cluster))+
geom_bar(stat="identity",position="fill")+
ggtitle("")+
theme_bw()+
theme(axis.ticks.length=unit(0.5,'cm'))+
guides(fill=guide_legend(title=NULL))
ggsave(
'NK/satck_prop_NK.pdf',
plot = last_plot(),
device = NULL,
path = NULL,
scale = 1,
width = 10,
height = 8,
dpi = 300,
limitsize = TRUE,
)
- 在從基因表達(dá)矩陣(行為基因,列為樣本)直接生成Seurat對象時,如下:
HC_1 <- CreateSeuratObject(counts = HC_1)
得到的HC_1樣本的orig.ident默認(rèn)是樣本名中第一個_號的前一部分。所以要保證矩陣的列名是樣本名_細(xì)胞barcode
這樣的格式。
如果有多個分組,例如兩個樣本矩陣中細(xì)胞分別命名為HC_1_barcode,HC_2_barcode,在直接通過如下方法得到兩個Seurat對象,再對其進(jìn)行merge之后,兩個樣本會被合并成一個。也就是樣本信息只保留了第一個_號之前的HC,沒有保留_號之后的1和2。
HC_1 <- CreateSeuratObject(counts = HC_1)
HC_2 <- CreateSeuratObject(counts = HC_2)
scRNA <- merge(HC_1,HC_2)
table(scRNA$orig.ident)
# HC
#3000
為了避免這種情況,可以在構(gòu)建Seurat對象時通過參數(shù)進(jìn)行設(shè)置
HC_1 <- CreateSeuratObject(counts = HC_1,names.field = 1:2)
HC_2 <- CreateSeuratObject(counts = HC_2,names.field = 1:2)
scRNA <- merge(HC_1,HC_2)
table(scRNA$orig.ident)
# HC_1 HC_2
# 1500 1500
- 在做umap和tsne的時候有很多聚不在一起的小群,可以考慮下面幾種情況
(1) 雙細(xì)胞的問題
雙細(xì)胞傾向于獨立成群,或位于大群的邊緣或線狀連接部分。
(2) 高變基因數(shù)目選擇問題
FindVariableFeatures()
時nfeatures選的越多,圖越分散
(3) 降維時pc數(shù)目的選擇
做tsne和umap降維時選擇的pc數(shù)越多,圖越分散。
參考:如何確定細(xì)胞聚類的PC數(shù)
??PC數(shù)的選擇:Seurat官網(wǎng)提供的三種方法只能給出PC數(shù)的粗略范圍,選擇不同PC數(shù)目,細(xì)胞聚類效果差別較大,因此,需要一個更具體的PC數(shù)目。作者提出一個確定PC閾值的三個標(biāo)準(zhǔn):
# Determine percent of variation associated with each PC
pct <- pbmc [["pca"]]@stdev / sum( pbmc [["pca"]]@stdev) * 100
# Calculate cumulative percents for each PC
cumu <- cumsum(pct)
# Determine which PC exhibits cumulative percent greater than 90% and % variation associated with the PC as less than 5
co1 <- which(cumu > 90 & pct < 5)[1]
co1
# Determine the difference between variation of PC and subsequent PC
co2 <- sort(which((pct[1:length(pct) - 1] - pct[2:length(pct)]) > 0.1), decreasing = T)[1] + 1
# last point where change of % of variation is more than 0.1%.
co2
# Minimum of the two calculation
pcs <- min(co1, co2)
pcs
# Create a dataframe with values
plot_df <- data.frame(pct = pct, cumu = cumu, rank = 1:length(pct))
# Elbow plot to visualize
ggplot(plot_df, aes(cumu, pct, label = rank, color = rank > pcs)) +
geom_text() +
geom_vline(xintercept = 90, color = "grey") +
geom_hline(yintercept = min(pct[pct > 5]), color = "grey") +
theme_bw()
- 亞群注釋注意事項
一般先選默認(rèn)分辨率(0.8),大概可能會分出十幾個群。因為最終都是要注釋到每一個barcode,所以首先可以看大類marker的分布(不受分辨率影響),可以根據(jù)marker基因的分布來調(diào)整分辨率。是否需要精細(xì)的分群得看精細(xì)的分群對研究有沒有決定作用,還有很重要的一點是看分出的各個cluster在Findallmarkers給出的結(jié)果中marker的熱圖是不是能明顯分開。精細(xì)劃分的細(xì)胞本來就很類似,如果有部分小群的熱圖明顯分不開或者非常類似,就可以考慮把分辨率調(diào)小。
- 跑umap/tsne跟跑FindNeighbors輸入的都是PCA的矩陣,但是用的pc數(shù)可以是不一樣的。
在一些教程里面,我們常常看到這樣的代碼,在看了一下ElbowPlot之后選定了PC數(shù)就直接RunTSNE
,RunUMAP
和FindNeighbors
都用一樣的pc數(shù)。
pbmc <- RunPCA(pbmc, verbose = F)
ElbowPlot(pbmc, ndims = 50)
pc.num=1:20
pbmc <- pbmc %>% RunTSNE(dims=pc.num) %>% RunUMAP(dims=pc.num) %>%
FindNeighbors(dims = pc.num) %>% FindClusters()
這實際上是沒有必要的必須保持一致的。下游的都是用pca之后的,pca是為了壓縮數(shù)據(jù)。
umap和tsne是為了可視化(僅僅是可視化),但是FindNeighbor是計算細(xì)胞間距離矩陣。找類群數(shù)目和可視化可以說沒有關(guān)系。
- UMAP圖的分群可視化
library(dplyr)
library(Seurat)
library(patchwork)
library(tidyverse)
library(cowplot)
library(clustree)
# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
pbmc <- NormalizeData(pbmc)
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc,dims=1:20,resolution = seq(from=0,by=.2,length=10))
pbmc <- RunUMAP(pbmc, dims = 1:10)
clustree(pbmc)
Idents(pbmc) <- "RNA_snn_res.1"
p<- map(c(levels(Idents(pbmc))),function(x){DimPlot(pbmc, cells.highlight = CellsByIdentities(object = pbmc, idents = x))})
wrap_plots(plots = p, nrow=3)
## 對比27,不必先設(shè)置p=list()就可以直接使用wrap_plots是因為map生成的對象就是個list
# 或 plot_grid(plotlist = p)
map函數(shù):
R語言循環(huán)第三境界:purrr包map函數(shù)!
淺析R語言中map(映射)與reduce(規(guī)約)
批量讀入矩陣并創(chuàng)建seurat對象
??assign()
的用法
# Data loading and QC
### 讀入sample消息
samples <- read_excel("../data/metadata/patients_metadata.xlsx", range = cell_cols("A:A")) %>% .$sample_id
samples
# [1] "p018t" "p018n" "p019t" "p019n" "p023t" "p024t" "p027t" "p027n" "p028n"
# [10] "p029n" "p030t" "p030n" "p031t" "p031n" "p032t" "p032n" "p033t" "p033n"
# [19] "p034t" "p034n"
### import cellranger files from different data sets
for (i in seq_along(samples)){
assign(paste0("scs_data", i), Read10X(data.dir = paste0("../data/cellranger/", samples[i], "/filtered_feature_bc_matrix")))
}
# 讀入的每一個文件都是一個對象,命名為scs_data1-20
### create seurat objects from cellranger files
for (i in seq_along(samples)){
assign(paste0("seu_obj", i), CreateSeuratObject(counts = eval(parse(text = paste0("scs_data", i))), project = samples[i], min.cells = 3))
}
# 對每一個scs_data創(chuàng)建一個Seurat對象,命名為seu_obj1-20
### merge data sets
seu_obj <- merge(seu_obj1, y = c(seu_obj2, seu_obj3, seu_obj4, seu_obj5, seu_obj6, seu_obj7, seu_obj8, seu_obj9, seu_obj10, seu_obj11, seu_obj12, seu_obj13, seu_obj14, seu_obj15, seu_obj16, seu_obj17, seu_obj18, seu_obj19, seu_obj20), add.cell.ids = samples, project = "lung")
### calculate mitochondrial, hemoglobin and ribosomal gene counts
seu_obj <- PercentageFeatureSet(seu_obj, pattern = "^MT-", col.name = "pMT")
seu_obj <- PercentageFeatureSet(seu_obj, pattern = "^HBA|^HBB", col.name = "pHB")
seu_obj <- PercentageFeatureSet(seu_obj, pattern = "^RPS|^RPL", col.name = "pRP")
qcparams <- c("nFeature_RNA", "nCount_RNA", "pMT", "pHB", "pRP")
for (i in seq_along(qcparams)){
print(VlnPlot(object = seu_obj, features = qcparams[i], group.by = "orig.ident", pt.size = 0))
}
for (i in seq_along(qcparams)){
print(RidgePlot(object = seu_obj, features = qcparams[i], group.by = "orig.ident"))
}
VlnPlot(seu_obj, features = c("nFeature_RNA", "nCount_RNA", "pMT"), pt.size = 0, group.by = "orig.ident", ncol = 1, log = T)
ggsave2("SuppFig1B.pdf", path = "../results", width = 30, height = 20, units = "cm")
- 繪圖時顏色的傳參
ClusterName_color_panel <- c(
"Naive CD4 T" = "#DC143C", "Memory CD4 T" = "#0000FF", "CD14+ Mono" = "#20B2AA",
"B" = "#FFA500", "CD8 T" = "#9370DB", "FCGR3A+ Mono" = "#98FB98",
"NK" = "#F08080", "DC" = "#0000FF", "Platelet" = "#20B2AA"
)
ggplot(df, aes(Pseudotime, colour = cell_type, fill=cell_type)) +
geom_density(bw=0.5,size=1,alpha = 0.5)+theme_classic2()+ scale_fill_manual(name = "", values = ClusterName_color_panel)+scale_color_manual(name = "", values = ClusterName_color_panel)
參考:monocle2
- 繪圖氣泡圖/小提琴圖的時候翻轉(zhuǎn)縱坐標(biāo)
使用scale_y_discrete
+rev
p1=DotPlot(pbmc,features = c('CCR2','CD3D'),group.by = 'cell_type')+theme_bw()
p2=DotPlot(pbmc,features = c('CCR2','CD3D'),group.by = 'cell_type')+theme_bw()+scale_y_discrete(limits = rev(levels(pbmc$cell_type)))
p1|p2
- 添加matadata
custom是n行1列的矩陣,行名是細(xì)胞名,一列是想要添加的信息,比如手動注釋結(jié)果等。
scRNA <- AddMetaData(scRNA, metadata=custom)
- 批量繪制細(xì)胞群marker基因
空轉(zhuǎn)也是一樣,把FeaturePlot()
換成SpatialFeaturePlot()
即可
markerlist <- list(
Tcell = c("CD3D","CD3E"),
CD4T = c("CD4","CD40LG"),
CD8T = c("CD8A","CD8B"),
Treg = c("FOXP3", "IL2RA"),
Bcell = c("CD79B","MS4A1"),
Plasma = c("MZB1", "XBP1"),
Myeloid = c("LYZ","CST3"),
Monocyte = c("FCN1","S100A9"),
Macrophage = c("CD163","CD68"),
DC_CD1 = c("CLEC9A", "BATF3"),
DC_CD2 = c("CD1C", "FCER1A"),
DC_LAMP3 = c("LAMP3", "FSCN1"),
pDC = c("LILRA4", "IL3RA"),
Neutrophil = c("FCGR3B", "CSF3R"),
Epithelial = c("EPCAM", "KRT5"),
Endothelial = c("PECAM1", "VWF"),
Fibroblasts = c("ACTA2", "COL1A1")
)
for(i in names(markerlist)){
markers <- markerlist[[i]]
p <- FeaturePlot(pbmc, features = markers) + plot_layout()&theme(legend.position = "right")
ggsave(paste0(i, ".pdf"), p, width = 10, height = 8)
}
markers <- do.call("c",markerlist)
p <- FeaturePlot(pbmc, features = markers,ncol = 4) + plot_layout()&theme(legend.position = "right")
ggsave("Markers_PBMC_all.pdf", p, width = 18, height = 30)
- 查看不同cluster的中位基因
a<-pbmc@meta.data%>%group_by(seurat_clusters)%>%
summarise(count=n(),nCount_RNA_M =median(nCount_RNA,na.rm = TRUE),nFeature_RNA_M=median(nFeature_RNA,rm=TRUE))
a
查看不同細(xì)胞群的中位基因也是一樣
a=pbmc@meta.data%>%group_by(cell_type)%>%
summarise(count=n(),nCount_RNA_M =median(nCount_RNA,na.rm = TRUE),nFeature_RNA_M=median(nFeature_RNA,rm=TRUE))
a
查看不同樣品的中位基因也是一樣
pbmc@meta.data%>%group_by(sample)%>%
summarise(count=n(),nCount_RNA_M =median(nCount_RNA,na.rm = TRUE),nFeature_RNA_M=median(nFeature_RNA,rm=TRUE))%>%head()
或者也可以
dim(pbmc)
df<-data.frame(pbmc$nFeature_RNA,pbmc$nCount_RNA)
apply(df,2,median)
# pbmc.nFeature_RNA pbmc.nCount_RNA
# 819 2213
- 計算線粒體基因
直接使用^(MT|mt|Mt)-
,人和小鼠的數(shù)據(jù)都適用
pbmc[['percent.mito']] <- PercentageFeatureSet(object = pbmc, pattern = '^(MT|mt|Mt)-')
使用ggplot2優(yōu)化Seurat繪圖
需要注意的點:
1、坐標(biāo)提取
2、顏色對接,尤其是colorRampPalette
的使用
3、viridis的使用
4、ggplot2的aes和aes_string使用subset去了單細(xì)胞子集之后,想要在原seurat對象上查看哪些細(xì)胞被濾掉了的方法
pbmc_new <- subset(pbmc, subset = nFeature_RNA > 500 & nFeature_RNA < 2500 & percent.mt < 5)
cellp <-rownames(pbmc_new@meta.data)
pbmc$filter <-ifelse(rownames(pbmc@meta.data) %in% cellp,"Cell","filtered")
p1 <-DimPlot(pbmc,label = T,repel = T,reduction = "umap",group.by="filter")
p1
47.提取seurat自帶顏色
library(scales)
p1 <- DimPlot(scRNA)
x<-ggplot_build(p1)
info = data.frame(colour = x$data[[1]]$colour, group = x$data[[1]]$group)
info <- unique((arrange(info, group)))
cols <- as.character(info$colour)