单细胞转录组

【单细胞转录组】monocle 脚本小记

2020-04-22  本文已影响0人  XuningFan

文章转自:
作者:周运来就是我

链接:https://www.jianshu.com/p/66c387e1de3d

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Seurat2monocle

library(monocle)
#<-importCDS(pbmc,import_all = TRUE)
#Load Seurat object
pbmc <- readRDS('hg19pbmc_tutorial.rds')

#Extract data, phenotype data, and feature data from the SeuratObject
data <- as(as.matrix(pbmc@assays$RNA@counts), 'sparseMatrix')
pd <- new('AnnotatedDataFrame', data = pbmc@meta.data)
fData <- data.frame(gene_short_name = row.names(data), row.names = row.names(data))
fd <- new('AnnotatedDataFrame', data = fData)

#Construct monocle cds
monocle_cds <- newCellDataSet(data,
                              phenoData = pd,
                              featureData = fd,
                              lowerDetectionLimit = 0.5,
                              expressionFamily = negbinomial.size())

如果你只有count矩阵可以这么读入

#do not run
HSMM_expr_matrix <- read.table("fpkm_matrix.txt")
HSMM_sample_sheet <- read.delim("cell_sample_sheet.txt")
HSMM_gene_annotation <- read.delim("gene_annotations.txt")

pd <- new("AnnotatedDataFrame", data = HSMM_sample_sheet)
fd <- new("AnnotatedDataFrame", data = HSMM_gene_annotation)
HSMM <- newCellDataSet(as.matrix(HSMM_expr_matrix),
    phenoData = pd, featureData = fd)

对于输入文件,有3种类型的格式:
一种是单细胞运行获得的3个结果文件。
exprs, a numeric matrix of expression values, where rows are genes, and columns are cells
phenoData, an AnnotatedDataFrame object, where rows are cells, and columns are cell attributes** (such as cell type, culture condition, day captured, etc.)
featureData, an AnnotatedDataFrame object, where rows are features (e.g. genes), and columns are gene attributes, such as biotype, gc content, etc.

  1. 准备需要进行拟时间分析数据的三个文件:
    表达量文件:exprs:基因在所有细胞中的count值矩阵
    2表型文件 phenoData:
    该文件即为每个细胞的barcode信息。
    3)featureData:
    该文件为所有基因名信息,有两种格式,一种是Ensemble Id和Symbol Id的组合,一种均是Symbol Id,但要保证第二列一定是Symbol Id。

官网给出许多其他建议以及读入数据的注意事项,需要注意的是,如果是UMI数据,不应该在创建CellDataSet之前自己对其进行标准化。也不应该试图将UMI计数转换为相对丰度(通过将其转换为FPKM/TPM数据)。Monocle将在内部执行所有需要的标准化步骤。自己将其正常化可能会破坏Monocle的一些关键步骤。

数据质控

> HSMM<-monocle_cds
## 归一化 
> HSMM <- estimateSizeFactors(HSMM)
> HSMM <- estimateDispersions(HSMM)
#Filtering low-quality cells
> HSMM <- detectGenes(HSMM, min_expr = 3 )
> print(head(fData(HSMM)))
              gene_short_name num_cells_expressed
AL627309.1         AL627309.1                   9
AP006222.2         AP006222.2                   3
RP11-206L10.2   RP11-206L10.2                   5
RP11-206L10.9   RP11-206L10.9                   3
LINC00115           LINC00115                  18
NOC2L                   NOC2L                 254
> expressed_genes <- row.names(subset(fData(HSMM),
+                                     num_cells_expressed >= 10))
> print(head(pData(HSMM)))
               orig.ident nCount_RNA nFeature_RNA percent.mt RNA_snn_res.0.5 seurat_clusters Size_Factor num_genes_expressed
