单细胞数据的导入与质控 - Seurat

######################################

  • 题目:单细胞数据的导入与质控 - Seurat
  • 语言:R
  • Author: YQ
    ######################################

step0.设置工作环境

  • 方法一:新建repository,在该repo内写R.scripts

  • 方法二:setwd()


setwd('/Users/apple/Desktop/Rsave/')
getwd()

创建以下目录

single_cell_rnaseq/
├── data
├── results
└── figures

step1.导入数据,创建计数矩阵

目前我碰到的有这几种情况;

- 情况一:三个文件

三个文件指的是“barcodes.tsv","features.tsv","matrix.mtx";
这个情况就比较好处理了,barcodes.tsv就是cell id,features.tsv就是gene id,matrix.mtx就是计数counts矩阵

##示例 https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE136916

# 设置默认路径
matrix_dir = '/Users/apple/Desktop/Rwork/Glasslung/' 

# 按路径读取三个文件
barcode.path<-paste0(matrix_dir,"barcodes.tsv")
genes.path<-paste0(matrix_dir,"features.tsv")
matrix.path<-paste0(matrix_dir,"matrix.mtx")

# readMM读取数据的values,columns,index
zebrafish.data <- readMM(file = matrix.path) ##mac上不能读压缩文件
gene.names = read.delim(genes.path,header = FALSE, stringsAsFactors = FALSE)
barcode.names = read.delim(barcode.path,header = FALSE,stringsAsFactors = FALSE)
colnames(zebrafish.data) = barcode.names$V1
rownames(zebrafish.data) = gene.names$V2 ##把示例中的V1改成V2

# check矩阵
zebrafish.data[1:6, 1:6] ##check矩阵
dim(zebrafish.data) ##check矩阵

- 情况二:直接给了计数矩阵的csv

单个csv矩阵读入

# 读取csv格式的矩阵
data1 <- read.csv("/Users/quyue/Desktop/gene_bc_matrices.csv", header = T, row.names = 1)

# csv矩阵转换成数据框
datan = data.frame(data1)

# 数据框转换成稀疏矩阵matrix
dataan <- as(as.matrix(datan), "dgCMatrix")

多个csv矩阵读入


# 设置默认路径
matrix_dir = '/Users/quyue/Desktop/bioinfo/bonemarrowniche/0526data/'  # 为了避免重复输入默认路径,赋值给matrix_dir

# 读取多个csv
data1 <- read.csv(paste0(matrix_dir, "GSM3714747_chow1_filtered_gene_bc_matrices.csv"), header = T,row.names= 1)
data2 <- read.csv(paste0(matrix_dir, "GSM3714748_chow2_filtered_gene_bc_matrices.csv"), header = T,row.names= 1)
data3 <- read.csv(paste0(matrix_dir, "GSM3714749_chow3_filtered_gene_bc_matrices.csv"), header = T,row.names= 1)

# csv合并成数据框
datan = data.frame(data1,data2,data3)

# 数据框转换成稀疏矩阵matrix
dataan <- as(as.matrix(datan), "dgCMatrix")


- 情况三:直接给了计数矩阵的txt

单个txt矩阵读入

# 读取txt格式的矩阵
data1 <- read.table("/Users/quyue/Desktop/GSM2915579_5FU-cntrl-col23.txt", header = T, row.names = 1)

# txt矩阵转换成数据框
datan = data.frame(data1)

# 数据框装转换成稀疏矩阵matrix
dataan <- as(as.matrix(datan),"dgCMatrix")

多个txt矩阵读入


# 设置默认路径
matrix_dir = "/Users/quyue/Desktop/"

# 读取多个txt格式的矩阵
data1 = read.table(paste0(matrix_dir,"GSM2915579_5FU-cntrl-col23-1.txt"), header = T, row.names = 1)

data2 = read.table(paste0(matrix_dir,"GSM2915579_5FU-cntrl-col23-2.txt"), header = T, row.names = 1)

data3 = read.table(paste0(matrix_dir,"GSM2915579_5FU-cntrl-col23-3.txt"), header = T, row.names = 1)

dataa = cbind(data1, data2, data3) #行数不同,会生成NaN值

# txt矩阵转换成数据框
datan = data.frame(dataa)

# 数据框转换成稀疏矩阵matrix
dataan <- as(as.matrix(datan),"dgCMatrix") # 此步骤是否必要有待验证

- 情况四:xslx文件

其实就是用R读取excel文件,把xslx转化成csv再读取

# 加载openxslx这个R包
library('openxslx')

# 读入xslx格式矩阵
a <- read.xslx("test.xslx",sheet = 1) # 文件名+sheet序号

# 把xslx格式矩阵转换成csv格式矩阵
# 获取excel中工作簿的名称
sheetnames<-getSheetNames('test.xlsx')

