根据现有列向文件添加列

时间:2013-02-04 08:48:46

标签: perl awk calculated-columns tsv

我正在尝试修改一个设置如下的文件:

chr start   ref alt 
chr1    18884   C   CAAAA
chr1    135419  TATACA  T
chr1    332045  T   TTG
chr1    453838  T   TAC
chr1    567652  T   TG
chr1    602541  TTTA    T
chr1    614937  C   CTCTCTG
chr1    654889  C   CA
chr1    736800  AC  A

我想修改它,以便: 如果列“ref”是一个字符串> 1(即第2行),那么我生成2个新列,其中:

第一个新列=开始坐标-1 第二个新列=开始坐标+(参考中字符串的长度)+1

因此,对于第2行输出看起来像:

chr1 135419 TATACA T 135418 135426

如果“ref”中的字符串长度= 1且列“alt”=长度> 1的字符串(即第1行)则

第一个新列=开始坐标 第二个新列=开始坐标+ 2

所以,第1行的输出是:

chr1 18884 C CAAAA 18884 18886

我在awk中试过这个但没有成功 我的perl不存在,但这是最好的方法吗?或者也许在R?

3 个答案:

答案 0 :(得分:2)

这是使用awk的一种方式。像:

一样运行
awk -f script.awk file | column -t

script.awk的内容:

NR==1 {
    next
}

length($3)>1 && length($4)==1 {
    print $0, $2-1, $2+length($3)+1
    next
}

length($3)==1 && length($4)>1 {
    print $0, $2, $2+2
    next
}1

结果:

chr1  18884   C       CAAAA    18884   18886
chr1  135419  TATACA  T        135418  135426
chr1  332045  T       TTG      332045  332047
chr1  453838  T       TAC      453838  453840
chr1  567652  T       TG       567652  567654
chr1  602541  TTTA    T        602540  602546
chr1  614937  C       CTCTCTG  614937  614939
chr1  654889  C       CA       654889  654891
chr1  736800  AC      A        736799  736803

或者,这是单行:

awk 'NR==1 { next } length($3)>1 && length($4)==1 { print $0, $2-1, $2+length($3)+1; next } length($3)==1 && length($4)>1 { print $0, $2, $2+2; next }1' filem | column -t

代码应该是不言自明的。脚本末尾的1只能启用每行的默认打印(即'1'返回true)。 HTH。

答案 1 :(得分:2)

Perl解决方案。请注意,如果两个字符串都是长度为1,则您的规范没有提及该怎么做。

#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

#use Data::Dumper;
<DATA>; # Skip the header;
while (<DATA>) {
    my ($chr, $start, $ref, $alt) = split;
    my @cols;
    if (1 < length $ref) {
          @cols = ( $start - 1, $start + 1 + length $ref);
    } elsif (1 < length $alt) {
        @cols = ($start, $start + 2);
    } else {
        warn "Don't know what to do at $.\n";
    }
    say join "\t", $chr, $start, $ref, $alt, @cols;
}


__DATA__
chr start   ref alt
chr1    18884   C   CAAAA
chr1    135419  TATACA  T
chr1    332045  T   TTG
chr1    453838  T   TAC
chr1    567652  T   TG
chr1    602541  TTTA    T
chr1    614937  C   CTCTCTG
chr1    654889  C   CA
chr1    736800  AC  A

答案 2 :(得分:0)

在perl中执行它是微不足道的(但在awk中也是如此):

#!/usr/bin/perl
while (<>) {
  chmop;
  my ($chr,$start,$ref,$alt)=split(/\s+/,$_);
  if (len($ref) > 1) {
print STDOUT
  "$chr\t$start\t$ref\t$alt\t",
    $start+len($ref)+1,"\n";
  } elsif (len($ref)==1) {
print STDOUT
  "$chr\t$start\t$ref\t$alt\t",
    $start+2,"\n";
  } else {
print STDERR "ERROR: ???\n"; #actually impossible
  }
}

将其粘贴在文件morecols.pl,chmod + x morecols.pl中,运行更多morecols.pl。 (请注意,此代码/说明中有很多假设)。我有一种感觉,你的实际问题更多的是编程/文本处理,然后是工具或语言。如果是这样,这段代码只是一个权宜之计......

干杯。