首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Perl:从大量数据中删除重复项

Perl:从大量数据中删除重复项
EN

Stack Overflow用户
提问于 2011-04-19 05:01:39
回答 4查看 1.6K关注 0票数 6

我正在使用Perl生成一个独特的外显子列表(这是基因的单位)。

我生成了一个这种格式的文件(有几十万行):

chr1 1000 2000 gene1

chr1 3000 4000 gene2

chr1 5000 6000 gene3

chr1 1000 2000 gene4

位置1是染色体,位置2是外显子的起始坐标,位置3是外显子的结束坐标,位置4是基因名称。

因为基因通常是由不同的外显子排列构成的,所以你在多个基因中有相同的外显子(参见第一和第四组)。我想删除这些“重复的”-即,删除gene1或gene4 (哪个被删除并不重要)。

为了(我认为)做一件简单的事情,我已经用头撞墙好几个小时了。谁能给我指个方向?我知道人们经常使用散列来删除重复的元素,但这些并不完全是重复的(因为基因名称是不同的)。重要的是我不能把基因的名字弄丢。否则,这将会更简单。

这是我试过的一个完全不起作用的循环。"exons“数组将每一行存储为标量,因此是子例程。别笑了。我知道它不起作用,但至少你能看到(我希望)我想要做的事情:

代码语言:javascript
运行
复制
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
                    }
            }
}

}

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-04-19 05:27:34

代码语言:javascript
运行
复制
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;

这将使您具有唯一性,并且将包含最后一个基因名称。这将导致:

代码语言:javascript
运行
复制
chr1 1000 2000 gene4 
chr1 5000 6000 gene3 
chr1 3000 4000 gene2
票数 7
EN

Stack Overflow用户

发布于 2011-04-19 05:12:59

您可以使用散列来对en passant进行重复数据删除,但您需要一种方法来将要用来检测重复项的部分连接到单个字符串中。

代码语言:javascript
运行
复制
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;
票数 3
EN

Stack Overflow用户

发布于 2011-04-19 05:16:25

您可以使用散列来跟踪您已经看到的副本,然后跳过它们。此示例假定输入文件中的字段以空格分隔:

代码语言:javascript
运行
复制
#!/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;
  }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5708846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档