前幾天晚上在練習(xí)Perl編程時(shí)突然頓悟了以前一直迷惑的哈希數(shù)組。對(duì)這一類的問題的解決瞬間開拓了新思路。這兩天利用雙重哈希/哈希數(shù)組解決了一些數(shù)據(jù)轉(zhuǎn)換中的一些小問題。記錄分享一下。
利用哈希數(shù)組整合相同的數(shù)據(jù)名
- 需求:在基因ID轉(zhuǎn)換過程中,存在著一個(gè)GeneID對(duì)應(yīng)著多個(gè)SYMBOL NAME,和description信息,需要對(duì)這多個(gè)SYMBOL做個(gè)整合,最終得到一個(gè)ID對(duì)一個(gè)SYMBOL對(duì)一個(gè)DESCRIPTION。
-
利用哈希數(shù)組中的哈希鍵是唯一的特性對(duì)值做整合
輸入文件格式
輸出文件格式
#!/usr/bin/env perl
use strict;
my %hash;
open IN,$ARGV[0] or die "$!";
while(<IN>){
chomp;
my @F = split/\t/;
push @{$hash{$F[1]}{$F[3]}},$F[2];
}
foreach my $id (sort keys %hash){
foreach my $description (sort keys %{$hash{$id}} ){
my $name=join "http://",@{$hash{$id}{$description}};
print "$id\t$name\t$description\n";
}
}
gff文件和fasta文件提取CDS序列
- 根據(jù)gff文件中的CDS坐標(biāo)提取各個(gè)轉(zhuǎn)錄本的核酸序列,注意存在轉(zhuǎn)錄本的正負(fù)鏈問題,每個(gè)轉(zhuǎn)錄本的第一個(gè)cds有frame移碼問題。
-
利用雙重哈希,以及程序USAGE基本用法。
GFF文件
FASTA
#!/usr/bin/env perl
use strict;
my $usage=<<USAGE;
Usage:
perl $0 genome.fasta genome.gff3
USAGE
print $usage if(@ARGV==0);
open IN ,"$ARGV[0]" or die "$!";
my (%seq,$seq_id);
while(<IN>){
chomp;
if(/^>(\S+)/){$seq_id=$1}else{
$seq{$seq_id}.=$_;
}
}
close IN;
open IN,"$ARGV[1]" or die "$!";
my(%cds_pos, %contig, %stream );
while(<IN>){
chomp;
if(/\tCDS\t/){
my @F=split/\t/;
$F[8]=~/Parent=(.*?);/;
$cds_pos{$1}{"$F[3]\t$F[4]\t$F[7]"}=1;
$contig{$1}=$F[0];
$stream{$1}=$F[6];
}
}
close IN;
foreach my $id(sort keys %contig){
my $cds_seq;
my @cds_pos_parsing=sort { $cds_pos{$id}{$a}<=>$cds_pos{$id}{$b} } keys %{$cds_pos{$id}};
foreach (@cds_pos_parsing){
my @F=split/\t/;
$cds_seq.=substr($seq{$contig{$id}},$F[0]-1,$F[1]-$F[0]+1);
}
if($stream{$id} eq "+"){
my $frame = $1 if ($cds_pos_parsing[0] =~/(\d+)$/);
$cds_seq=~s/\w{$frame}//;
print ">$id\n$cds_seq\n";
}else{
my $frame = $1 if ($cds_pos_parsing[-1]=~/(\d+)$/);
$cds_seq = reverse($cds_seq);
$cds_seq =~ tr/ATGCatgcn/TACGtacgN/;
$cds_seq =~ s/\w{$frame}//;
print">$id\n$cds_seq\n";
}
}