#把每个工作薄的数据按照'工作薄名称.csv'的名称存储
for(iin(1:length(sheetnames))){

write.table(read.xlsx('/Users/quyue/Desktop/test.xlsx',sheet=i),paste(sheetnames[i],'.csv',sep=''),row.names=F,sep=',')

} # 有待验证,不是我自己写的

# 读取csv格式矩阵
data1 <- read.csv("/Users/quyue/Desktop/test.csv", header = T, row.names = 1)

# 把csv格式矩阵转换成数据框
datan = data.frame(data1)

# 把数据框转换成稀疏矩阵matrix
dataan <- as(as.matrix(datan), "dgCMatrix")

- 情况五:直接给了已经构建好seurat对象的R.data

# 直接load R.data
load(file = "/Users/quyue/Desktop/bioinfo/bonemarrowniche/RNAMagnetDataBundle/NicheData10x.rda")
    > Loading required package: Seurat

# load完以后,看到底是什么数据类型,并查看数据
NicheData10x
    > An object of class Seurat # 已经是seurat对象了
    16701 features across 7497 samples within 1 assay 
    Active assay: RNA (16701 features, 2872 variable features)
     2 dimensional reductions calculated: pca, tsne

View(NicheData10x) # 显示seurat的具体参数

step2.构建矩阵为seurat对象

找到一个解释Seurat中所有函数的网站,比R自带的要清楚很多 rdrr

工作流程
  • generation of the count matrix 生成计数矩阵
    格式化读取、分离样本、映射(mapping)、定量(quantification);

  • quality control of the raw counts 原始矩阵质量控制
    过滤掉质量差的细胞

  • clustering of filtering counts 过滤后计数的聚类
    将转录活动相似的细胞归为一类(细胞类型=不同的聚类)

  • Marker identification 标记识别
    识别每个细胞群的基因标记(marker)

  • Optional downstream steps 其他可选的下游步骤

2.1 稀疏矩阵到seurat对象

2.1.1 使用ReadMM()或者Read10x()读取单个样本数据
  • 函数用法说明:

1.readMM():

input:"xx.mtx"

备注:readMM is the function of Matrix packages, it changes the standard matrix into sparse matrix.Of note,features.tsv and barcodes.tsv should be library first, and then combine sparse matrix、features.tsv and barcodes.tsv form a counts matrix with cell id and gene id.(详见step1情况一)

2.read10X():

input:"raw_feature_bc_matrix"(files from CellRanger output)

备注:read10X id the function of Seurat,its input from CellRanger output(10X genomics data的专用软件Cell Ranger的output会有一个out目录,"raw_feature_bc_matrix"在该目录中)

library(Seurat)

# 按1中方法完成数据读入到稀疏矩阵输出的过程
# sparse matrix稀疏矩阵
ctrl_counts <- Read10x(data.dir = "data/ctrl_raw_feature_bc_matrix")


# 将稀疏矩阵转换成一个Seurat
ctrl <- CreateSeuratObject(counts = ctrl_counts,
                          min.features = 100)

# 查看Seurat对象的元数据
head([email protected])

## 备注:元数据 meta.data代表什么?
orig.ident # 通常包含所知的样品名字,默认为“SeuratProject”
nCount_RNA # 每个细胞的UMI数目
nFeature_RNA # 每个细胞所检测到的基因数目

2.1.2 使用for循环读入多个样本数据
  • R中for 循环的语法结构
for (variable in input){
    command1
    command2
    command3
}

  • R中for循环实现读入多个样本数据
## 目的:for loop iterate 两个样本的文件
## 思路:执行三个命令 (1) 使用Read10x()读取计数数据;(2)使用CreateSeuratObject()从读取的数据中创建Seurat对象;(3)根据样本名将Seurat对象赋值给一个新的变量(好处是不会覆盖上一次迭代中创建的Seurat对象)

mtx_dir = "/Users/quyue/Desktop/"

for (files in c("ctrl_raw_feature_bc_matrix","stim_raw_feature_bc_matrix")){
    seurat_data <- Read10X(data.dir = paste0(mtx_dir, file)) # (1)
    seurat_obj <- CreateSeuratObject(counts = seurat_data,
                                    min.features = 100,
                                    project = file) #(2)
    assign(file, seurat_obj) #(3)
}

2.2 查看seurat对象元数据&merge

再完成2.1已经创建好了Seurat对象以后,快速查看元数据以了解其大概;

## 查看新Seurat对象的元数据
head([email protected])
head([email protected])

接着,需要把多个seurat对象合并成一个,这样比较方便我们同时为每个样品进行质控,且方便我们更容易地比较所有样本的数据质量,用merge()函数执行该操作;

## 创建一个合并的Seurat对象
## 用add.cell.id参数将样品特异的前缀添加到每个细胞ID,用以区分不同样本中的同个细胞ID
merged_seurat <- merge(x = ctrl_raw_feature_bc_matrix,
                       y = stim_raw_feature_bc_matrix,
                       add.cell.id = c("ctrl","stim"))

