||
在数据分析中经常会用到排序,使用Perl编程时,一个最简单的排序如下:
@array= sort @array; 该语句等同于:
@array= sort {$a cmp $b} @array;
假定数据储存在数组@array中,该语句表示对@array中元素执行字符串排序,就是按字母表顺序排序。如果希望按字母表顺序的倒序排序,则应该是:
@array= sort {$b cmp $a} @array;
如果希望按数字顺序从小到大排序,则应该是:
@array= sort {$a <=> $b} @array;
以上是一维数据,下面考虑复杂一点的情况,如何对二维数据进行排序。下面一组数据,第一列是GI号,第二列是序列长度,要求进行排序:
GI:389886562 2536
GI:215277009 15009
GI:301173067 138
...................
解决这个问题一个方式就是使用散列一次吃进所有数据,然后根据你的要求进行排序,比如:
my %hash;
open my ($IN), "<", $file or die;
while (<$IN>){
chomp($_);
my ($GI, $len)=split("\t", $_);
$hash{$GI}=$len;
}
close($IN);
foreach my $key(sort (keys %hash) ){
print "$keyt", "$hash{$key}n"; #根据GI号排序
}
foreach my $key(sort {$hash{$a} <=> $hash{b}} (keys %hash) ){
print "$keyt", "$hash{$key}n"; #根据序列长度排序
}
生物学数据分析经常出现比上面更复杂的情况,即如何对多维数据进行排序,假定下面一组数据是你的高通量测序结果,第一列是read counts,第二列是测序获得的序列,第三列是该序列长度,第四列显示该序列可以在多少样本中可以检测到,要求先根据read counts从大到小进行排序,然后根据序列长度排序,最后再根据样本数量排序:
12334 ATGTCGTGACGT 12 5
334 ATGTCGTGACGTATGTCGTGACGT 24 3
194 ATGTCGTGAC 10 8
...................
当然简单的办法就是放到EXCEL中处理,不过实际情况下数据可能有几万条,每一条有好几列信息,可能是字符串或数字,如果每一列信息长度相差很大,加上如果还要求进行其它操作,或者需要数据过滤或数据合并,那EXCEL就力不从心了。就需要Perl编程解决,于是需要把数组和散列结合起来使用,无论多复杂的数据结构都可以一次吃进,然后根据具体情况或排序或分析或输出:
my @array;
open my ($IN), "<", $file or die;
while (<$IN>){
chomp($_);
my ($read_counts, $seq, $len, $sample_num)=split("\t", $_);
my %hash=(read_counts=>$read_counts,
seq=>$seq,
seq_len=>$len,
sample_num=>$sample_num,
);
push(@array, %hash);
}
close($IN);
foreach my $pointer (sort { $b->{read_counts} <=> $a->{read_counts} or $b->{seq_len} <=> $a->{seq_len} or $b->{sample_num} <=> $a->{sample_num} } @array){
print "$pointer->{read_counts}\t", "$pointer->{seq}t", "$pointer->{seq_len}t", "$pointer->{sample_num}n";
}
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-10-19 22:08
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社