用 R 提取代表性转录本

前言:

上上篇文章讲了从 GTF 文件的提取代表性的转录本 gtf 信息:提取代表转录本之 gencode,如果想获得代表性转录本序列的话,可以使用 gffread 软件取获得 cDNA 序列。

也可以直接下载转录组序列,但是里面包含了同一个基因的多个转录本,我们可以筛选出代表性的转录本。筛选原则与上面的文章有一些不同,我们先看下面这张图:

用 R 提取代表性转录本 - 图1

基于 gtf 注释文件挑选的最长转录本的长度是包含了内含子的长度,这样选择不能真实反应转录本的实际长度,在选择 CDS 最长的前提下,再选择转录本外显子的总长度最长更加合理。

提取实操:

1、数据准备

首先去 gencode 数据库下载蛋白编码基因的转录组序列文件:

  1. # 下载
  2. $ wget http://ftp.ebi.ac.uk/pub/databases/gencode/Gencode_human/release_38/gencode.v38.pc_transcripts.fa.gz
  3. # 查看有多少个转录本序列
  4. $ zless gencode.v38.pc_transcripts.fa.gz | grep '>' | wc -l
  5. 106143
  6. # 简单查看前面几行
  7. $ zless gencode.v38.pc_transcripts.fa.gz | head
  8. >ENST00000641515.2|ENSG00000186092.7|OTTHUMG00000001094.4|OTTHUMT00000003223.4|OR4F5-201|OR4F5|2618|UTR5:1-60|CDS:61-1041|UTR3:1042-2618|
  9. CCCAGATCTCTTCAGTTTTTATGCCTCATTCTGTGAAAATTGCTGTAGTCTCTTCCAGTT
  10. ATGAAGAAGGTAACTGCAGAGGCTATTTCCTGGAATGAATCAACGAGTGAAACGAATAAC
  11. TCTATGGTGACTGAATTCATTTTTCTGGGTCTCTCTGATTCTCAGGAACTCCAGACCTTC
  12. CTATTTATGTTGTTTTTTGTATTCTATGGAGGAATCGTGTTTGGAAACCTTCTTATTGTC
  13. ATAACAGTGGTATCTGACTCCCACCTTCACTCTCCCATGTACTTCCTGCTAGCCAACCTC
  14. TCACTCATTGATCTGTCTCTGTCTTCAGTCACAGCCCCCAAGATGATTACTGACTTTTTC
  15. AGCCAGCGCAAAGTCATCTCTTTCAAGGGCTGCCTTGTTCAGATATTTCTCCTTCACTTC
  16. TTTGGTGGGAGTGAGATGGTGATCCTCATAGCCATGGGCTTTGACAGATATATAGCAATA
  17. TGCAAGCCCCTACACTACACTACAATTATGTGTGGCAACGCATGTGTCGGCATTATGGCT

ENST00000641515.2|ENSG00000186092.7|OTTHUMG00000001094.4|OTTHUMT00000003223.4|OR4F5-201|OR4F5|2618|UTR5:1-60|CDS:61-1041|UTR3:1042-2618|

每个序列的 ID 由这么一长串内容组成,分别是:

  • ENST00000641515.2 : ensembl 的转录本 id
  • ENSG00000186092.7 : ensembl 的基因 id
  • OTTHUMG00000001094.4 : havana 的基因 id
  • OTTHUMT00000003223.4 : havana 的转录本 id
  • OR4F5-201 : 转录本名称
  • OR4F5 : 基因名
  • 2618 : 转录本序列总长度
  • UTR5:1-60 : 转录本 5’UTR 的位置
  • CDS:61-1041 : 转录本 CDS 的位置
  • UTR3:1042-2618 : 转录本 3’UTR 的位置

我还想重新命名每个转录本序列的 ID,只保留基因名gene_idtranscript_idtranscript_nameCDS 起始位置终止位置转录本长度,类似于下面这种更加简洁一点:

  1. >OR4F5_ENSG00000186092.7_ENST00000641515.2_OR4F5-201_61_1041_2618
  2. >OR4F29_ENSG00000284733.2_ENST00000426406.4_OR4F29-201_1_939_939
  3. >OR4F16_ENSG00000284662.1_ENST00000332831.4_OR4F16-201_20_958_995