## 查看合并对象是否有对应的样本前缀
head([email protected])
tail([email protected])

step3. 进行质控流程(QC and pre-processing)

3.1 熟悉质控指标

通常根据以下四个指标筛选:

# 每个细胞的read counts数目(UMI指的是molecular ID)
nCount_RNA  # (> 1000)

# 每个细胞所检测到的基因数目
nFeature_RNA # (> 1000)

# 线粒体基因比例 mitoRatio
mitoRatio  # (< 5%)

# 单位UMI(read count=molecular id)检测到的gene数目的比例(这个数据让我们知道数据的复杂性)
GenesPerUMI

3.2 标准的质控分析流程 - Standard pre-processing workflow

3.2.1 计算质控指标
  • 需要计算的主要是mitoRatio和GenesPerUMI(因为nCount_RNA和nFeature_RNA在meta.data中)

1.计算mitoRatio

主要是利用的Seurat的PercentageFeatureSet()功能,这个函数将使用一个模式(pattern)搜索基因标识符,对于每一列(细胞),它将选取特征基因的计数之和,除以所有基因的计数之和

## count mitoRatio with PercentageFeatureSet() 并添加 mito Ratio这一项到 meta.data当中

# 方法一
## The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")

# 方法二
pbmc$mitoRatio <- PercentageFeatureSet(object = pbmc, pattern = "^MT-")
pbmc$mitoRatio <- [email protected]$mitoRatio / 100

2.计算log10GenesPerUMI(option)

GenesPerUMI = nFeature_RNA / nCount_RNA
这个指标代表的意思是 “单位read counts的gene数目的比例” 反映的是数据的复杂度;常用于评估ctrl和stim基因的整体复杂性

## count log10GenesPerUMI and add it to seurat object metadata
pbmc$log10GenesPerUMI <- log10(pbmc$nFeature_RNA)/log10(pbmc$nCount_RNA)

3.2.2 可视化质控指标
## 一般可视化以下三个参数即可:"nFeature_RNA", "nCount_RNA", "percent.mt"
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3, pt.size=0.05)

## 可视化log10GenesPerUMI(option)
# 通过可视化每一个UMI检测到的基因数来可视化基因表达的整体复杂性
metadata %>%
    ggplot(aes(x=log10GenesPerUMI, color = sample, fill=sample)) +
    geom_density(alpha = 0.2) +
    theme_classic() +
    geom_vline(xintercept = 0.8)

3.2.3 筛选 Filtering(option - 因为一般给的是经过筛选过后的gene mtx)
3.2.3.1 细胞水平的筛选(Cell-level filtering)
  • 参考阈值
nUMI > 500
nGene > 250
log10GenesPerUMI > 0.8
mitoRatio < 0.2

细胞水平的过滤, 主要是用subset()函数过滤

# 使用选择的阈值筛掉低质量读写 - 这些将会随实验而改变
filtered_pbmc <- subset(x = pbmc, subset= (nUMI >= 500) & 
                                          (nGene >= 250) & 
                                          (log10GenesPerUMI > 0.80) & 
                                          (mitoRatio < 0.20))   

3.2.3.2 基因水平的筛选(Gene-level filtering)

在我们的数据中,会有许多基因的计数为零。这些基因会显著降低一个细胞的平均表达量,因此我们将从数据中删除它们。

主要删除两类基因,
(1)删除所有细胞中零表达的基因;

(2)如果一个基因只在少数几个细胞中表达,那么它的意义并不是特别大,因为它仍然会把没有表达它的其他所有细胞的平均表达量降下来。对于我们的数据,我们选择只保留在10个或更多细胞中表达的基因。

# 提取计数
counts <- GetAssayData(object = filtered_pbmc, slot = "counts")

# 根据在每个细胞的计数是否大于0为每个基因输出一个逻辑向量
nonzero <- counts > 0

# 将所有TRUE值相加,如果每个基因的TRUE值超过10个,则返回TRUE。
keep_genes <- Matrix::rowSums(nonzero) >= 10

# 仅保留那些在10个以上细胞中表达的基因
filtered_counts <- counts[keep_genes, ]

# 重新赋值给经过过滤的Seurat对象
filtered_pbmc <- CreateSeuratObject(filtered_counts, meta.data = [email protected])

3.2.4 重新评估质量指标 (Re-assess QC metrics)

在进行过滤后,建议回过头来再看看指标,确保你的数据符合你的预期,对下游分析有好处。

3.2.5 保存筛选过的细胞 (Saving filtered cells)

我们将保存筛选后的细胞对象用于聚类 (clustering) 和标记识别 (marker identification),将过滤以后的Seurat数据创建为.RData对象

# 创建.RData对象以方便在任何时候导入
save(filtered_pbmc, file="data/pbmc_seurat_filtered.RData")

你可能感兴趣的:(单细胞数据的导入与质控 - Seurat)