【单细胞转录组 实战】十、复现文章数据——scater、monocle Package

这里是佳奥,我们继续复现文章数据。

1 scater Package

rm(list = ls()) 
Sys.setenv(R_MAX_NUM_DLLS=999)
## 首先载入文章的数据
load(file='../input.Rdata')
counts=a
counts[1:4,1:4];dim(counts)
library(stringr) 
meta=df
head(meta) 

options(warn=-1) # turn off warning message globally
suppressMessages(library(scater))
## 创建 scater 要求的对象
sce <- SingleCellExperiment(
  assays = list(counts = as.matrix(counts)), 
  colData = meta
)
sce
exprs(sce) <- log2(  calculateCPM(sce ) + 1)
## 只有运行了下面的函数后才有各式各样的过滤指标
genes=rownames(rowData(sce))
genes[grepl('^MT-',genes)]
genes[grepl('^ERCC-',genes)]
sce <- calculateQCMetrics(sce, 
                          feature_controls = list(ERCC = grep('^ERCC',genes)))


sce <- addPerCellQC(sce,
                    subsets=list(ERCC = grep('^ERCC',genes)))

keep_feature <- rowSums(exprs(sce) > 0) > 5
table(keep_feature)
sce <- sce[keep_feature,]
tf=sce$detected
boxplot(tf)
fivenum(tf)
table(tf>2000)
sce=sce[,tf > 2000 ]
sce
head(meta)
QQ截图20220902202443.png
## 基因表达,理论上应该是跟384孔板 这个变量无关
plotExpression(sce, rownames(sce)[1:6],
               x = "plate", 
               exprs_values = "logcounts") 
QQ截图20220902202601.png
# 展示高表达量基因, 绘图有点耗时
plotHighestExprs(sce, exprs_values = "counts")
QQ截图20220902203002.png
sce <- runPCA(sce)
plotPCA(sce)
reducedDimNames(sce)
QQ截图20220902203036.png
# colnames(as.data.frame(colData(sce)))
head(colData(sce))
## PCA分布图上面添加临床信息--------------
plotReducedDim(sce, "PCA", 
                shape_by= "plate", 
                colour_by= "g")
QQ截图20220902203244.png
##包更新了,没有feature_set功能了

## 考虑ERCC 影响后继续PCA
#sce2 <- runPCA(sce, 
               feature_set = rowData(sce)$is_feature_control)
#plotPCA(sce2)
## PCA分布图上面添加临床信息--------------
#plotReducedDim(sce2, use_dimred = "PCA", 
               shape_by= "plate", 
               colour_by= "g")

## 运行 tSNE 降维算法
set.seed(1000)
sce <- runTSNE(sce, perplexity=10)
plotTSNE(sce, 
         shape_by= "plate", 
         colour_by= "g")
QQ截图20220902210133.png
## 对tSNE降维后结果进行不同的聚类
##原始代码跑不了
#colData(sce)$tSNE_kmeans <- as.character(kmeans(sce@reducedDims$TSNE,
                                                centers = 4)$clust)
##蛮试了一个
colData(sce)$tSNE_kmeans <- as.character(kmeans(sce@colData$detected,
                                                centers = 4)$clust)

head(sce@colData$detected)
hc=hclust(dist( sce@colData$detected ))
clus = cutree(hc, 4) 
colData(sce)$tSNE_hc <-  as.character(clus)
plotTSNE(sce,  colour_by = "tSNE_kmeans")
plotTSNE(sce,  colour_by = "tSNE_hc")
table(colData(sce)$tSNE_hc , colData(sce)$tSNE_kmeans)##查看两种分组情况
      1   2   3   4
  1 107  51   0   0
  2   0 188   0  30
  3   0   0 110 179
  4   0   0  28   0
