合并表中的重叠坐标

时间:2014-06-05 01:40:18

标签: perl awk

我有一个包含五列的表格。如果它们重叠,我想合并起始和结束列,并且具有相同的RNAiclone和target_mRNA名称。如果两个条目的起始端是:(A)1-10,11-20表示重叠范围;而(B)1-10,12-20表示无重叠范围。 RNAilength(nt)对于类似的RNAiclone是相同的。

input.txt中

RNAiclone   RNAilength(nt)  target_mRNA  start   end
siRNA1      10              mRNA1         1      10
siRNA1      10              mRNA1         11     20
siRNA1      10              mRNA1         17     30
siRNA1      10              mRNA2         18     19
siRNA2      20              mRNA2         1      10
siRNA2      20              mRNA2         9      100

预期output.txt

RNAiclone   RNAilength(nt)  target_mRNA   start   end
siRNA1      10              mRNA1         1       30
siRNA1      10              mRNA2         18      19
siRNA2      20              mRNA2         1       100

program.awk

BEGIN{
  i=0;
  s="";
  m="";
  OFS="\t";
}
{
  if (s!=$1 && m!=$3){
    if (s != "" && m!= ""){
      combine(chr,s,m,i);
    }
    i=0;
    s="";
  }
  s=$1;
  m=$3;
  chr[i,0]=$4;
  chr[i,1]=$5;
  i++
}
END{
  combine(chr,s,m,i);
}
function combine(arr,s,m,i) {
  j=0;
  new[j,0]=arr[0,0];
  new[j,1]=arr[0,1];
  for (k=1;k<i;k++)
    {
      if ((arr[k,0]<=new[j,1])&&(arr[k,1]>=new[j,1])){
    new[j,1]=arr[k,1];
      }
      else if (arr[k,0]>new[j,1]){
    j++;
    new[j,0]=arr[k,0];
    new[j,1]=arr[k,1];
      }
    }
  for (n=0;n<=j;n++){
    print s,m,new[n,0],new[n,1]
  }
}

我正在使用命令&#34; wk -f program.awk input.txt&gt;运行脚本。 output.txt&#34;,但我没有得到预期的结果。你能帮我纠正一下这个剧本吗?非常感谢你。

2 个答案:

答案 0 :(得分:0)

尝试重启比调试代码更容易。这是awk的替代品。将以下内容放入可执行的awk文件中:

#!/usr/bin/awk -f

BEGIN { OFS="\t" }

/^RNA/ { print; next }

{
  key = $1 OFS $2 OFS $3

  # new key or new range, print last line
  if( key != l_key || l_end+1 < $4 ) {
    if( FNR>1 && l_key ) { print l_key, s[l_key], l_end }
    s[key]=$4
  }

  l_key=key
  l_end=$5
}

END { print l_key, s[l_key], l_end } # print final range

调用该文件awko(和chmod +x awko),然后像awko input.txt一样运行,提供以下内容:

RNAiclone   RNAilength(nt)  target_mRNA  start   end
siRNA1  10  mRNA1   1   30
siRNA1  10  mRNA2   18  19
siRNA2  20  mRNA2   1   100

可以与awko input.txt | column -t重新对齐:

RNAiclone  RNAilength(nt)  target_mRNA  start  end
siRNA1     10              mRNA1        1      30
siRNA1     10              mRNA2        18     19
siRNA2     20              mRNA2        1      100

所以最后的命令是

awko data | column -t > output.txt

这至少有以下假设:

  • 数据按列1-4排序,如示例input.txt
  • 中所示
  • 范围的行为就好像结束总是&gt; =开始(我没有测试任何其他内容)

答案 1 :(得分:0)

您已经收到了awk个答案,但这里的版本在perl中也是如此:

use strict;
use warnings;

my $last;
while (<>) {
    my @cols = split;
    my $key = join ' ', splice @cols, 0, 3;
    my ($start, $end) = @cols;
    if ($last) {
        if ($last->[0] ne $key || $last->[2] < $start - 1) {
            print "@$last\n"
        } else {
            $start = $last->[1];
            $end   = $last->[2] if $end < $last->[2];
        }
    }
    $last = [$key, $start, $end];
}
print "@$last\n";

执行此程序perl merge_range.pl file.dat会得到以下结果:

RNAiclone RNAilength(nt) target_mRNA start end
siRNA1 10 mRNA1 1 30
siRNA1 10 mRNA2 18 19
siRNA2 20 mRNA2 1 100

假设数据的排序方式与示例数据类似。要格式化列,只需通过column -t