将SNP坐标映射到基因坐标太慢

时间:2017-11-02 16:03:42

标签: perl optimization match

我有两个制表符分隔的文件,例如

文件1 (这些是单核苷酸多态性(SNP)位置)

Chr1 26690
Chr1 33667
Chr1 75049
.
.

Chr2 12342
Chr2 32642
Chr2 424421
.
.

文件2 (这些是基因起点和终点坐标)

Chr1    2903    10817   LOC_Os01g01010
Chr1    2984    10562   LOC_Os01g01010
Chr1    11218   12435   LOC_Os01g01019
Chr1    12648   15915   LOC_Os01g01030
Chr1    16292   18304   LOC_Os01g01040
Chr1    16292   20323   LOC_Os01g01040
Chr1    16321   20323   LOC_Os01g01040
Chr1    16321   20323   LOC_Os01g01040
Chr1    22841   26971   LOC_Os01g01050
Chr1    22841   26971   LOC_Os01g01050
.
.

我想要的是将文件1中的SNP与文件2中的基因相匹配。脚本应匹配文件第一列中的字符串,如果它们匹配则应该找到文件2中的哪个基因包含相应的SNP并从文件2的第四列返回基因座ID。

这是我写的剧本

use strict;

my $i1 = $ARGV[0];            # SNP 
my $i2 = $ARGV[1];            # gene coordinate

open(I1, $i1);
open(I2, $i2);

my @snp  = ();
my @coor = ();

while( <I1> ) {
  push(@snp, $_);    
}

while ( <I2> ) {
  push(@coor, $_);   
}

for ( my $i = 0; $i <= $#snp; $i++ ) {

    my @snp_line = split "\t", $snp[$i];

    for ( my $j = 0; $j <= $#coor; $j++ ) {

        my @coor_line = split "\t", $coor[$i];   

        if ( $snp_line[0] eq $coor_line[0] ) {

            if ( $snp_line[1] >= $coor_line[1] && $snp_line[1] <= $coor_line[2] ) {
              print "$snp_line[0]\t$snp_line[1]\t$coor_line[3]\n";
              goto a;
            }
        }   
    }
a: 
}

问题是,显然这不是最好的方法,因为它遍历第1行中每个SNP的文件2中的所有~60,000行。此外,它在一夜之间运行并且没有超过{{1} };我们最多Chr1

2 个答案:

答案 0 :(得分:-1)

这是一个工作脚本,上面发布的脚本有错误

use strict;

my $i1=$ARGV[0];            # SNP 
my $i2=$ARGV[1];            # gene coordinate

open(I1,$i1);
open(I2,$i2);

my @snp=();
my @coor=();

while(<I1>)
{
push(@snp,$_);  
}
while(<I2>)
{
push(@coor,$_); 
}

for(my $i=0;$i<=$#snp;$i++)
{
my @snp_line = split "\t",$snp[$i];

for(my $j=0;$j<=$#coor;$j++)
{
    my @coor_line = split "\t",$coor[$j];

    if ($snp_line[0] eq $coor_line[0])
    {   
        if ($snp_line[1] >= $coor_line[1] && $snp_line[1] <= $coor_line[2])
        {
            print "$snp_line[0]\t$snp_line[1]\t$coor_line[3]\n";                
        }

    }   

}

}

这个人完成了这项工作。

答案 1 :(得分:-1)

您可以在重新格式化为UCSC BED格式时使用这些文件,使用像BEDOPS这样的工具包对排序的BED文件执行有效的设置操作。

将您的第一个SNP文件转换为已排序的BED文件:

$ awk -v OFS="\t" '{ print $1, $2, ($2+1); }' snps.txt | sort-bed - > snps.bed

对基因进行排序(“文件2”):

$ sort-bed genes.unsorted.txt > genes.bed

将SNP映射到基因:

$ bedmap --echo --echo-map-id-uniq --delim '\t' snps.bed genes.bed > answer.bed

如果需要,您可以从答案中删除SNP的最终位置:

$ cut -f1,2,4 answer.bed > answer.txt

这些工具运行速度非常快,通常会在几分钟内完成。

我不会使用Perl或Python来进行这些类型的集合操作,除非我正在进行某种学术练习。