我有以下任务要做,我想知道如何在Perl中最有效地解决这个问题。 首先,我有一个包含66个元素的数组(染色体:start:end),看起来像这样
my @array = qw( chr1:1566-1762 chr7:1695-1955 ....)
接下来,我有一个包含此内容的大小为50MB的文件
CHR \t START \t \END \tab \Pattern
chr1 \t 1757 \t \2354 \t XM:Z:......H..H....H
.
.
我想检查我的文件的每一行,无论位置,开始和结束是否适合我的数组中的任何元素。文件中读取的位置与我的数组中的位置不同,但开始应包含在范围内。例如,我有一个适合第一个元素的读取" chr1:1566-1662"通过在1757年开始的位置。
你的方法是什么?我对每一个暗示和想法感到高兴!
答案 0 :(得分:1)
首先,我会将数组从字符串数组更改为某种结构数组(哈希)。这使得一些事情变得更容易:
my @array = (
{ chr => "chr1", start => 1566, end => 1762 },
{ chr => "chr7", start => 1695, end => 1955 }
);
进一步的优化可能是可以想象的(使用染色体作为范围列表的散列中的关键字)。
然后逐行浏览您的文件并拆分每一行并使用此信息进行检查。
open FILE, fname || die "could not open file\n";
while(my $line = <FILE>){
my @fields = split("\t", $line);
chomp($fields[0]); # remove whitespaces
my $entry = {chr => $fields[0], start => $fields[1], end => $fields[2]};
foreach $elem(@array){
if(testMatch($entry, $elem)){
print "found something";
}
}
}
close FILE;
分裂可能更复杂。你在问题中的例子并不十分清楚它是如何形成的。
如果条目匹配
,则testMatch例程只返回1sub testMatch
{
my $elem = shift;
my $range = shift;
return $elem->{chr} eq $range->{chr}
&& $elem->{start} >= $range->{start}
&& $elem->{start} <= $range->{end}
# && $elem->{end} <= $range->{end} # not sure if the segment has to be entirely in the range
;
如果您不想重新格式化输入@array
,可以在阅读文件之前以编程方式创建重新格式化的内容。
}