自己写了一个脚本来合并htseq-count得到的多个样本文件的计数矩阵。
以3个计数文件为例,不太规范,应该是偶数才对,且要满足重复的要求
3.pl* allfiles.txt SRR3589956.count SRR3589957.count SRR3589958.count
huangsiyuan 01:46:00 ~/learn_rnaseq/matrix_tmp
$ cat allfiles.txt
SRR3589956.count
SRR3589957.count
SRR3589958.count
以下是代码
#! /ifs1/Software/miniconda3/bin/perl
use warnings;
use strict;
#将参数文件中的count文件名保存至数组中
my @files = ();
my $parm_name = $ARGV[0];
open my $file_fh, "<", "$parm_name";
while (<$file_fh>) {
chomp $_;
push @files, $_;
}
close $file_fh;
#目的是求所有geneID的并集,并将键值对设定为:geneID=>所存在的文件
my %geneID_sample = ();
my @geneID_sample_keyarray = ();
for ( my $i = 0; $i <= $#files; $i++ ) {
open my $file_fh2, "<", "$files[$i]";
while (<$file_fh2>) {
chomp $_;
my @expression = (split("\t", $_));
my $geneID = $expression[0];
if (exists $geneID_sample{$geneID}) {
$geneID_sample{$geneID} .= ";$files[$i]";
} else {
$geneID_sample{$geneID} = "$files[$i]";
}
}
close $file_fh2;
}
#按照样本个数循环
#在一个内循环中,参照并集键,如果该样本有就附上count值,没有就补NA
my %left_index = ();#创建数组索引值与元素值的哈希
for ( my $i = 0; $i <= $#files; $i++ ) {
my $afile_line = 0;#记录行数和索引
my @left = ();
my @right = ();
open my $file_fh3, "<", "$files[$i]";
while (<$file_fh3>) {
chomp $_;
my @expression = (split("\t", $_));
push @left, $expression[0];
push @right, $expression[1];
$left_index{$expression[0]} = $afile_line;
$afile_line += 1;
}
close $file_fh3;
@geneID_sample_keyarray = sort ( keys %geneID_sample);
foreach my $each_ID ( @geneID_sample_keyarray ) {
if ($geneID_sample{$each_ID} =~ /$files[$i]/) {
$geneID_sample{$each_ID} .= "\t$right[$left_index{$each_ID}]";
} else {
$geneID_sample{$each_ID} .= "\tNA";
}
}
}
foreach my $j (@geneID_sample_keyarray) {
print "$j\t$geneID_sample{$j}\n";
}
使用,可以处理批量count文件
perl 3.pl allfiles.txt > allfiles_count.txt
代码有些长,主要是因为我对这种count文件不熟悉,其实可以简化很多。比如,这三个文件的行数是一样的,都为60844行,和gff3注释文件提取的gene_ID去重后几乎是相等的,三个文件每一行的gene_ID也一样。这说明,count计数是对所有基因(包括不编码蛋白质的基因)一起来计的。如果一个gene上面没有reads,则记为0,基本不会有缺失值,我grep了一下确实没有。