AAACATACAACCAC     pbmc3k       2419          779  3.0177759               1               1          NA                 779
AAACATTGAGCTAC     pbmc3k       4903         1352  3.7935958               3               3          NA                1352
AAACATTGATCAGC     pbmc3k       3147         1129  0.8897363               1               1          NA                1129
AAACCGTGCTTCCG     pbmc3k       2639          960  1.7430845               2               2          NA                 960
AAACCGTGTATGCG     pbmc3k        980          521  1.2244898               6               6          NA                 521
AAACGCACTGGTAC     pbmc3k       2163          781  1.6643551               1               1          NA                 781###### 细胞分类(Classifying)

Monocle提供了一个简单的系统,可以根据您选择的marker基因的表达来标记细胞。您只需提供Monocle可以用来注释每个单元格的一组函数。

聚类

第一步是决定用哪些基因来进行聚类(特征选择)。我们可以使用所有的基因,但是我们将包括很多没有表达到足够高水平来提供有意义的信号的基因,它们只会给系统增加噪音。我们可以根据平均表达水平筛选基因,我们还可以选择细胞间异常变异的基因。这些基因往往对细胞状态有很高的信息含量。

#Clustering cells without marker genes 

disp_table <- dispersionTable(HSMM)
unsup_clustering_genes <- subset(disp_table, mean_expression >= 0.1)
HSMM <- setOrderingFilter(HSMM, unsup_clustering_genes$gene_id)
plot_ordering_genes(HSMM)

image

红线表示单片基于这种关系对色散的期望。我们标记用于聚类的基因用黑点表示,其他的用灰点表示。

# Plots the percentage of variance explained by the each component based on PCA from the normalized expression data using the same procedure used in reduceDimension function.
# HSMM@auxClusteringData[["tSNE"]]$variance_explained <- NULL
plot_pc_variance_explained(HSMM, return_all = F) # norm_method='log'

image
> HSMM <- reduceDimension(HSMM, max_components = 2, num_dim = 10,
+                         reduction_method = 'tSNE', verbose = T)
Remove noise by PCA ...
Reduce dimension by tSNE ...
> HSMM <- clusterCells(HSMM, num_clusters = 2)
Distance cutoff calculated to 2.589424 
> plot_cell_clusters(HSMM, 1, 2, color = "CellType",
+                    markers = c("CDC20", "GABPB2"))

image

我发现指定cluster为5的时候,只能画出来4个,为什么?

HSMM <- clusterCells(HSMM, num_clusters = 5)
plot_cell_clusters(HSMM, 1, 2)

image

Monocle允许我们减去“无趣的”变异源的影响,以减少它们对集群的影响。您可以使用到clusterCells和其他几个Monocle函数的residualmodelformula astr参数来实现这一点。此参数接受一个R模型公式字符串,该字符串指定要在cluster之前减去。

HSMM <- reduceDimension(HSMM, max_components = 2, num_dim = 2,
                        reduction_method = 'tSNE',
                        residualModelFormulaStr = "~Size_Factor + num_genes_expressed",
                        verbose = T)
HSMM <- clusterCells(HSMM, num_clusters = 5)
plot_cell_clusters(HSMM, 1, 2, color = "Cluster")  # 图不放了

plot_cell_clusters(HSMM, 1, 2, color = "Cluster") +
  facet_wrap(~CellType)

image

monocle 支持半监督聚类Clustering cells using marker genes来定义细胞以及外部导入细胞类型(Imputing cell type)(cell与type对应文件),这里均不再展示。

构建轨迹

在发育过程中,细胞会对刺激做出反应,并在整个生命过程中,从一种功能“状态”转变为另一种功能“状态”。不同状态的细胞表达不同的基因,产生蛋白质和代谢物的动态重复序列,从而完成它们的工作。当细胞在不同状态间移动时,会经历一个转录重组的过程,其中一些基因被沉默,另一些基因被激活。这些瞬时状态通常很难描述,因为在更稳定的端点状态之间纯化细胞可能是困难的或不可能的。

单细胞RNA-Seq可以使您在不需要纯化的情况下看到这些状态。然而,要做到这一点,我们必须确定每个细胞的可能状态区间。