把转录组序列名字输出保存到一个文件里,同时去除 havana 的基因 id 和转录本 id:

  1. # 按 | 字符分割
  2. $ zless gencode.v38.pc_transcripts.fa.gz |grep '>' |sed 's/|/\t/g' |cut -f 1,2,5,6,7,8,9,10 > name.txt
  3. # 查看内容
  4. $ head -3 name.txt
  5. >ENST00000641515.2 ENSG00000186092.7 OR4F5-201 OR4F5 2618 UTR5:1-60 CDS:61-1041 UTR3:1042-2618
  6. >ENST00000426406.4 ENSG00000284733.2 OR4F29-201 OR4F29 939 CDS:1-939
  7. >ENST00000332831.4 ENSG00000284662.1 OR4F16-201 OR4F16 995 UTR5:1-19 CDS:20-958 UTR3:959-995

2、改名操作

导入 R 里:

  1. # 设置工作路径
  2. setwd('C:/Users/admin/Desktop/test/')
  3. # 读取id数据
  4. all_name <- read.delim('name.txt',header = F)
  5. # 添加列名
  6. colnames(all_name) <- c('tt_id','gene_id','tt_name','gene_name','tt_length','info1','info2','info3')
  7. # 查看行数
  8. nrow(all_name)
  9. [1] 106143

用 R 提取代表性转录本 - 图2

可以看到最后 3 列相同的内容不在一列里,这是因为有些转录本只有 CDS 区或者 5’UTR 和 CDS 区,我们需要增加一列都是 CDS 区的位置信息:

  1. # 添加cds列
  2. library(stringr)
  3. # 新建储存cds信息的list
  4. cds_list <- list()
  5. # 循环
  6. for (i in 1:nrow(all_name)) {
  7. # 提取数据
  8. all_name_filter <- all_name[i,]
  9. # 分割info1
  10. info_1 <- unlist(strsplit(all_name_filter$info1,split = ':|-'))
  11. if (info_1[1] == 'UTR5') {
  12. # 如果第一个是UTR5,则取第二个元素
  13. cds_list[[i]] <- all_name_filter$info2
  14. }else if(info_1[1] == 'CDS') {
  15. # 如果第一个是CDS,则取第一个元素
  16. cds_list[[i]] <- all_name_filter$info1
  17. }else {
  18. }
  19. }
  20. # 查看个数
  21. length(cds_list)
  22. [1] 106143
  23. # 合并cds数据
  24. cds_res <- do.call('rbind',cds_list)
  25. # 储存在新数据里
  26. all_name_cds <- all_name
  27. all_name_cds$cds <- cds_res
  28. # 查看内容
  29. head(all_name_cds,4)
  30. tt_id gene_id tt_name gene_name tt_length info1 info2 info3
  31. 1 >ENST00000641515.2 ENSG00000186092.7 OR4F5-201 OR4F5 2618 UTR5:1-60 CDS:61-1041 UTR3:1042-2618
  32. 2 >ENST00000426406.4 ENSG00000284733.2 OR4F29-201 OR4F29 939 CDS:1-939
  33. 3 >ENST00000332831.4 ENSG00000284662.1 OR4F16-201 OR4F16 995 UTR5:1-19 CDS:20-958 UTR3:959-995
  34. 4 >ENST00000616016.5 ENSG00000187634.13 SAMD11-209 SAMD11 3465 UTR5:1-509 CDS:510-3044 UTR3:3045-3465
  35. cds
  36. 1 CDS:61-1041
  37. 2 CDS:1-939
  38. 3 CDS:20-958
  39. 4 CDS:510-3044
  40. ###################################
  41. # 改名
  42. # 新建储存添加列名的list
  43. st_sp_list <- list()
  44. # 循环
  45. for (i in 1:nrow(all_name_cds)) {
  46. # 提取数据
  47. all_name_cds_filter <- all_name_cds[i,]
  48. # 分割info1
  49. info_cds <- unlist(strsplit(all_name_cds_filter$cds,split = ':|-'))
  50. # 去掉tt_id的 > 符号
  51. ttid <- unlist(strsplit(all_name_cds_filter$tt_id,split = '>'))[2]
  52. # 添加改名列
  53. all_name_cds_filter$new_name <- paste(all_name_cds_filter$gene_name,
  54. all_name_cds_filter$gene_id,
  55. ttid,
  56. all_name_cds_filter$tt_name,
  57. info_cds[2],
  58. info_cds[3],
  59. all_name_cds_filter$tt_length,
  60. sep = '_')
  61. # 储存结果
  62. st_sp_list[[i]] <- all_name_cds_filter
  63. }
  64. length(st_sp_list)
  65. [1] 106143
  66. # 合并数据
  67. st_sp_res <- do.call('rbind',st_sp_list)
  68. # 查看内容
  69. head(st_sp_res$new_name,4)
  70. [1] "OR4F5_ENSG00000186092.7_ENST00000641515.2_OR4F5-201_61_1041_2618"
  71. [2] "OR4F29_ENSG00000284733.2_ENST00000426406.4_OR4F29-201_1_939_939"
  72. [3] "OR4F16_ENSG00000284662.1_ENST00000332831.4_OR4F16-201_20_958_995"
  73. [4] "SAMD11_ENSG00000187634.13_ENST00000616016.5_SAMD11-209_510_3044_3465"

