同系列文章:
- sc-RAN-seq 數據分析||Seurat新版教程:Guided Clustering Tutorial
- sc-RAN-seq 數據分析||Seurat新版教程: Integrating datasets to learn cell-type specific responses
- sc-RAN-seq 數據分析||Seurat新版教程: Using sctransform in Seurat
- 單細胞轉錄組數據分析||Seurat新版教程:Differential expression testing
- 單細胞轉錄組 數據分析||Seurat新版教程:New data visualization methods in v3.0
- 單細胞轉錄組數據分析||Seurat并行策略
- Seurat Weekly NO.0 || 開刊詞
- Seurat Weekly NO.1 || 到底分多少個群是合適的?!
- Seurat Weekly NO.2 || 我該如何取子集
- 你到底想要什么樣的umap/tsne圖?
- scRNA-seq擬時分析 || Monocle2 踩坑教程
- scRNA-seq數據分析 || Monocle3
關于擬時分析的一些基本知識請參看以下兩篇及其參考文章:
更多詳細內容請參考monocle3官網,本文僅為個人學習筆記。
在發育過程中,細胞對刺激作出反應,并在整個生命過程中,從一種功能“狀態”過渡到另一種功能“狀態”。不同狀態的細胞表達不同的基因,產生蛋白質和代謝物的動態重復序列,從而完成它們的工作。當細胞在狀態之間移動時,它們經歷一個轉錄重組的過程,一些基因被沉默,另一些基因被激活。這些瞬時狀態通常很難描述,因為在更穩定的端點狀態之間純化細胞可能是困難的或不可能的。單細胞RNA-Seq可以使您在不需要純化的情況下看到這些狀態。然而,要做到這一點,我們必須確定每個cell在可能的狀態范圍內的位置。
Monocle介紹了利用RNA-Seq進行單細胞軌跡分析的策略。Monocle不是通過實驗將細胞純化成離散狀態,而是使用一種算法來學習每個細胞必須經歷的基因表達變化序列,作為動態生物學過程的一部分。一旦它了解了基因表達變化的整體“軌跡”,Monocle就可以將每個細胞置于軌跡中的適當位置。然后,您可以使用Monocle的微分分析工具包來查找在軌跡過程中受到調控的基因,如查找作為偽時間函數變化的基因一節所述。如果這個過程有多個結果,Monocle將重建一個“分支”軌跡。這些分支與細胞的“決策”相對應,Monocle提供了強大的工具來識別受它們影響的基因,并參與這些基因的形成。在分析單細胞軌跡中的分支的小節中,您可以看到如何分析分支。
monocle 能做的不只是擬時分析,或者說為了做擬時分析他也做了sc-rna-seq的基本分析流程:數據讀入,均一化,降維(PCA,umap,tsne,),聚類,marker基因篩選以及可視化函數。在新的學習中我們發現monocle能做的遠不只這些,例如用shiny開發了web程序,更加用戶友好;借助garnett包可以做細胞定義-----monocle已經是一個sc-rna-seq數據分析的工具箱。
library(monocle3)
packageVersion("monocle3")
[1] ‘0.1.1’
monocle3是新的開始大部分的函數名稱都改變了,連版本號都從零開始。
多種格式的數據讀入,這里我們依然是從seurat3對象中讀入:
#Generate a cell_data_set
#expression_matrix <- readRDS(url("http://staff.washington.edu/hpliner/data/cao_l2_expression.rds"))
#cell_metadata <- readRDS(url("http://staff.washington.edu/hpliner/data/cao_l2_colData.rds"))
#gene_annotation <- readRDS(url("http://staff.washington.edu/hpliner/data/cao_l2_rowData.rds"))
#cds <- new_cell_data_set(expression_matrix,
# cell_metadata = cell_metadata,
# gene_metadata = gene_annotation)
讀10X數據,cellranger V2 V3 均可:
#Generate a cell_data_set from 10X output
# Provide the path to the Cell Ranger output.
#cds <- load_cellranger_data("D:\\Users\\Administrator\\Desktop\\RStudio\\single_cell\\V2")
setwd("D:\\Users\\Administrator\\Desktop\\Novo周運來\\SingleCell\\scrna_tools")
#library(monocle)
#<-importCDS(pbmc,import_all = TRUE)
#Load Seurat object
pbmc <- readRDS('D:\\Users\\Administrator\\Desktop\\RStudio\\single_cell\\filtered_gene_bc_matrices\\hg19pbmc_tutorial.rds')
#Extract data, phenotype data, and feature data from the SeuratObject
data <- as(as.matrix(pbmc@assays$RNA@counts), 'sparseMatrix')
pd <- pbmc@meta.data
fData <- data.frame(gene_short_name = row.names(data), row.names = row.names(data))
colnames(pd)
[1] "orig.ident" "nCount_RNA" "nFeature_RNA" "percent.mt" "RNA_snn_res.0.5" "seurat_clusters"
創建cds對象,注意這里每一項是什么。
#Construct monocle cds
cds <- new_cell_data_set(data,
cell_metadata = pd,
gene_metadata = fData)
> cds
class: cell_data_set
dim: 13714 2638
metadata(1): cds_version
assays(1): counts
rownames(13714): AL627309.1 AP006222.2 ... PNRC2.1 SRSF10.1
rowData names(1): gene_short_name
colnames(2638): AAACATACAACCAC AAACATTGAGCTAC ... TTTGCATGAGAGGC TTTGCATGCCTCAC
colData names(10): orig.ident nCount_RNA ... cell_type cluster_ext_type
reducedDimNames(2): PCA UMAP
spikeNames(0):
降維
- 標準化
Monocle3中的大多數分析(包括軌跡推斷和聚類)都需要各種規范化和預處理步驟。preprocess_cds執行并存儲這些預處理步驟。
具體地說,根據選擇的參數,preprocess_cds首先根據日志和因子大小對數據進行規范化(normalizes),以處理深度差異,或者只根據大小因子進行規范化。有三種方法: PCA or LSI. For LS,默認是PCA。接下來,preprocess_cds計算一個較低的維度空間,該空間將用作進一步降維的輸入,如tSNE和UMAP。
#Pre-process the data
cds = preprocess_cds(cds, num_dim = 100)
?preprocess_cds
plot_pc_variance_explained(cds)
可視化降維
- UMAP
#Reduce dimensionality and visualize the cells
cds = reduce_dimension(cds) #Monocle uses UMAP by default
plot_cells(cds)
#No trajectory to plot. Has learn_graph() been called yet?
head(rownames(cds))
"AL627309.1" "AP006222.2" "RP11-206L10.2" "RP11-206L10.9" "LINC00115" "NOC2L"
plot_cells(cds, genes=c("S100A9", "RPS27", "FCER1A", "GNLY"))
- tSNE
cds = reduce_dimension(cds, reduction_method="tSNE")
plot_cells(cds, reduction_method="tSNE", color_cells_by="seurat_clusters")
可以自己設置分組看看是否有批次效應。
#Check for and remove batch effects
plot_cells(cds, color_cells_by="seurat_clusters", label_cell_groups=FALSE)
聚類
無監督聚類是許多單細胞表達工作中的一個常見步驟。在包含多種細胞類型的實驗中,每個cluxter可能對應不同的細胞類型。該函數接受cell_data_set作為輸入,使用Louvain community detection對細胞進行聚類,并返回一個cell_data_set,其中包含內部存儲的聚類結果。
#Group cells into clusters
#library(reticulate)
#use_python("E:\\conda\\python.exe")
#reticulate::py_install("louvain")
cds = cluster_cells(cds, python_home = "E:\\conda\\python",verbose = T,resolution=c(10^seq(-6,-1)))
Running louvain clustering algorithm ...
Run kNN based graph clustering starts:
-Input data of 2638 rows and 2 columns
-k is set to 20
Finding nearest neighbors...DONE ~ 0.129999999997381 s
Compute jaccard coefficient between nearest-neighbor sets ...DONE ~ 0.129999999997381 s
Build undirected graph from the weighted links ...DONE ~ 0.14 s
Run louvain clustering on the graph ...
Running louvain iteration 1 ...
Current iteration is 1; current resolution is 1e-06; Modularity is 0.547843095426104; Number of clusters are 3
Current iteration is 1; current resolution is 1e-05; Modularity is 0.547843095426104; Number of clusters are 3
Current iteration is 1; current resolution is 1e-04; Modularity is 0.547843095426104; Number of clusters are 3
Current iteration is 1; current resolution is 0.001; Modularity is 0.723545062987134; Number of clusters are 5
Current iteration is 1; current resolution is 0.01; Modularity is 0.865973276843872; Number of clusters are 13
Current iteration is 1; current resolution is 0.1; Modularity is 0.822758898433183; Number of clusters are 49
Maximal modularity is 0.865973276843872; corresponding resolution is 0.01
Run kNN based graph clustering DONE, totally takes 2.71215486526489 s.
-Number of clusters: 13
plot_cells(cds,graph_label_size=15,cell_size=1.5)
尋找marker 基因
#Find marker genes expressed by each cluster
marker_test_res = top_markers(cds, group_cells_by="seurat_clusters", reference_cells=1000, cores=8)
library(dplyr)
top_specific_markers = marker_test_res %>%
filter(fraction_expressing >= 0.10) %>%
group_by(cell_group) %>%
top_n(1, pseudo_R2)
top_specific_marker_ids = unique(top_specific_markers %>% pull(gene_id))
plot_genes_by_group(cds,
top_specific_marker_ids,
group_cells_by="seurat_clusters",
ordering_type="maximal_on_diag",
max.size=3)
top_specific_markers = marker_test_res %>%
filter(fraction_expressing >= 0.10) %>%
group_by(cell_group) %>%
top_n(3, pseudo_R2)
top_specific_marker_ids = unique(top_specific_markers %>% pull(gene_id))
plot_genes_by_group(cds,
top_specific_marker_ids,
group_cells_by="seurat_clusters",
ordering_type="cluster_row_col",
max.size=3)
已知細胞類型
#Annotate your cells according to type
colData(cds)$assigned_cell_type=as.character(clusters(cds))
colData(cds)$assigned_cell_type = dplyr::recode(colData(cds)$assigned_cell_type,
"1"="Body wall muscle",
"2"="Germline","3"="Unclassified neurons","4"="Seam cells",
"5"="Coelomocytes",
"6"="Pharyngeal epithelia",
"7"="Vulval precursors",
"8"="Non-seam hypodermis",
"9"="Intestinal/rectal muscle",
"10"="Touch receptor neurons",
"11"="Unclassified neurons",
"12"="flp-1(+) interneurons",
"13"="Canal associated neurons")
plot_cells(cds, group_cells_by="cluster", color_cells_by="assigned_cell_type",group_label_size=4,cell_size=1.5)
手動選擇細胞
cds_subset = choose_cells(cds)
#Warning: package ‘shiny’ was built under R version 3.5.3
軌跡推斷
Monocle3的目的是在實驗中了解細胞是如何通過一個基因表達變化的生物程序進行轉化的。每個細胞都可以看作是高維空間中的一個點,每個維描述了不同基因的表達。識別基因表達變化的程序相當于學習細胞在這個空間中遵循的軌跡。然而,分析中維度越多,學習軌跡就越困難。
幸運的是,許多基因通常彼此共存,因此可以使用各種不同的算法來降低數據的維數。Monocle3通過reduce_dimension提供了兩種不同的降維算法(UMAP和tSNE)。兩者都使用cell_data_set對象和一些允許用于縮小空間的維度。您還可以提供一個模型公式,指示從數據中“減去”的一些變量(例如批ID或其他技術因素),這樣它就不會對軌跡產生影響。
函數learn_graph是繼preprocess_cds、reduce_dimensions和cluster_cells之后的軌跡構建過程的第四個步驟。在learn_graph之后,通常調用order_cells。
> cds <- learn_graph(cds)
|===============================================================================================================================================| 100%
|===============================================================================================================================================| 100%
|===============================================================================================================================================| 100%
> heand(colData(cds))
> head(colData(cds))
DataFrame with 6 rows and 11 columns
orig.ident nCount_RNA nFeature_RNA percent.mt RNA_snn_res.0.5 seurat_clusters Size_Factor garnett_cluster cell_type cluster_ext_type assigned_cell_type
<factor> <numeric> <integer> <numeric> <factor> <factor> <numeric> <logical> <character> <character> <character>
AAACATACAACCAC pbmc3k 2419 779 3.01777594047127 1 1 1.10763503821696 NA T cells CD4 T cells Coelomocytes
AAACATTGAGCTAC pbmc3k 4903 1352 3.79359575769937 3 3 2.24503290300858 NA Unknown B cells Unclassified neurons
AAACATTGATCAGC pbmc3k 3147 1129 0.889736256752463 1 1 1.44097869585315 NA CD4 T cells CD4 T cells Seam cells
AAACCGTGCTTCCG pbmc3k 2639 960 1.74308450170519 2 2 1.20837075893119 NA Monocytes Monocytes flp-1(+) interneurons
AAACCGTGTATGCG pbmc3k 980 521 1.22448979591837 6 6 0.44873184681795 NA NK cells NK cells Intestinal/rectal muscle
AAACGCACTGGTAC pbmc3k 2163 781 1.66435506241331 1 1 0.99041529047676 NA T cells CD4 T cells Seam cells
plot_cells(cds,
color_cells_by = "assigned_cell_type",
label_groups_by_cluster=FALSE,
label_leaves=FALSE,
label_branch_points=FALSE,
group_label_size=4,cell_size=1.5)
選擇root
#Order the cells in pseudotime
cds = order_cells(cds)
plot_cells(cds,
color_cells_by = "pseudotime",
label_cell_groups=FALSE,
label_leaves=TRUE,
label_branch_points=TRUE,
graph_label_size=1.5,
group_label_size=4,cell_size=1.5)
# a helper function to identify the root principal points:
get_earliest_principal_node <- function(cds, time_bin="Body wall muscle"){
cell_ids <- which(colData(cds)[, "assigned_cell_type"] == time_bin)
closest_vertex <-cds@principal_graph_aux[["UMAP"]]$pr_graph_cell_proj_closest_vertex
closest_vertex <- as.matrix(closest_vertex[colnames(cds), ])
root_pr_nodes <-
igraph::V(principal_graph(cds)[["UMAP"]])$name[as.numeric(names(which.max(table(closest_vertex[cell_ids,]))))]
root_pr_nodes
}
cds = order_cells(cds, root_pr_nodes=get_earliest_principal_node(cds))
plot_cells(cds,
color_cells_by = "pseudotime",
label_cell_groups=FALSE,
label_leaves=FALSE,
label_branch_points=FALSE,
graph_label_size=1.5,
group_label_size=4,cell_size=1.5)
3D 圖
#Working with 3D trajectories
cds_3d = reduce_dimension(cds, max_components = 3)
cds_3d = cluster_cells(cds_3d)
cds_3d = learn_graph(cds_3d)
cds_3d = order_cells(cds_3d, root_pr_nodes=get_earliest_principal_node(cds))
cds_3d_plot_obj = plot_cells_3d(cds_3d, color_cells_by="assigned_cell_type")
cds_3d_plot_obj
單個基因的擬時軌跡
AFD_genes = c("S100A9", "RPS27", "FCER1A")
AFD_lineage_cds = cds[AFD_genes,
clusters(cds) %in% c(11, 12, 5)]
plot_genes_in_pseudotime(AFD_lineage_cds,
color_cells_by="pseudotime",
min_expr=0.5)
細胞定義
setwd("D:\\Users\\Administrator\\Desktop\\Novo周運來\\SingleCell\\scrna_tools")
library(garnett)
load("hsPBMC")# 下載好的訓練模型
library(org.Hs.eg.db)
cds <- classify_cells(cds, hsPBMC,
db = org.Hs.eg.db,
cluster_extend = TRUE,
cds_gene_id_type = "SYMBOL")
> head(pData(cds))
DataFrame with 6 rows and 11 columns
orig.ident nCount_RNA nFeature_RNA percent.mt RNA_snn_res.0.5 seurat_clusters Size_Factor garnett_cluster cell_type cluster_ext_type assigned_cell_type
<factor> <numeric> <integer> <numeric> <factor> <factor> <numeric> <logical> <character> <character> <character>
AAACATACAACCAC pbmc3k 2419 779 3.01777594047127 1 1 1.10763503821696 NA T cells CD4 T cells Coelomocytes
AAACATTGAGCTAC pbmc3k 4903 1352 3.79359575769937 3 3 2.24503290300858 NA Unknown B cells Unclassified neurons
AAACATTGATCAGC pbmc3k 3147 1129 0.889736256752463 1 1 1.44097869585315 NA CD4 T cells CD4 T cells Seam cells
AAACCGTGCTTCCG pbmc3k 2639 960 1.74308450170519 2 2 1.20837075893119 NA Monocytes Monocytes flp-1(+) interneurons
AAACCGTGTATGCG pbmc3k 980 521 1.22448979591837 6 6 0.44873184681795 NA NK cells NK cells Intestinal/rectal muscle
AAACGCACTGGTAC pbmc3k 2163 781 1.66435506241331 1 1 0.99041529047676 NA T cells CD4 T cells Seam cells
> table(pData(cds)$cell_type)
B cells CD34+ CD4 T cells CD8 T cells Dendritic cells Monocytes NK cells T cells Unknown
297 3 563 147 27 421 252 345 583
plot_cells(cds,
group_cells_by="partition",
color_cells_by="cell_type",
cell_size=1.5,
group_label_size=5)
回歸分析
在本節中,我們將探索如何使用Monocle來發現根據幾種不同標準表達不同的基因。根據分析的復雜程度,對cell_data_set對象中的所有基因執行差異表達分析可能需要幾分鐘到幾個小時。為了讓這個小插曲簡單而快速,我們將使用一組小的基因。不過,請放心,Monocle即使在大型實驗中也可以分析數千個基因,這對于在您正在研究的生物學過程中發現動態調控基因非常有用。
Monocle中的差異分析工具非常靈活。Monocle的工作原理是為每個基因擬合一個回歸模型。您可以指定此模型來考慮實驗中的各種因素(時間、治療等)。例如,在胚胎數據中,細胞是在不同的時間點收集的。我們可以通過先對每個基因擬合一個廣義線性模型來測試上述基因的表達是否會隨著時間發生變化:
ciliated_genes = top_specific_marker_ids[0:4]
cds_subset = cds[rowData(cds)$gene_short_name %in% ciliated_genes,]
gene_fits = fit_models(cds_subset, model_formula_str = "~seurat_clusters")
# A tibble: 4 x 4
gene_short_name model model_summary status
<fct> <list> <list> <chr>
1 S100A9 <speedglm> <smmry.sp> OK
2 S100A8 <speedglm> <smmry.sp> OK
3 RPS27 <speedglm> <smmry.sp> OK
4 FCER1A <speedglm> <smmry.sp> OK
gene_fits是一個包含每個基因一行的tibble。模型列包含廣義線性模型對象,每個模型對象都旨在使用上面的方程解釋基因在細胞間的表達。參數model_formula a_str應該是指定模型公式的字符串。您在測試中使用的模型公式可以包含colData表中作為列存在的任何術語,包括Monocle在其他分析步驟中添加的那些列。例如,如果使用cluster_cells,可以使用cluster或partition(分別)作為模型公式來測試集群和分區之間不同的基因。您還可以包含多個變量,例如~胚。時間+批處理,這對于減去不需要的效果非常有用。
> fit_coefs = coefficient_table(gene_fits)
> fit_coefs
# A tibble: 36 x 10
gene_short_name status term estimate std_err test_val p_value normalized_effect model_component q_value
<fct> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
1 S100A9 OK (Intercept) -1.78 0.196 -9.08 2.07e- 19 0 count 2.07e- 19
2 S100A9 OK seurat_clusters1 0.129 0.295 0.437 6.62e- 1 0.176 count 1.00e+ 0
3 S100A9 OK seurat_clusters2 5.16 0.196 26.3 2.36e-135 7.36 count 7.08e-135
4 S100A9 OK seurat_clusters3 0.0943 0.330 0.286 7.75e- 1 0.129 count 1.00e+ 0
5 S100A9 OK seurat_clusters4 0.00262 0.369 0.0071 9.94e- 1 0.00357 count 9.94e- 1
6 S100A9 OK seurat_clusters5 2.80 0.220 12.7 3.82e- 36 3.96 count 1.15e- 35
7 S100A9 OK seurat_clusters6 -0.223 0.503 -0.443 6.58e- 1 -0.301 count 1.00e+ 0
8 S100A9 OK seurat_clusters7 2.68 0.309 8.68 7.04e- 18 3.79 count 1.41e- 17
9 S100A9 OK seurat_clusters8 1.70 0.621 2.74 6.16e- 3 2.39 count 1.85e- 2
10 S100A8 OK (Intercept) -2.33 0.230 -10.1 1.29e- 23 0 count 2.58e- 23
# ... with 26 more rows
> emb_time_terms = fit_coefs %>% filter(term == "seurat_clusters1")
> emb_time_terms
# A tibble: 4 x 10
gene_short_name status term estimate std_err test_val p_value normalized_effect model_component q_value
<fct> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
1 S100A9 OK seurat_clusters1 0.129 0.295 0.437 6.62e- 1 0.176 count 1.00e+ 0
2 S100A8 OK seurat_clusters1 0.190 0.341 0.558 5.77e- 1 0.251 count 1.00e+ 0
3 RPS27 OK seurat_clusters1 -0.192 0.0174 -11.1 8.74e-28 -0.277 count 3.50e-27
4 FCER1A OK seurat_clusters1 -2.47 1.30 -1.90 5.70e- 2 -1.51 count 1.71e- 1
>
現在,讓我們找出那些具有重要時間成分的基因。ent_table()計算每個系數在Wald檢驗下是否顯著不同于零。默認情況下,ent_table()使用Benjamini和Hochberg方法對這些p值進行調整,用于多重假設檢驗。這些調整值可以在q_value列中找到。我們可以對結果進行過濾,控制假發現率如下:
emb_time_terms = fit_coefs %>% filter(term == "seurat_clusters1")
emb_time_terms %>% filter (q_value < 0.05) %>%
select(gene_short_name, term, q_value, estimate)
plot_genes_violin(cds_subset[,], group_cells_by="cell_type", ncol=2) +
theme(axis.text.x=element_text(angle=45, hjust=1))