Monocle介绍了利用RNA-Seq进行单细胞轨迹分析的策略。Monocle不是通过实验将细胞纯化成离散状态,而是使用一种算法来学习每个细胞必须经历的基因表达变化序列,作为动态生物学过程的一部分。一旦它了解了基因表达变化的整体“轨迹”,Monocle就可以将每个细胞置于轨迹中的适当位置。

然后,您可以使用Monocle的微分分析工具包来查找在轨迹过程中受到调控的基因,如查找作为伪时间函数变化的基因。如果这个过程有多个结果,Monocle将重建一个“分支”轨迹。这些分支与细胞的“决策”相对应,Monocle提供了强大的工具来识别受它们影响的基因,并参与这些基因的形成以及如何进行分析分支。Monocle依靠一种叫做反向图嵌入的机器学习技术来构建单细胞轨迹。

在开始之前您也需要问,什么是拟时(伪时间)分析。

伪时间是衡量单个细胞在细胞分化等过程中取得了多大进展的指标。在许多生物学过程中,细胞并不是完全同步的。在细胞分化等过程的单细胞表达研究中,捕获的细胞在分化方面可能分布广泛。也就是说,在同一时间捕获的细胞群中,有些细胞可能已经很长时间了,而有些细胞甚至还没有开始这个过程。

当您想要了解在细胞从一种状态转换到另一种状态时所发生的调节更改的顺序时,这种异步性会产生主要问题。跟踪同时捕获的细胞间的表达可以产生对基因动力学一个大致的认识,该基因表达的明显变异性将非常高。Monocle根据每个cell在学习轨迹上的进展对其进行排序,从而缓解了由于异步而产生的问题。

Monocle不是跟踪表达式随时间变化的函数,而是跟踪沿轨迹变化的函数,我们称之为伪时间。伪时间是一个抽象的分化单位:它只是一个cell到轨迹起点的距离,沿着最短路径测量。轨迹的总长度是由细胞从起始状态移动到结束状态所经历的总转录变化量来定义的。

The ordering workflow
基因的选择

首先,我们必须决定我们将使用哪些基因来定义细胞在肌生成过程中的进展。我们最终想要的是一组基因,能够随着我们研究过程的进展而增加(或减少)表达。

理想情况下,我们希望尽可能少地使用正在研究的系统生物学的先验知识。我们希望从数据中发现重要的排序基因,而不是依赖于文献和教科书,因为这可能会在排序中引入偏见。我们将从一种更简单的方法开始,但是我们通常推荐一种更复杂的方法,称为“dpFeature”。

diff_test_res <- differentialGeneTest(HSMM[expressed_genes,],
                                      fullModelFormulaStr = "~percent.mt")
ordering_genes <- row.names (subset(diff_test_res, qval < 0.1)) ## 不要也写0.1 ,而是要写0.01。

HSMM <- setOrderingFilter(HSMM, ordering_genes)
plot_ordering_genes(HSMM)

image

根据时间点的差异分析来选择基因通常是非常有效的,但是如果我们没有时间序列数据呢?如果细胞在我们的生物过程中是异步分化的(通常是这样),Monocle通常可以从同时捕获的单个种群重建它们的轨迹。下面是两种选择基因的方法,它们完全不需要知道实验的设计。

一旦我们有了一个用于排序的基因id列表,我们就需要在HSMM对象中设置它们,因为接下来的几个函数将依赖于它们。

降维
#Trajectory step 2: reduce data dimensionality  
HSMM <- reduceDimension(HSMM, max_components = 2,
                            method = 'DDRTree')

排序
#Trajectory step 3: order cells along the trajectory  
HSMM <- orderCells(HSMM)
plot_cell_trajectory(HSMM, color_by = "seurat_clusters")

image

有了树结构分类颜色是可以侄自己指定的。轨迹呈树形结构,Monocle事先不知道应该调用树的哪个轨迹中的哪个来调用“开始”,所以我们经常不得不再次使用root_state参数调用orderCells来指定开始。首先,我们绘制轨迹,这次按“状态”给细胞上色。

···
plot_cell_trajectory(HSMM, color_by = "State")
···