这样我们就成功的改好了名字!接下来我们需要读入转录组序列,把它们重新命名。

  1. # 读取转录组序列fasta文件
  2. # 安装读取fasta文件的R包
  3. BiocManager::install('seqinr')
  4. library(seqinr)
  5. fasta <- read.fasta('gencode.v38.pc_transcripts.fa.gz',
  6. seqtype = 'DNA',
  7. forceDNAtolower = F)
  8. # fasta数据类型
  9. class(fasta)
  10. [1] "list"
  11. # 查看命名前的名称
  12. names(fasta)[1]
  13. [1] "ENST00000641515.2|ENSG00000186092.7|OTTHUMG00000001094.4|OTTHUMT00000003223.4|OR4F5-201|OR4F5|2618|UTR5:1-60|CDS:61-1041|UTR3:1042-2618|"
  14. # 命名
  15. names(fasta) <- st_sp_res$new_name
  16. # 查看命名后的名称
  17. names(fasta)[1]
  18. [1] "OR4F5_ENSG00000186092.7_ENST00000641515.2_OR4F5-201_61_1041_2618"
  19. # 保存命名后的数据
  20. write.fasta(sequences = fasta,
  21. names = names(fasta),
  22. file.out = 'name_changed.fa')

3、提取代表性转录本