QQ截图20220902210933.png
QQ截图20220902210943.png
##'runDiffusionMap'不再有用。
## 同样是一直降维方式,不同的算法
# sce <- runDiffusionMap(sce)
# plotDiffusionMap(sce,  
                 shape_by= "plate", 
                 colour_by= "g")
library(SC3) # BiocManager::install('SC3')
sce <- sc3_estimate_k(sce)
metadata(sce)$sc3$k_estimation
rowData(sce)$feature_symbol=rownames(rowData(sce))
# 耗费时间
kn=4
sc3_cluster="sc3_4_clusters"
# 非常耗时
sce <- sc3(sce, ks = kn, biology = TRUE)

sc3_plot_consensus(sce, k = kn, show_pdata = c("g",sc3_cluster))
sc3_plot_expression(sce, k = kn, show_pdata =  c("g",sc3_cluster))
sc3_plot_markers(sce, k = kn, show_pdata =  c("g",sc3_cluster))
plotPCA(sce, shape_by= "g" , colour_by =  sc3_cluster )
sc3_interactive(sce)
QQ截图20220902212049.png
QQ截图20220902212104.png
QQ截图20220902212152.png
QQ截图20220902212209.png
QQ截图20220902212321.png

2 monocle Package

参考代码:

https://cloud.tencent.com/developer/article/1606574
rm(list = ls()) 
Sys.setenv(R_MAX_NUM_DLLS=999)
## 首先载入文章的数据
load(file='../input.Rdata')

# 原始表达矩阵
counts=a
# using raw counts is the easiest way to process data through Seurat.
counts[1:4,1:4];dim(counts)
library(stringr) 

# 样本信息
meta=df
head(meta) 

# 按行/基因检查:每个基因在多少细胞中有表达量
fivenum(apply(counts,1,function(x) sum(x>0) ))
boxplot(apply(counts,1,function(x) sum(x>0) ))
# 按列/样本检查:每个细胞中存在多少表达的基因
fivenum(apply(counts,2,function(x) sum(x>0) ))
hist(apply(counts,2,function(x) sum(x>0) ))
           
# 上面检测了 counts 和 meta 两个变量,后面需要使用

有50%的基因只在低于20个细胞中有表达量,还有许多没有表达量的

QQ截图20220903102950.png
QQ截图20220903102959.png
table(apply(counts,1,function(x) sum(x>0) )==0)

FALSE  TRUE 
17429  7153 
# 存在7000多个基因在任何一个细胞中都没表达

##开始使用newCellDataSet()构建monocle对象
# ---------首先构建基因的注释信息(feature_data)-----------
            
gene_ann <- data.frame(
  gene_short_name = row.names(counts), 
  row.names = row.names(counts)
)
                  
sample_ann=meta
            
fd <- new("AnnotatedDataFrame",
          data=gene_ann)  
            
# ---------然后构建样本的注释信息(sample_data)---------
            
pd <- new("AnnotatedDataFrame",
          data=sample_ann)

# ---------开始构建对象---------
            
#sc_cds <- newCellDataSet(
  as.matrix(counts), 
  phenoData = pd,
  featureData =fd,
  expressionFamily = negbinomial.size(),
  lowerDetectionLimit=1)

counts<-as(as.matrix(counts),"sparseMatrix")
sc_cds <- newCellDataSet(
  counts, 
  phenoData = pd,
  featureData =fd,
  lowerDetectionLimit = 1,
  expressionFamily = VGAM::negbinomial.size())            
            
sc_cds

> sc_cds
CellDataSet (storageMode: environment)
assayData: 24582 features, 768 samples 
  element names: exprs 
protocolData: none
phenoData
  sampleNames: SS2_15_0048_A3 SS2_15_0048_A6 ... SS2_15_0049_P24 (768 total)
  varLabels: g plate ... Size_Factor (5 total)
  varMetadata: labelDescription
featureData
  featureNames: 0610005C13Rik 0610007P14Rik ... ERCC-00171 (24582 total)
  fvarLabels: gene_short_name
  fvarMetadata: labelDescription
