Сопоставление значений в полях и присвоение им идентификатора на основе сопоставления

chr:pos1:pos2   Sun     NC      S1      S2      S3      S4      S9      S11     S14     S15     S16     S17     S18     S19     S28     S29     S30     S33     S34     S35     S36     S37     S38     S39
Aradu.A01:100145549:100145556   AG      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA      AA
Aradu.A01:100408119:100408137   CA      TA      0       0       0       TA      TA      TA      TA      TA      TA      TA      TA      TA      TA      TA      TA      TA      TA      TA      TA      0
Aradu.A01:10102206:10102212     TG      TA      TA      TA      TA      0       TG      TA      TA      TA      TG      TG      TG      TG      TG      TA      TG      TG      TA      0       TG      TG
Aradu.A01:10112010:10112029     GA      GG      GG      GG      GG      GG      GA      GG      GG      GG      GA      0       GA      GA      GA      GG      GA      GA      GG      GA      0       GA
Aradu.A01:10112029:10112059     AC      GC      GC      GC      GC      GC      AC      GC      GC      GC      AC      0       AC      AC      AC      GC      AC      0       GC      AC      0       AC
Aradu.A01:101198026:101198058   GT      GC      GC      GC      GT      GC      0       GT      GT      GC      GT      GT      GT      0       GT      GC      GT      GC      GC      GT      0       GT
Aradu.A01:101198058:101198081   TC      CC      CC      CC      TC      CC      0       TC      TC      CC      TC      TC      TC      0       TC      CC      TC      CC      CC      TC      0       TC
Aradu.A01:101306922:101306946   AG      AA      AA      AA      AG      0       AA      AG      AG      AA      0       AG      AG      AG      AG      AA      AG      AG      AA      AG      AG      AG

В данном файле я пытаюсь сопоставить значения во всех полях столбца 4 и далее со столбцами 2 и 3. Если значение поля (столбец 4 и далее) совпадает с полем столбца 2, пометьте его как S , если он соответствует столбцу 3, пометьте его как N, а если он равен 0, присвойте ему -1.

Я попробовал следующее:

NR>1  {for(i=4;i<=NF;i++)
        { if ( $i == $2 ) $i=S ;
          if ( $i == $3 ) $i=N ;
          if ( $i == 0 ) $i=-1 ;
       } ## if ;
       ## for loop is done
       print ;
       }

В результате всем полям, кроме первых 3, присвоено значение -1.

0
05.05.2017, 09:29
2 ответа

Похоже, это работает:

NR > 1 {
  for( i=4; i<NF; i++) {
    if( $i == $2 ) {
      $i = "S"
    }
    else if( $i == $3 ) {
      $i = "N"
    }
    else if( $i == 0 ) {
      $i = -1
    }
  }
  print
}

Поместите это в файл с именем e. г. 363142.awk и запустите:

$ awk -f 363142.awk /path/to/input
0
28.01.2020, 04:46
perl -F\\s+ -pale '
   $. > 1 and /(?:\S+\s+){3}/g and
   s{\G(\S+)(\s*)}
   {
      ($1 eq $F[1] ? "S" : $1 eq $F[2] ? "N" : $1 eq "0" ? -1 : $1) . $2
   }cge;
' your_genes_file

Опции

  • -F\\s+ зададут для FS один или несколько пробелов => /\s+/
  • - p установит неявное чтение файла в цикле, И печать будет автоматической.
  • -a разделяет каждую запись заново на основе разделителя поля, предоставленного параметром -F, или одиночного пробела по умолчанию. Поля хранятся в массиве @F.
  • -l установит ORS=RS=\n
  • -e — код Perl, применяемый к каждой записи.

Объяснение

Мы пропускаем первую строку из обработки. Опция -p позаботится о его печати. Затем мы размещаем маркер нашего движка регулярных выражений в начале 4-го поля, так как именно здесь должны начинаться все действия. Затем применяем команду s/// в режимах global, cumulative и eval. /c => маркер регулярного выражения начнется с того места, где он был припаркован в последней команде m//g, а НЕ с начала. /g => просматривает всю строку для ее преобразования, а /e просматривает секцию замены s//repl/ как Perl код, который нужно выполнить, и его результаты помещаются в секцию замены.

GNU sed

Это можно написать в POSIX sed, но тогда код будет мешать ясности, и его оставят в качестве умеренного упражнения.

sed -e '
   1b

   # fence the column 2 and go looking for col2 matching fields from col 4 onwards
   s/\S\+/\n&\n/2
   :c2
   s/\(\n\(.*\)\n\s\+\S\+\s.*\)\<\2\>/\1S/g;tc2
   s/\n//g

   # fence the column 3 and go looking for col3 matching fields from col 4 onwards
   s/\S\+/\n&\n/3
   :c3
   s/\(\n\(.*\)\n.*\)\<\2\>/\1N/g;tc3
   s/\n//

   # from col 4 onwards look for any lone 0s and change them to -1
   :zm1
   s/\(\n.*\)\<0\>/\1-1/;tzm1
   s/\n//

' gene_file.dat

Perl

Здесь мы удаляем все начальные пробелы, которые будут мешать индексации массива @F, а затем восстанавливаем их во время печати данных. В map мы передаем элементы с 6 и далее (4+2 для пробелов) и просто проверяем, равны ли они 2-му/3-му столбцам или 0.

perl -F'(\s+)' -lane '
   print,next if $. == 1;
   my $dummy = splice @F, 0, 2 if /^\h/;
   print $dummy, @F[0..5], map {
      s/^\Q$F[2]\E$/S/ or s/^\Q$F[4]\E$/N/ or s/^0$/-1/; $_
   } @F[6 .. $#F];
' gene_file.dat
0
28.01.2020, 04:46

Теги

Похожие вопросы