image
plot_cell_trajectory(HSMM, color_by = "Pseudotime")

image

“状态”只是单片树的术语,表示这段树。下面的函数便于识别包含时间为零的大多数细胞的状态。然后我们可以把它传递给orderCells

GM_state <- function(cds){
  if (length(unique(pData(cds)$State)) > 1){
    T0_counts <- table(pData(cds)$State, pData(cds)$seurat_clusters)[,"0"]
    return(as.numeric(names(T0_counts)[which
                                       (T0_counts == max(T0_counts))]))
  } else {
    return (1)
  }
}
HSMM_1 <- orderCells(HSMM, root_state = GM_state(HSMM))
plot_cell_trajectory(HSMM_1, color_by = "Pseudotime")

image

可以看出不同的排序条件拟时方向是不一样的。同时如果想看每个状态下细胞的分化可以指定分面,当然你也可以指定其他的分面方式。

plot_cell_trajectory(HSMM_myo, color_by = "State") +
    facet_wrap(~State, nrow = 1)

image

如果没有timeseries,可能需要根据某些标记基因的表达位置来设置根,使用您对系统的生物学知识。例如,在这个实验中,高度增殖的祖细胞群产生两种有丝分裂后的细胞。所以根应该有表达高水平增殖标记的细胞。我们可以使用抖动图找出对应于快速增殖的状态

blast_genes <- row.names(subset(fData(HSMM),
                                gene_short_name %in% c("CCNB2", "NOC2L", "CDC20")))
plot_genes_jitter(HSMM[blast_genes,],
                  grouping = "State",
                  min_expr = 0.1)

image

单个基因的时间变化(我可以随意选择基因而你不可以,你要选有意义的生活)

HSMM_expressed_genes <-  row.names(subset(fData(HSMM),
                                          num_cells_expressed >= 10))
HSMM_filtered <- HSMM[HSMM_expressed_genes,]
my_genes <- row.names(subset(fData(HSMM_filtered),
                             gene_short_name %in% c("YWHAB", "ICAM2", "ICAM2")))
cds_subset <- HSMM_filtered[my_genes,]
plot_genes_in_pseudotime(cds_subset, color_by = "seurat_clusters")

image
差异分析

差异基因表达分析是RNA-Seq实验中的一项常见任务。Monocle可以帮助你找到不同细胞群间差异表达的基因,并评估这些变化的统计显著性。这些比较要求您有一种方法将细胞收集到两个或更多组中。这些组由每个CellDataSet的表现型数据表中的列定义。Monocle将评估不同细胞群中每个基因表达水平的显著性。

marker_genes <- row.names(subset(fData(HSMM),
                                 gene_short_name %in% c("MEF2C", "MEF2D", "MYF5",
                                                        "ANPEP", "PDGFRA","MYOG",
                                                        "TPM1",  "TPM2",  "MYH2",
                                                        "MYH3",  "NCAM1", "TNNT1",
                                                        "TNNT2", "TNNC1", "CDK1",
                                                        "CDK2",  "CCNB1", "CCNB2",
                                                        "CCND1", "CCNA1", "ID1")))

diff_test_res <- differentialGeneTest(HSMM[marker_genes,],
                                      fullModelFormulaStr = "~percent.mt")
> head(diff_test_res)
      status           family       pval      qval gene_short_name num_cells_expressed use_for_ordering
MEF2D     OK negbinomial.size 0.10544931 0.4590520           MEF2D                   1            FALSE
CCNB1     OK negbinomial.size 0.45277970 0.7043240           CCNB1                   1            FALSE
MEF2C     OK negbinomial.size 0.28733226 0.5028315           MEF2C                   2            FALSE
TPM2      OK negbinomial.size 0.94348541 0.9696949            TPM2                   0            FALSE
CDK1      OK negbinomial.size 0.12768261 0.4590520            CDK1                   0            FALSE
CCND1     OK negbinomial.size 0.04021331 0.4590520           CCND1                   0            FALSE