experimentData: use 'experimentData(object)'
Annotation:  
##接下来质控过滤
cds=sc_cds
cds
## 起初是 24582 features, 768 samples 

#---------首先是对基因的过滤-------------

cds <- detectGenes(cds, min_expr = 0.1)
print(head(cds@featureData@data))
expressed_genes <- row.names(subset(cds@featureData@data,
                                    num_cells_expressed >= 5))
length(expressed_genes)
# 14442
# 这里需要去掉ERCC基因
# 去掉ERCC基因
is.ercc <- grepl("ERCC",expressed_genes)
length(expressed_genes[!is.ercc])
# 14362(看到去掉了80个ERCC)
cds <- cds[expressed_genes[!is.ercc],]
cds
# 过滤基因后是 14362 features, 768 samples 

#---------然后是对细胞的过滤-------------

# 如果不支持使用pData()函数,可以使用cds@phenoData@data来获得各种细胞注释信息
cell_anno <- cds@phenoData@data
> head(cell_anno)
               g plate  n_g all Size_Factor num_genes_expressed
SS2_15_0048_A3 1  0048 2624 all   0.6693919                3069
SS2_15_0048_A6 1  0048 2664 all   0.6820532                3040
SS2_15_0048_A5 2  0048 3319 all   1.0759418                3743
SS2_15_0048_A4 3  0048 4447 all   0.7294812                5014
SS2_15_0048_A1 2  0048 4725 all   1.5658507                5128
SS2_15_0048_A2 3  0048 5263 all   1.6187569                5693

# 这里简单过滤细胞
valid_cells <- row.names(cell_anno[cell_anno$num_genes_expressed>2000,] )
cds <- cds[,valid_cells]
cds 
# 最后剩下:14362 features, 693 samples
library(dplyr)
colnames(phenoData(sc_cds)@data)

## 接下来的分析,都是基于sc_cds对象

cds=sc_cds
cds
## 起初是 24582 features, 768 samples 
cds <- detectGenes(cds, min_expr = 0.1)

#print(head(fData(cds)))
#expressed_genes <- row.names(subset(fData(cds),
                                    num_cells_expressed >= 5))

print(head(cds@featureData@data))
expressed_genes <- row.names(subset(cds@featureData@data,
                                    num_cells_expressed >= 5))

length(expressed_genes)
cds <- cds[expressed_genes,]
cds
# 过滤基因后是  14442 features, 768 samples 

##然后进行归一化
library(dplyr)
colnames(phenoData(cds)@data)
## 必要的归一化 
cds <- estimateSizeFactors(cds)
cds <- estimateDispersions(cds)

##降维聚类
disp_table <- dispersionTable(cds)
unsup_clustering_genes <- subset(disp_table, 
                                 mean_expression >= 0.1)
cds <- setOrderingFilter(cds, unsup_clustering_genes$gene_id)
cds
plot_ordering_genes(cds) 
# 图中黑色的点就是被标记出来一会要进行聚类的基因
QQ截图20220903134337.png
plot_pc_variance_explained(cds, return_all = F) # norm_method='log'

QQ截图20220903134941.png

关于聚类:monocle一共有三种方法:densityPeak", "louvain", "DDRTree"

默认使用density peak的方法,但是对于大型数据(例如有5万细胞)推荐louvain方法

# ---------进行降维---------
cds <- reduceDimension(cds, max_components = 2, num_dim = 6,
                        reduction_method = 'tSNE', verbose = T)
# ---------进行聚类---------
# (这里先设置num_clusters,不一定最后真就分成5群;我们这里设置5,最后只能得到4群;如果设成4,结果就得到3群)
cds <- clusterCells(cds, num_clusters = 5) 
# Distance cutoff calculated to 1.818667 

# color使用的这些数据就在:cds$Cluster
plot_cell_clusters(cds, 1, 2, color = "Cluster")
QQ截图20220903135039.png

