我正在使用Perl生成一个独特的外显子列表(这是基因的单位)。
我生成了一个这种格式的文件(有几十万行):
chr1 1000 2000 gene1
chr1 3000 4000 gene2
chr1 5000 6000 gene3
chr1 1000 2000 gene4
位置1是染色体,位置2是外显子的起始坐标,位置3是外显子的结束坐标,位置4是基因名称。
因为基因通常是由不同的外显子排列构成的,所以你在多个基因中有相同的外显子(参见第一和第四组)。我想删除这些“重复的”-即,删除gene1或gene4 (哪个被删除并不重要)。
为了(我认为)做一件简单的事情,我已经用头撞墙好几个小时了。谁能给我指个方向?我知道人们经常使用散列来删除重复的元素,但这些并不完全是重复的(因为基因名称是不同的)。重要的是我不能把基因的名字弄丢。否则,这将会更简单。
这是我试过的一个完全不起作用的循环。"exons“数组将每一行存储为标量,因此是子例程。别笑了。我知道它不起作用,但至少你能看到(我希望)我想要做的事情:
for (my $i = 0; $i < scalar @exons; $i++) {
my @temp_line = line_splitter($exons[$i]); # runs subroutine turning scalar into array
for (my $j = 0; $j < scalar @exons_dup; $j++) {
my @inner_temp_line = line_splitter($exons_dup[$j]); # runs subroutine turning scalar into array
unless (($temp_line[1] == $inner_temp_line[1]) && # this loop ensures that the the loop
($temp_line[3] eq $inner_temp_line[3])) { # below skips the identical lines
if (($temp_line[1] == $inner_temp_line[1]) && # if the coordinates are the same
($temp_line[2] == $inner_temp_line[2])) { # between the comparisons
splice(@exons, $i, 1); # delete the first one
}
}
}}
发布于 2011-04-19 05:27:34
my @exons = (
'chr1 1000 2000 gene1',
'chr1 3000 4000 gene2',
'chr1 5000 6000 gene3',
'chr1 1000 2000 gene4'
);
my %unique_exons = map {
my ($chro, $scoor, $ecoor, $gene) = (split(/\s+/, $_));
"$chro $scoor $ecoor" => $gene
} @exons;
print "$_ $unique_exons{$_} \n" for keys %unique_exons;这将使您具有唯一性,并且将包含最后一个基因名称。这将导致:
chr1 1000 2000 gene4
chr1 5000 6000 gene3
chr1 3000 4000 gene2发布于 2011-04-19 05:12:59
您可以使用散列来对en passant进行重复数据删除,但您需要一种方法来将要用来检测重复项的部分连接到单个字符串中。
sub extract_dup_check_string {
my $exon = shift;
my @parts = line_splitter($exon);
# modify to suit:
my $dup_check_string = join( ';', @parts[0..2] );
return $dup_check_string;
}
my %seen;
@deduped_exons = grep !$seen{ extract_dup_check_string($_) }++, @exons;发布于 2011-04-19 05:16:25
您可以使用散列来跟踪您已经看到的副本,然后跳过它们。此示例假定输入文件中的字段以空格分隔:
#!/usr/bin/env perl
use strict;
use warnings;
my %seen;
while (my $line = <>) {
my($chromosome, $exon_start, $exon_end, $gene) = split /\s+/, $line;
my $key = join ':', $chromosome, $exon_start, $exon_end;
if ($seen{$key}) {
next;
}
else {
$seen{$key}++;
print $line;
}
}https://stackoverflow.com/questions/5708846
复制相似问题