实验记录5(.h5文件解析为.tsv和.mtx格式)
这篇主要针对Seurat包装不上hdf5r包的bug而无法使用Read10X_h5这个函数的读者。
在使用Seurat包读取10Xgenomics测序数据时,我发现github上有很多人面临着与我同样的问题:hdf5r包无法安装,因此在调用Read10X_h5函数时会出现以下报错信息:
Error in Read10X_h5("/bone_marrow/ica_bone_marrow_h5.h5") :
Please install the 'hdf5r' package
在用包的时候,若数据格式不是.h5则用不到这个函数。但是偏巧,当你需要用Seurat分析这个数据,而数据格式正好是.h5怎么办呢?
因此我们需要先将.h5解析为Read10X这个函数能够读取的格式。
目标:将.h5文件转化为10X outs中的barcodes.tsv, genes.tsv, matrix.mtx三个文件
文件 | 格式 |
---|---|
barcodes.tsv | 1列,为barcode名 |
genes.tsv | 2列,第1列为ENS编号,第2列为基因名 |
matrix.mtx | 3列,第1列为基因编号,第2列为细胞编号,第3列为对应的reads数 |
- 这是大文件的文本处理,要注意内存和磁盘空间的控制
- 主要是用R的hdf5r包处理,Seurat的依赖包
- tsv文件与csv文件类似,不同点在于分隔符是\t而不是逗号
- mtx格式是一个矩阵
R version 3.4.4 (2018-03-15) -- "Someone to Lean On"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin15.6.0 (64-bit)
能够成功安装hdf5r包。
Step2:查看数据
setwd("/data/immune_census/bone_marrow/data")
library(hdf5r)
bm <- H5File$new("./ica_bone_marrow_h5.h5", mode = "r")
bm
Class: H5File
Filename: /immune_census/bone_marrow/data/ica_bone_marrow_h5.h5
Access type: H5F_ACC_RDONLY
Attributes: TITLE, CLASS, VERSION, FILTERS, PYTABLES_FORMAT_VERSION
Listing:
nameobj_type dataset.dims dataset.type_class
GRCh38 H5I_GROUP
bm$ls()
namelink.typeobj_type num_attrs group.nlinks group.mounted dataset.rank
1 GRCh38 H5L_TYPE_HARD H5I_GROUP470NA
dataset.dims dataset.maxdims dataset.type_class dataset.space_class committed_type
1
将GRCh38导出来查看后发现共7组信息。
GRCh38 <- bm[["GRCh38"]]
GRCh38$ls()
namelink.typeobj_type num_attrs group.nlinks group.mounted dataset.rank dataset.dims
1barcodes H5L_TYPE_HARD H5I_DATASET3NANA1378000
2data H5L_TYPE_HARD H5I_DATASET3NANA1303795547
3 gene_names H5L_TYPE_HARD H5I_DATASET3NANA133694
4genes H5L_TYPE_HARD H5I_DATASET3NANA133694
5indices H5L_TYPE_HARD H5I_DATASET3NANA1303795547
6indptr H5L_TYPE_HARD H5I_DATASET3NANA1378001
7shape H5L_TYPE_HARD H5I_DATASET3NANA12
dataset.maxdims dataset.type_class dataset.space_class committed_type
1378000H5T_STRINGH5S_SIMPLE
2303795547H5T_INTEGERH5S_SIMPLE
333694H5T_STRINGH5S_SIMPLE
433694H5T_STRINGH5S_SIMPLE
5303795547H5T_INTEGERH5S_SIMPLE
6378001H5T_INTEGERH5S_SIMPLE
716384H5T_INTEGERH5S_SIMPLE
将所有的信息导出来
### 1细胞barcode:
barcodes <- GRCh38[["barcodes"]]
barcodes[1:5]
[1] "MantonBM1_HiSeq_1-AAACCTGAGCAGGTCA-1" "MantonBM1_HiSeq_1-AAACCTGCACACTGCG-1"
[3] "MantonBM1_HiSeq_1-AAACCTGCACCGGAAA-1" "MantonBM1_HiSeq_1-AAACCTGCATAGACTC-1"
[5] "MantonBM1_HiSeq_1-AAACCTGCATCGATGT-1"### 2基因ENS编号
genes <- GRCh38[["genes"]]
genes[1:10]
[1] "ENSG00000243485" "ENSG00000237613" "ENSG00000186092" "ENSG00000238009" "ENSG00000239945"
[6] "ENSG00000239906" "ENSG00000241599" "ENSG00000279928" "ENSG00000279457" "ENSG00000228463"### 3基因名
gene_names <- GRCh38[["gene_names"]]
gene_names[1:10]
[1] "RP11-34P13.3""FAM138A""OR4F5""RP11-34P13.7""RP11-34P13.8"
[6] "RP11-34P13.14" "RP11-34P13.9""FO538757.3""FO538757.2""AP006222.2"### 4 基因索引号
indices <- GRCh38[["indices"]]
indices[1:10]
[1] 33664 33662 33661 33659 33658 33657 33655 33654 33653 33652### 5 reads数:
data <- GRCh38[["data"]]
data[1:10]
[1]55 14 12 359 15 26 175### 6
indptr <- GRCh38[["indptr"]]
indptr[1:10]
[1]0785 1466 2010 2942 4605 5569 5678 6374 7096### 7 矩阵shape(33694个基因,378000个细胞)
shape <- GRCh38[["shape"]]
shape[1:2]
[1]33694 378000
Step3:转化为R可操作的dataframe
现在仍然是h5的compounds数据类型,要把它转化为R可操作的dataframe
### 读取数据###数据个数(用length查看)
barcodes <- bm$open("/GRCh38/barcodes")#378000
genes <- bm$open("/GRCh38/genes")#33694
gene_names <- bm$open("/GRCh38/gene_names")#33694
indices <- bm$open("/GRCh38/indices")#303795547
data <- bm$open("/GRCh38/data")#303795547
indptr <- bm$open("/GRCh38/indptr")#378001
shape <- bm$open("/GRCh38/shape")#[1]33694 378000####### 文件1 barcodes.tsv 的生成 #######
barcodes <- barcodes[]
write.csv(barcodes, file = "barcodes.csv") #再手动重命名为.tsv格式####### 文件2 genes.tsv 的生成 #######
genes <- genes[]
gene_names <- gene_names[]
df <- data.frame(gene_names, row.names = c(genes))
write.csv(df, file = "genes.csv") #再手动重命名为.tsv格式
文件3 matrix.mtx 比较特殊,列名是基因的索引号,表示该基因在该细胞中的reads数。第二列没有现成的变量可以一次性填进去,需要进行一些转化和运算:
- 第一列是indices,作为row.names;
- 第三列是data,也就是reads数;
- 第二列是细胞的编号,如1,1,1,2,2,2,2,2,2,3,4,……,33694。这些数字表示即第1个细胞至第33694个细胞。如第一行为33688 1 2 则表示33688号基因在细胞1中的reads数为2。
indices <- indices[]
indptr <- indptr[]
data <- data[]####### 文件3 matrix.csv 的生成 ####### # 创建两个相差一个元素的数列,相减得到细胞数量列表
indptr1 <- indptr[2:length(indptr)]
indptr2 <- indptr[1:length(indptr)-1]
cell_numb <- indptr1 - indptr2column2_of_file3 <- rep(c(1:length(indptr1)),c(cell_numb)) # rep函数万岁df <- data.frame(indices, column2_of_file3, data)
save(df, file = "df_marrow_bone.RData") # 10分钟后运行结束,文件大小672Mb
这里仅仅只是把变量保存,由于磁盘限制没有写入csv中。
这里是利用另一个数据的处理过程,和之前的过程一样,不展开说明:
setwd("/Users/shinianyike/Desktop/zll/data/immune_census/cord_blood/data")
library(hdf5r)
bm <- H5File$new("./ica_cord_blood_h5.h5", mode = "r")
GRCh38 <- bm[["GRCh38"]]### 读取数据###数据个数
barcodes <- bm$open("/GRCh38/barcodes")#384000
genes <- bm$open("/GRCh38/genes")#33694
gene_names <- bm$open("/GRCh38/gene_names")#33694
indices <- bm$open("/GRCh38/indices")#260473471
data <- bm$open("/GRCh38/data")#260473471
indptr <- bm$open("/GRCh38/indptr")#384001
shape <- bm$open("/GRCh38/shape")#[1]33694 384000#### 将.h5格式转化为R可操作的list
#### 注意data <- GRCh38[["data"]] 这种读取方式仍然得到的是.h5的格式
barcodes <- barcodes[]
genes <- genes[]
gene_names <- gene_names[]
indices <- indices[]
indptr <- indptr[]
data <- data[]####### 文件1 barcodes.tsv 的生成 #######
write.csv(barcodes, file = "barcodes.csv", row.names = FALSE, col.names = FALSE) #再手动将文件重命名为.tsv结尾####### 文件2 genes.tsv 的生成 #######
df <- data.frame(gene_names, row.names = c(genes))
write.csv(df, file = "genes.csv", row.names = FALSE, col.names = FALSE) #再手动将文件重命名为.tsv结尾####### 文件3 matrix.tsv 的生成 ####### # 创建两个相差一个元素的数列,相减得到细胞数量列表
indptr1 <- indptr[2:length(indptr)]
indptr2 <- indptr[1:length(indptr)-1]
cell_numb <- indptr1 - indptr2column2_of_file3 <- rep(c(1:length(indptr1)),c(cell_numb)) # rep函数万岁df <- data.frame(indices, column2_of_file3, data)
save(df, file = "df_cord_blood.RData")
Step4:将数据转换为mtx格式
上述的文件3仅仅只是生成了一个csv文件,然而与输入的mtx格式是不同的。
mtx文件描述: 引自:http://people.sc.fsu.edu/~jburkardt/data/mm/mm.html
A file in the Matrix Market format comprises four parts:
- Header line: contains an identifier, and four text fields;
- Comment lines: allow a user to store information and comments;
- Size line: specifies the number of rows and columns, and the number of nonzero elements;
- Data lines: specify the location of the matrix entries (implicitly or explicitly) and their values.
The header line has the form:
%%MatrixMarket object format field symmetry
The header line must be the first line of the file, and the header line must begin with the string %%MatrixMarket. The four fields that follow that string are例子:人外周血10Xgenomics数据比对方法所得RNA-seq数据的mtx文件(下图)以%%MatrixMarket字符串开头,object为matrix,format为coordinate,field为real,symmetry为general。分隔符为空格。
- object is usually matrix, and that is the case we will consider here. Another legal value is vector, whose format is similar, but with some obvious simplifications.
- format is either coordinate or array;
- field is either real, double, complex, integer or pattern.
- symmetry is either general (legal for real, complex, integer or pattern fields), symmetric (real, complex, integer or pattern), skew-symmetric (real, complex or integer), or hermitian (complex only).
第一行为%%MatrixMarket matrix coordinate real general
第二行为%
第三行为基因总数,细胞总数,以及reads总数(第三列的和)
第三行的前两个数字已经有了,只需要计算一下reads总数。
文章图片
pbmc.mtx
脾脏数据的第一行则为
%%MatrixMarket matrix coordinate integer general
载入R变量
> setwd("/Users/shinianyike/Desktop/zll/data/immune_census/bone_marrow/")
> load("./data/10X/df_marrow_bone.RData")
> head(df)
indices column2_of_file3 data
13366415
23366215
333661114
433659112
533658135
63365719# reads总数:
sum(df$data)
[1] 1179704196
# 所以mtx文件的第三行为33694 378000 1179704196
总的来说,要做的事情是在df数据框前添加三行:
第一行:%%MatrixMarket matrix coordinate real general
第二行:%
第三行:33694 378000 303795547
由于第一行和第二行是一行字符,并不像数据框那样行列元素个数能一一对应,因此要考虑其他的文本处理方法。
另外,R在第一行添加元素的操作比较繁杂,尤其是大文件。需要创建新空白文件,写入第一行,再把剩下的一行一行写入,缺点在于慢。若一次性写入又会产生内存不够的问题。
但是,利用linux的sed命令就可以轻松解决这个问题。
正式开始操作:
将R变量传上服务器,载入R变量,写入csv文件:
load("./df_marrow_bone.RData")
head(df)
indices column2_of_file3 data
13366415
23366215
333661114
433659112
533658135
63365719write.csv(df, file = "matrix.csv", row.names = FALSE, col.names = FALSE)
# 用时15min左右Warning message:
In write.csv(df, file = "matrix.csv", row.names = FALSE, col.names = FALSE) :
quit()
### 查看文件
head matrix.csv
"indices","column2_of_file3","data"
33664,1,5
33662,1,5
33661,1,14
33659,1,12
33658,1,35
33657,1,9
33655,1,15
33654,1,26
33653,1,17### 处理文件格式
sed -i 's/,/ /g' matrix.csv ###将分隔符逗号改为空格
sed -i '1d' matrix.csv###将第一行删除
sed -i '1i %%MatrixMarket matrix coordinate real general\
%\
33694 378000 303795547' matrix.csv ###添加前面三行内容### 检查文件
head matrix.csv
%%MatrixMarket matrix coordinate real general
%
33694 378000 303795547
33664 1 5
33662 1 5
33661 1 14
33659 1 12
33658 1 35
33657 1 9
33655 1 15### 更改后缀名
mv ./matrix.csv ./matrix.mtxwc -l matrix.mtx##查看行数
303795550 matrix.mtx ##行数正确
Step6:genes.tsv和barcodes.tsv的处理
sed -i 's/ENSG/\nENSG/g' genes.tsv ##添加空行
sed -i '$a \' genes.tsv
sed -i '1d' genes.tsv
wc -l genes.tsv
33694 genes.tsv
barcodes同理
参考: hdf5r包的介绍:https://cran.r-project.org/web/packages/hdf5r/vignettes/hdf5r.html#conversion-of-datatypes
mtx文件描述:http://people.sc.fsu.edu/~jburkardt/data/mm/mm.html
https://github.com/cran/Matrix/blob/master/R/HBMM.R
后续读取数据出现报错
bm_data <- Read10X(data.dir ='./10X/')Error: readMM(): rowvalues 'i' are not in 1:nr
#6:12
【实验记录5(.h5文件解析为.tsv和.mtx格式)】这里说明第一列的数据中不在1:nrow的范围内,检查后发现有3行0的存在(这是什么坑爹数据啊。。。。),只好手动修改。
2月28日
library(Matrix)
head(df)
indices column2_of_file3 data
[1,]3366415
[2,]3366215
[3,]33661114
[4,]33659112
[5,]33658135
[6,]3365719which(df[,1]=="0")
[1]2446541 121241013 212008491
# 这里就是报错来源。
df[2446540,]
#indices column2_of_file3data
#12830141
df[121241012,]
#indices column2_of_file3data
#121557051
df[212008490,]
#indices column2_of_file3data
#722592111
df[2446541,1]=45
df[121241013,1]=8
df[212008491,1]=20sparseM <- sparseMatrix(i=df[,1],j=df[,2],x=df[,3])
writeMM(obj = sparseM, file="matrix.mtx")
推荐阅读
- 20170612时间和注意力开销记录
- 【学生作品】温暖的记忆
- 【剽悍读书营成长记录】2018年我收获了什么|【剽悍读书营成长记录】2018年我收获了什么 3357-小松
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 课后分享记录
- 感赏15+投射
- 实验室女王从0到1亿的1001天创业日记第62天
- 我在管理实验班中的一些经验教训
- “寓教于乐,丰知润德”——沭东实验学校临沂龙园研学旅行企划书
- Day5+5组+小鹿#写手账,就是记录你一生的帐