做完基因组注释后需要统计一下基因长度,CDS长度和intron以及exon长度。
1.首先统计基因数目,直接使用linux统计:
awk '$3 == "gene"' myannotation.gff | wc -l ##统计注释文件中第三列为gene的行数,即为基因的数目
2.统计基因长度,使用tidyverse包
2.1第一步先把gff文件转为gtf格式的注释
gffread myanno.gff -T -o myanno.gtf
用此种方式转换来的gtf注释没有exon id,不利于后续统计exon长度,因此使用perl脚本另转换一次,转换后的gtf文件如下,有了exon id
perl gff3_to_gtf_phytozome_1nt_exon_Mgly.pl my.gff myexon.gff ###for exon
perl 脚本来自导师,就不放啦,有需要可以私信(不知道这样行不行,思考ing)
2.2转换后使用R计算基因长度:
我文件中的所有gene都转换成了transcript,gene_id在gtf中为transcript_id,先提取所有transcript,然后计算平均长度:
install.packages("tidyverse") ##加载包
library(tidyverse)
gtf<-rtracklayer::import("my.gtf") ##读gtf文件
head(gtf)
table(gtf$type)
transcript<-gtf[gtf$type=="transcript",c("start", "end", "transcript_id")] ##每个transcript对应原有的基因
length(unique(transcript$transcript_id)) ###数基因数目
glc = lapply(split(transcript,transcript$transcript_id),function(x){
tmp=apply(x,1,function(y){
y[1]:y[2]
})
length(unique(unlist(tmp)))
}) ###计算长度
glc=data.frame(transcript_id=names(glc),
length=as.numeric(glc))
save(glc,file = "Mglytrans.Rdata")
load("Mglytrans.Rdata")
head(glc) ###所有基因长度
mylen<-glc$length
mymean<-mean(mylen) ##平均基因长度
mymean
2.2 计算平均CDS长度,这里是按照基因计算的,每个基因的CDS之和算是一个,因此是总CDS长度除以基因个数
gtf<-rtracklayer::import("my.gtf")
gtf<-as.data.frame(gtf);dim(gtf)
table(gtf$type) ###exon CDS transcript
CDS<-gtf[gtf$type=="CDS",c("start", "end", "transcript_id")] ##以基因为单位进行计算
length(unique(CDS$transcript_id))
glc = lapply(split(CDS,CDS$transcript_id),function(x){
tmp=apply(x,1,function(y){
y[1]:y[2]
})
length(unique(unlist(tmp)))
})
glc=data.frame(transcript_id=names(glc),
length=as.numeric(glc))
save(glc,file = "glc.Rdata")
load("glc.Rdata")
head(glc)
mylen<-glc$length
meancds<-mean(mylen)
meancds
2.3 计算平均外显子长度,以每个外显子为单位,因此是exon总长度除以exon个数
class(gtf) ###这里读入的是第二种方式转换的gtf
gtf<-as.data.frame(gtf);dim(gtf)
head(gtf)
table(gtf$type)
exon<-gtf[gtf$type=="exon",c("start", "end", "exon_id")]
length(unique(exon$exon_id))
glc = lapply(split(exon,exon$exon_id),function(x){
tmp=apply(x,1,function(y){
y[1]:y[2]
})
length(unique(unlist(tmp)))
})
glc=data.frame(exon_id=names(glc),
length=as.numeric(glc))
save(glc,file = "exon.Rdata")
load("exon.Rdata")
head(glc)
mylen<-glc$length
mymean<-mean(mylen)
mymean
2.4 计算平均内含子长度,使用python脚本计算的:
def step1(infile):
with open(infile, 'r') as f:
allintron = 0
id_exon = {}
out_list = []
sumlength = 0
for line in f:
lin = line.strip().split('\t')
name = lin[8].split(';')[1].split('\"')[1]
start = lin[3]
end = lin[4]
start_end = start + "\t" + end
if name not in id_exon.keys():
id_exon[name] = []
id_exon[name].append(start)
id_exon[name].append(end)
else:
id_exon[name].append(start)
id_exon[name].append(end)
for id in id_exon.keys():
exon = id_exon[id]
if len(exon) == 2:
intron = 0
else:
enum = len(exon)
print(enum, id)
for i in range(0, enum, 2):
if i == 0:
pass
else:
#print(i)
allintron += 1
len_intron = int(exon[i]) - int(exon[i-1]) - 1
sumlength += len_intron
num_int = i/2
outline = id + "\t" + str(num_int) + "\t" + str(len_intron) + "\n"
out_list.append(outline)
print(outline)
lastline = "average" + "\t" + str(sumlength/allintron) + "\n"
out_list.append(lastline)
return out_list
def write_out(list, outfile):
with open(outfile, "w") as myout:
for item in list:
myout.write(item)
myout.close()
intron_list = step1("Mgly.coding.gene_new_chr_new.gff")
write_out(intron_list, "Mgly_intron.txt")