Correspondência de coluna múltipla e ajuste com awk

3

Eu tenho um problema que está me dando um pouco de dor de cabeça, mas não costuma levar muito como um iniciante.

Eu tenho um arquivo que se parece com isso

    ID A1 A2 A3
    1  A  G  A
    2  T  G  A
    3  T  A  G
    4  T  G  A
    5  A  A  G
    6  A  C  A
    7  C  T  G

que tem milhares de linhas de comprimento e é composto de G, C, T, A, onde G complementa C e A complementa T. O que eu estou tentando fazer é procurar uma correspondência para A1 em A2 ou A3 Se houver uma correspondência, então ela deve ser deixada como está e se não houver a mudança de A2 e A3 para seus complementos, ou seja, A = T e G = C e vice-versa.

Assim, a saída seria:

    ID A1 A2 A3
    1  A  G  A
    2  T  C  T
    3  T  T  C
    4  T  C  T
    5  A  A  G
    6  A  C  A
    7  C  A  C

Eu achei que poderia fazer isso usando o awk para filtrar IDs correspondentes e inigualáveis usando:

   awk '{if($2 != $3 || $2 != $4) print $0}' mergedlist > nonmatchlist

e

   awk '{if($2 == $3 || $2 == $4) print $0}' mergedlist > matchlist

mas funcionou apenas para uma variável, isto é, T no primeiro e A no segundo.

Muito obrigado pela sua contribuição.

    
por Asfound 14.08.2015 / 21:41

3 respostas

3
perl -lane 'sub flip { if ($_[0] eq "T") { "A" } elsif ($_[0] eq "A") { "T" } elsif ($_[0] eq "G") { "C" } elsif ($_[0] eq "C") { "G" } else { $_[0] } } if (!($F[1] eq $F[2] or $F[1] eq $F[3])) { $F[2] = flip($F[2]); $F[3] = flip($F[3]) } print "@F"' < input

Deve ser fácil voltar a awk , já que não está realmente fazendo nada extravagante, mas isso me levaria mais tempo para descobrir.

    
por 14.08.2015 / 21:56
3

Você poderia construir uma matriz associativa como uma tabela de consulta para os complementos, por exemplo

awk '
  BEGIN {
    complement["A"]="T"; complement["T"]="A";
    complement["C"]="G"; complement["G"]="C";
  } 

  NR>1 && $3!=$2 && $4!=$2 {
    $3 = complement[$3]; 
    $4 = complement[$4];
  } 

  {
    print;
  }
' file
    
por 14.08.2015 / 22:18
1

Como alternativa a uma matriz sugerida por @steeldriver, você pode definir uma função:

awk '
  BEGIN { FS == " +" }
  NR == 1 {print $0 }
  function CHANGE( F )
    {
      if ( F == "A" ) F = "T"
      else if ( F == "T" ) F = "A"
      else if ( F == "C" ) F = "G"
      else F = "C"
      return F
    }
  NR >= 2 {
    if ( $2 == $3 || $2 == $4 ) print $0
    else {
      $3=CHANGE($3)
      $4=CHANGE($4)
      printf "%5d%3s%3s%3s\n",$1,$2,$3,$4
    }
  }
' file 
    
por 15.08.2015 / 20:32