主要思路,我们已经获得了转录本长度的信息,只要计算每个转录本的 CDS 区长度即可,然后按 CDS 列转录本长度列降序排序取第一个就行了。

  1. library(tidyverse)
  2. # 提取代表性转录本
  3. # 新建储存筛选出代表性转录本的信息
  4. repsentive_tspt <- list()
  5. # gene
  6. gene <- unique(st_sp_res$gene_name)
  7. # 循环
  8. for (g in gene) {
  9. # 筛选gene
  10. ginfo <- st_sp_res %>% filter(gene_name == g)
  11. # 添加cds length
  12. # 切分cds列
  13. cds_list <- strsplit(ginfo$cds,split = ':|-')
  14. # 获取cds start和stop位置
  15. start <- sapply(cds_list, '[',2)
  16. stop <- sapply(cds_list, '[',3)
  17. # 计算赋值cds length
  18. ginfo$cds_length <- as.numeric(stop) - as.numeric(start)
  19. # 先按cds_length列降序,再按tt_length列降序
  20. ginfo_order <- ginfo %>% arrange(desc(cds_length,tt_length))
  21. # 筛选transcript
  22. tid <- ginfo$tt_id[1]
  23. list_name <- paste(g,tid,sep = '_')
  24. # 取第一行元素保存
  25. repsentive_tspt[[list_name]] <- ginfo_order[1,]
  26. }
  27. # 查看筛选结果数量
  28. length(repsentive_tspt)
  29. [1] 20336
  30. repsentive_results <- do.call('rbind',repsentive_tspt)
  31. # 查看有多少个基因
  32. length(unique(repsentive_results$gene_id))
  33. [1] 20336
  34. # 查看有多少个转录本
  35. length(unique(repsentive_results$tt_id))
  36. [1] 20336
  37. # 查看结果
  38. head(repsentive_results,4)
  39. tt_id gene_id tt_name gene_name tt_length info1
  40. OR4F5_>ENST00000641515.2 >ENST00000641515.2 ENSG00000186092.7 OR4F5-201 OR4F5 2618 UTR5:1-60
  41. OR4F29_>ENST00000426406.4 >ENST00000426406.4 ENSG00000284733.2 OR4F29-201 OR4F29 939 CDS:1-939
  42. OR4F16_>ENST00000332831.4 >ENST00000332831.4 ENSG00000284662.1 OR4F16-201 OR4F16 995 UTR5:1-19
  43. SAMD11_>ENST00000616016.5 >ENST00000618323.5 ENSG00000187634.13 SAMD11-213 SAMD11 3468 UTR5:1-509
  44. info2 info3 cds
  45. OR4F5_>ENST00000641515.2 CDS:61-1041 UTR3:1042-2618 CDS:61-1041
  46. OR4F29_>ENST00000426406.4 CDS:1-939
  47. OR4F16_>ENST00000332831.4 CDS:20-958 UTR3:959-995 CDS:20-958
  48. SAMD11_>ENST00000616016.5 CDS:510-3047 UTR3:3048-3468 CDS:510-3047
  49. new_name cds_length
  50. OR4F5_>ENST00000641515.2 OR4F5_ENSG00000186092.7_ENST00000641515.2_OR4F5-201_61_1041_2618 980
  51. OR4F29_>ENST00000426406.4 OR4F29_ENSG00000284733.2_ENST00000426406.4_OR4F29-201_1_939_939 938
  52. OR4F16_>ENST00000332831.4 OR4F16_ENSG00000284662.1_ENST00000332831.4_OR4F16-201_20_958_995 938
  53. SAMD11_>ENST00000616016.5 SAMD11_ENSG00000187634.13_ENST00000618323.5_SAMD11-213_510_3047_3468 2537

接下来该怎么从筛选的结果中取提取 fasta 数据呢?

  1. # 读取改名后的fasta
  2. named_fasta <- read.fasta('name_changed.fa',seqtype = 'DNA',forceDNAtolower = F)
  3. # 对代表性转录本循环
  4. tar_name <- repsentive_results$new_name
  5. # 建立储存筛选结果的list
  6. target_falist <- list()
  7. # 循环
  1. for (i in tar_name) {
  2. choose <- i %in% names(named_fasta)
  3. if ("TRUE" %in% choose) {
  4. target_falist[i] <- named_fasta[i]
  5. }else{
  6. }
  7. }
  8. # 查看筛选结果数量
  9. length(target_falist)
  10. [1] 20336
  11. # 保存筛选的数据
  12. write.fasta(sequences = target_falist,
  13. names = names(target_falist),
  14. file.out = 'test_transcript.fa')

查看数据内容:

  1. $ head test_transcript.fa
  2. >OR4F5_ENSG00000186092.7_ENST00000641515.2_OR4F5-201_61_1041_2618
  3. CCCAGATCTCTTCAGTTTTTATGCCTCATTCTGTGAAAATTGCTGTAGTCTCTTCCAGTT
  4. ATGAAGAAGGTAACTGCAGAGGCTATTTCCTGGAATGAATCAACGAGTGAAACGAATAAC
  5. TCTATGGTGACTGAATTCATTTTTCTGGGTCTCTCTGATTCTCAGGAACTCCAGACCTTC
  6. CTATTTATGTTGTTTTTTGTATTCTATGGAGGAATCGTGTTTGGAAACCTTCTTATTGTC
  7. ATAACAGTGGTATCTGACTCCCACCTTCACTCTCCCATGTACTTCCTGCTAGCCAACCTC
  8. TCACTCATTGATCTGTCTCTGTCTTCAGTCACAGCCCCCAAGATGATTACTGACTTTTTC
  9. AGCCAGCGCAAAGTCATCTCTTTCAAGGGCTGCCTTGTTCAGATATTTCTCCTTCACTTC
  10. TTTGGTGGGAGTGAGATGGTGATCCTCATAGCCATGGGCTTTGACAGATATATAGCAATA
  11. TGCAAGCCCCTACACTACACTACAATTATGTGTGGCAACGCATGTGTCGGCATTATGGCT

OK!搞定!