MYOG_ID1 <- HSMM[row.names(subset(fData(HSMM),
                                      gene_short_name %in% c("CCND1", "CCNB2"))),]
plot_genes_jitter(MYOG_ID1, grouping = "seurat_clusters", ncol= 2)

image
选择对区分细胞类型有意义的基因(Finding Genes that Distinguish Cell Type or State )
#Finding Genes that Distinguish Cell Type or State 
to_be_tested <- row.names(subset(fData(HSMM),
                                 gene_short_name %in% c("CDC20", "NCAM1", "ANPEP")))
cds_subset <- HSMM[to_be_tested,]

diff_test_res <- differentialGeneTest(cds_subset,
                                      fullModelFormulaStr = "~CellType")
diff_test_res[,c("gene_short_name", "pval", "qval")]

plot_genes_jitter(cds_subset,
                  grouping = "CellType",
                  color_by = "CellType",
                  nrow= 1,
                  ncol = NULL,
                  plot_trend = TRUE)

image
full_model_fits <-
  fitModel(cds_subset,  modelFormulaStr = "~CellType")
reduced_model_fits <- fitModel(cds_subset, modelFormulaStr = "~1")
diff_test_res <- compareModels(full_model_fits, reduced_model_fits)
diff_test_res

      status           family        pval       qval
CDC20     OK negbinomial.size 0.007822883 0.02346865
NCAM1     OK negbinomial.size 0.791131484 0.88906005
ANPEP     OK negbinomial.size 0.889060052 0.88906005

Monocle中的差异分析过程非常灵活:您在测试中使用的模型公式可以包含pData表中作为列存在的任何项,包括Monocle在其他分析步骤中添加的列。例如,如果您使用集群细胞,您可以使用集群作为模型公式来测试cluster之间不同的基因。

Finding Genes that Change as a Function of Pseudotime

Monocle的主要工作是将细胞按照生物过程(如细胞分化)的顺序排列,而不事先知道要查看哪些基因。一旦这样做了,你就可以分析细胞,找到随着细胞进步而变化的基因。例如,你可以发现当细胞“成熟”时,基因显著上调。

to_be_tested <- row.names(subset(fData(HSMM),
                                 gene_short_name %in% c("MYH3", "MEF2C", "CCNB2", "TNNT1")))
cds_subset <- HSMM[to_be_tested,]

diff_test_res <- differentialGeneTest(cds_subset,
                                      fullModelFormulaStr = "~sm.ns(Pseudotime)")

diff_test_res[,c("gene_short_name", "pval", "qval")]

      gene_short_name         pval         qval
MEF2C           MEF2C 2.996841e-02 3.995789e-02
CCNB2           CCNB2 5.328721e-03 1.065744e-02
MYH3             MYH3 6.371156e-01 6.371156e-01
TNNT1           TNNT1 1.634704e-12 6.538818e-12

plot_genes_in_pseudotime(cds_subset, color_by = "seurat_clusters")

image
Clustering Genes by Pseudotemporal Expression Pattern

在研究时间序列基因表达研究时,一个常见的问题是:“哪些基因遵循相似的动力学趋势?”Monocle可以通过将具有相似趋势的基因分组来帮助你回答这个问题,这样你就可以分析这些基因组,看看它们有什么共同之处。Monocle提供了一种方便的方法来可视化所有伪时间相关的基因。函数plot_pseudotime_heatmap接受一个CellDataSet对象(通常只包含重要基因的子集),并生成与plot_genes_in_pseudotime类似的平滑表达曲线.然后,它将这些基因聚类并使用pheatmap包绘制它们。这允许您可视化基因模块,这些模块在伪时间内共同变化。

注意下面的num_clusters 指的是基因可以聚成几个类,而不是细胞。

diff_test_res <- differentialGeneTest(HSMM[marker_genes,],
                                      fullModelFormulaStr = "~sm.ns(Pseudotime)")
sig_gene_names <- row.names(subset(diff_test_res, qval < 0.1))
plot_pseudotime_heatmap(HSMM[sig_gene_names,],
                        num_clusters = 6,
                        cores = 1,
                        show_rownames = T)