因为之前还做过层次聚类,所以还可以对比一下:

plot_cell_clusters(cds, 1, 2, color = "g")

看到monocle使用其他的聚类算法确实不如使用自己的结果得到的效果好


QQ截图20220903135059.png

再次对比不同分群结果的基因数量差异:

boxplot(cds@phenoData@data$num_genes_expressed~cds@phenoData@data$Cluster)
boxplot(cds@phenoData@data$num_genes_expressed~cds@phenoData@data$g)
QQ截图20220903135122.png
QQ截图20220903135143.png

去除一些影响因素

因为这几群的细胞中基因表达数量是有差别的,因此我们可以在聚类之前先去掉这部分影响,从而关注它们真正的生物学影响

## 去除检测到基因数量效应
cds <- reduceDimension(cds, max_components = 2, num_dim = 2,
                       reduction_method = 'tSNE',
                       residualModelFormulaStr = "~num_genes_expressed",
                       verbose = T)
cds <- clusterCells(cds, num_clusters = 5)
plot_cell_clusters(cds, 1, 2, color = "Cluster")
QQ截图20220903135252.png
##差异分析
start=Sys.time()
diff_test_res <- differentialGeneTest(cds,
                                      fullModelFormulaStr = "~Cluster")
end=Sys.time()
end-start
# Time difference of 4.724045 mins

##挑差异基因
# 选择FDR-adjusted p-value(也就是q值) < 10%的基因作为差异基因
sig_genes <- subset(diff_test_res, qval < 0.1)
dim(sig_genes)
> head(sig_genes[,c("gene_short_name", "pval", "qval")] )
              gene_short_name         pval         qval
0610007P14Rik   0610007P14Rik 3.377244e-03 1.277429e-02
0610010F05Rik   0610010F05Rik 1.243943e-02 3.924761e-02
0610011F06Rik   0610011F06Rik 2.338530e-03 9.285587e-03
1110004E09Rik   1110004E09Rik 2.487600e-02 7.003903e-02
1110020A21Rik   1110020A21Rik 2.318327e-02 6.618129e-02
1110059E24Rik   1110059E24Rik 5.193533e-09 4.856089e-08

##作图
cg=as.character(head(sig_genes$gene_short_name))
# 还能上色
plot_genes_jitter(cds[cg,],
                  grouping = "Cluster",
                  color_by = "Cluster",
                  nrow= 3,
                  ncol = NULL )
QQ截图20220903141430.png
##推断发育轨迹

##step1: 选合适基因
ordering_genes <- row.names (subset(diff_test_res, qval < 0.01))
cds <- setOrderingFilter(cds, ordering_genes)
plot_ordering_genes(cds)
QQ截图20220903141500.png
##step2: 降维
# 默认使用DDRTree的方法 
cds <- reduceDimension(cds, max_components = 2,
                            method = 'DDRTree')

##step3: 细胞排序
cds <- orderCells(cds)
head(pData(cds))

##最后可视化
plot_cell_trajectory(cds, color_by = "Cluster")  
QQ截图20220903141709.png

写在后面

orderCells会出现报错:
Error in if (class(projection) != "matrix") projection <- as.matrix(projection) : 
  the condition has length > 1
In addition: Warning message:
In graph.dfs(dp_mst, root = root_cell, neimode = "all", unreachable = FALSE,  :
  Argument `neimode' is deprecated; use `mode' instead

GitHub上解决办法是修改该包的代码:
https://github.com/cole-trapnell-lab/monocle-release/issues/434

from
if(class(projection) != 'matrix')
projection <- as.matrix(projection)

to
projection <- as.matrix(projection)

尚不确定是否有用。

本流程花了很多时间把所有代码都调试到可以顺利运行最新版本的package。

希望能有所帮助。

下一篇我们看一下作者的原始代码。

我们下一篇再见!

©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容