R编程反面教材:1646992行的gff文件处理了6小时

耐心看下背景

前段时间帮客户做转录组上游分析定量,要求定量到基因水平,遇到一个非模式真核生物。它的gff注释文件示例如下:

Chr4	.	gene	215480503	215499887	.	-	.	ID=evm.TU.ctg388.13;Name=EVM%20prediction%20ctg388.13
Chr4	.	mRNA	215480503	215499887	.	-	.	ID=evm.model.ctg388.13;Parent=evm.TU.ctg388.13;Name=EVM%20prediction%20ctg388.13
Chr4	.	five_prime_UTR	215499673	215499887	.	-	.	ID=evm.model.ctg388.13.utr5p1;Parent=evm.model.ctg388.13
Chr4	.	exon	215499406	215499887	.	-	.	ID=evm.model.ctg388.13.exon1;Parent=evm.model.ctg388.13
Chr4	.	CDS	215499406	215499672	.	-	0	ID=cds.evm.model.ctg388.13;Parent=evm.model.ctg388.13
Chr4	.	exon	215480503	215481095	.	-	.	ID=evm.model.ctg388.13.exon2;Parent=evm.model.ctg388.13
Chr4	.	CDS	215480751	215481095	.	-	0	ID=cds.evm.model.ctg388.13;Parent=evm.model.ctg388.13
Chr4	.	three_prime_UTR	215480503	215480750	.	-	.	ID=evm.model.ctg388.13.utr3p1;Parent=evm.model.ctg388.13

从上面这个基因的注释来看,feature为exon 的行中attributes注释部分,并没有给出基因IDevm.TU.ctg388.13,而是只给到了转录本IDevm.model.ctg388.13 。由于整个注释文件中存在特殊情况,并不能直接将转录本ID中的model部分替换为TU。因此,我们需要做一些工作使我们能定量到基因水平。

目前的大方向有两个:

  1. 提取基因ID与转录本ID对应关系。一般非模式真核生物的注释,很少有基因能注释出可变剪切。也就是一个基因只注释出一个转录本,我们可以从gtf文件中提取基因ID和转录本ID对应关系。提取的代码可以参考我之前的代码

探索GRCh38的转录组本、基因和SYMBOL等的对应关系

  1. 给到对应的five_prime_UTRexonCDSthree_prime_UTR注释部分添加基因ID。

我当时用的就是第二种方法。一开始是用R写的代码,写代码10分钟,运行6小时。后来嫌弃太慢,花40分钟写了个perl版本代码,然后4秒钟解决了。。。

今天带大家看下我写的反面教材R代码(改进思路见小结部分,有兴趣的可以找一个模式生物验证下自己的思路和代码是否正确。)。

R反面教材代码

library(vroom)
library(stringr)

gff <- vroom_lines(file = "./test.gff.gz")

new_gff <- vector()
for (i in 1:length(gff)) {
  message(i)
  gff_line <- gff[i]
  gff_tmp <- str_split(gff_line, pattern = "\t")[[1]]
  feature <- c("mRNA","exon","CDS")
 if(length(gff_tmp) == 9){
  if(gff_tmp[3] == "gene"){gene <- gff_tmp[9] %>% str_extract(pattern = "ID=.*?;") %>% str_remove("ID=") %>% str_remove(";")}
  if(gff_tmp[3] %in% feature) gff_line <- paste0(gff_line,";gene_id=",gene)
 }
  new_gff <- c(new_gff, gff_line)
}

vroom_write_lines(new_gff, file = "new_test.gff.gz", eol = "\n")
save.image(file = "new_gff.Rdata")

原注释文件有1646992行,这里是尝试用R按行处理的数据,还使用了for循环。我是知道for循环慢,但是也没有想到for循环这么慢啊!单纯的处理gff就花费6小时。

小结

R按行处理+for循环固然是慢,花了6小时,但是同样的处理思路移植到perl语言中,只花了4秒!根据编程语言特点写代码,很重要!

当然了,对于科研上的数据处理,这种处理时间要求一般不是很严格的,能解决问题即可。

既然说了“根据语言特点写代码,很重要!”,对于R语言来说,向量化处理数据就是其一个重要特点。R代码改进方法可以是如下思路:

  • 将gff文件读入为data.frame。
  • 对于featture列为mRNA的部分行中提取基因ID。根据提取的基因ID和feature列进行插补,生成一个基因ID向量,将其paste到第9列的注释行部分。
  • 循环部分用apply家族或者purrr包。
  • 导出新的gff文件。

这也只是我的思路而已,并不是唯一的。大家可以找一个模式生物验证下自己的思路是否正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值