image
Multi-Factorial Differential Expression Analysis

Monocle可以在多个因素存在的情况下进行差异分析,这可以帮助你减去一些因素来看到其他因素的影响。在下面的简单例子中,Monocle测试了三个基因在成肌细胞和成纤维细胞之间的差异表达,同时减去percent.mt的影响。为此,我们必须同时指定完整模型和简化模型。完整的模型同时捕捉细胞类型和percent.mt的影响。

to_be_tested <-
  row.names(subset(fData(HSMM),
                   gene_short_name %in% c("TPM1", "MYH3", "CCNB2", "GAPDH")))

cds_subset <- HSMM[to_be_tested,]

diff_test_res <- differentialGeneTest(cds_subset,
                                      fullModelFormulaStr = "~CellType + percent.mt",
                                      reducedModelFormulaStr = "~percent.mt")
diff_test_res[,c("gene_short_name", "pval", "qval")]

      gene_short_name       pval      qval
GAPDH           GAPDH 0.07990737 0.1598147
CCNB2           CCNB2 0.04148172 0.1598147
TPM1             TPM1 0.90861287 0.9086129
MYH3             MYH3 0.77085745 0.9086129

plot_genes_jitter(cds_subset,
                  grouping = "seurat_clusters", color_by = "CellType", plot_trend = TRUE) +
  facet_wrap( ~ feature_label, scales= "free_y")

image
Analyzing Branches in Single-Cell Trajectories

通常,单细胞的轨迹包括分支。分支的产生是因为细胞执行替代基因表达程序。在发育过程中,当细胞做出命运的选择时,分支就会出现在轨迹中:一个发育谱系沿着一条路径前进,而另一个谱系产生第二条路径。Monocle包含用于分析这些分支事件的广泛功能。

芭芭拉·特雷特琳和她的同事们在史蒂夫·奎克的实验室里进行了一项实验,他们从正在发育的老鼠肺中获取细胞。他们在细胞发育的早期捕获细胞,之后当肺包含两种主要类型的上皮细胞(AT1和AT2),以及即将决定成为AT1或AT2的细胞时。Monocle可以将这个过程重构为一个分支轨迹,让你可以非常详细地分析决策点。下图显示了使用Monocle的一些数据重建的一般方法。有一个单独的分支,标记为“1”。当细胞从树的左上方通过树枝的早期发育阶段通过时,哪些基因发生了变化?哪些基因在分支间有差异表达?为了回答这个问题,Monocle为您提供了一个特殊的统计测试:分支表达式分析建模,或BEAM。

lung <- load_lung()
plot_cell_trajectory(lung, color_by = "Time")

# 图如下

BEAM_res <- BEAM(lung, branch_point = 1, cores = 1)
BEAM_res <- BEAM_res[order(BEAM_res$qval),]
BEAM_res <- BEAM_res[,c("gene_short_name", "pval", "qval")]

image

使用一种特殊类型的热图,您可以可视化所有明显依赖于分支的基因的变化。这张热图同时显示了两种血统的变化。它还要求您选择要检查的分支点。列是伪时间中的点,行是基因,伪时间的开始在热图的中间。当你从热图的中间读到右边的时候,你正在跟随一个伪时间谱系。当你读到左边时,另一个。这些基因是分层聚类的,因此您可以可视化具有类似的依赖于序列的基因模块.

plot_genes_branched_heatmap(lung[row.names(subset(BEAM_res,
                                                  qval < 1e-4)),],
                            branch_point = 1,
                            num_clusters = 4,
                            cores = 1,
                            use_gene_short_name = T,
                            show_rownames = T)

image
lung_genes <- row.names(subset(fData(lung),
                               gene_short_name %in% c("Ccnd2", "Sftpb", "Pdpn")))
plot_genes_branched_pseudotime(lung[lung_genes,],
                               branch_point = 1,
                               color_by = "Time",
                               ncol = 1)

image
上一篇下一篇

猜你喜欢

热点阅读