Converter genótipos para 0/1

4

Eu tenho um arquivo que parece:

1    rs6687776    1020428    T    C    T    C    T    C    C    C    T    C    C    C    T    C

A quarta e a quinta coluna são os dois possíveis alelos possíveis nesse site. Preciso alterar a coluna 6 em diante para mostrar 0 se houver um% al_de T e 1 se houver um alelo C . Meu arquivo é 20805 x 459. Assim deve ser assim:

1   rs6687776   1020428 T   C   0   1   0   1   1   1   0   1   1   1   0   1

Eu tentei:

cat file | while read line
do if [ [,6-] = [,4] ]
then
    echo "0"
    echo "1"
fi
done

Mas acabo com um arquivo alternando 0 e 1 , ou seja, 41610 linhas. Talvez o AWK seja mais útil?

    
por user133375 09.09.2015 / 13:07

3 respostas

6

Aqui está outra abordagem de awk :

$ awk '{a[$4]=0;a[$5]=1; for(i=6;i<=NF;i++){$i=a[$i]}}1;' file
1 rs6687776 1020428 T C 0 1 0 1 1 1 0 1 1 1 0 1

Explicação

  • a[$4]=0;a[$5]=1; : cria a matriz a com duas chaves, $4 e $5 . O valor para $4 está definido como 0 e o valor de $5 para 1.
  • for(i=6;i<=NF;i++){$i=a[$i]} : para cada número de campo de 6 até o último, defina esse campo para o que estiver armazenado na matriz para o nucleotídeo encontrado.

  • 1; : abreviação do atalho para "imprimir esta linha".

Você também pode fazer isso com o Perl:

$ perl -lane 's/$F[3]/0/ for @F[5..$#F]; s/$F[4]/1/ for @F[5..$#F]; print "@F"' file
1 rs6687776 1020428 T C 0 1 0 1 1 1 0 1 1 1 0 1

Esta é a mesma ideia. O -a faz com que perl aja como awk , dividindo cada linha no espaço em branco na matriz @F . Em seguida, substituímos todos os casos do nucleotídeo encontrado no quarto campo ( $F[3] , matrizes começam em 0) com 0 e todos os casos do quinto ( $F[4] ) com 1 . O for @F[5..$#F] significa que a substituição é aplicada apenas nos campos 6 a último. Finalmente, o array modificado é impresso.

    
por 09.09.2015 / 14:11
3

Você pode tentar seguir awk :

awk '{ for (i = 6; i <= NF; i++) { if ($i == $4) { $i = 0; } else if ($i == $5) { $i = 1; } } } 1' file

ou:

awk '{ for (i = 6; i <= NF; i++) { $i = ($i == $4) ? 0 : 1; } } 1' file
    
por 09.09.2015 / 13:15
2

Sempre há mais de uma maneira de fazer isso; sed é o Unix Stream EDitor - é útil para modificar entradas como esta:

while read one two three four five rest
do
  echo $one $two $three $four $five $(echo $rest | sed -e 's/T/0/g' -e 's/C/1/g')
done < input

O sinalizador -e fornece uma expressão para analisar; a função "s" pesquisa e substitui o primeiro parâmetro (T ou C) pelo segundo parâmetro (0 ou 1). Você pode dar várias expressões sed para fazer várias coisas. O resto do loop apenas preserva os primeiros cinco campos.

    
por 09.09.2015 / 13:23