【问题标题】:Merge Overlapping coordinate in a table合并表格中的重叠坐标
【发布时间】:2014-06-10 05:54:35
【问题描述】:

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

输入.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

预期输出.txt

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

程序.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]
  }
}

我正在使用命令“wk -f program.awk input.txt > output.txt”运行脚本,但没有得到预期的结果。你能帮我改正剧本吗?非常感谢。

【问题讨论】:

  • 有人在 3 个月前遇到过类似的问题,extract overlapping regions。不过,您的要简单得多。如果没有其他人的话,今晚晚些时候会响起。

标签: perl awk


【解决方案1】:

我尝试重新启动比调试您的代码更容易。这是 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
  • 范围的行为就像 end always >= start(我没有测试其他任何东西)

【讨论】:

    【解决方案2】:

    您已经得到了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 管道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 2017-12-27
      • 1970-01-01
      • 2011-09-30
      • 2021-12-21
      相关资源
      最近更新 更多