awk: суммировать таблицу по первому полю и объединять последующие столбцы - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть следующая таблица:

id1 0720f5eb2d611dc66e0e9941d516961f    193 PANTHER PTHR34107       7   187 9.50E-16    T   01.02.19                
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302:SF0       2   119 7.00E-42    T   01.02.19    IPR011344   Single-stranded DNA-binding protein GO:0003697|GO:0006260   Reactome: R-HSA-2151201
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302       2   119 7.00E-42    T   01.02.19    IPR000424   Primosome PriB/single-strand DNA-binding    GO:0003697  Reactome: R-HSA-2151201

Она состоит из 16 столбцов и разделена табуляцией.

Теперь я хочу объединить эту таблицу следующим образом:

  1. Суммировать по первому столбцу
  2. Объединить столбцы так, чтобы одинаковые поля каждого id из исходной таблицы были разделены на ;
* 1015Поэтому мой желаемый результат будет таким:
id2 PTHR10302:SF0; PTHR10302        2-119; 2-119    7.0E-42; 7.0E-42    T; T    IPR011344; IPR000424    Single-stranded DNA-binding protein; Primosome PriB/single-strand DNA-binding
id1     PTHR34107       7-187   9.5E-16 T

Столбцы 2, 3, 4 и 10 можно опустить.Столбцы 7 и 8 объединяются с помощью -.

. Я мог бы решить 1. с помощью этой команды:

awk 'BEGIN{FS=OFS="\t"}{unique[$1]=(unique[$1] FS $5 FS $6 FS $7 "-" $8 FS $9 FS $10 FS $12 FS $13); next}END{for (i in unique) print i,unique[i]}'

, которая суммируется по id, но не объединяет поля:

id2     PTHR10302:SF0       2-119   7.0E-42 T   IPR011344   Single-stranded DNA-binding protein PTHR10302       2-119   7.0E-42 T   IPR000424   Primosome PriB/single-strand DNA-binding
id1     PTHR34107       7-187   9.5E-16 T

Но как мне сделать 2.?

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Как упоминал @tripleee, Perl сделает это.Проверьте это

$ cat rororo.txt
id1 0720f5eb2d611dc66e0e9941d516961f    193 PANTHER PTHR34107       7   187 9.50E-16    T   01.02.19
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302:SF0       2   119 7.00E-42    T   01.02.19    IPR011344   Single-stranded DNA-binding protein GO:0003697|GO:0006260   Reactome: R-HSA-2151201
id2 32912bc00b9b84f6b06600aff56cef8f    138 PANTHER PTHR10302       2   119 7.00E-42    T   01.02.19    IPR000424   Primosome PriB/single-strand DNA-binding    GO:0003697  Reactome: R-HSA-2151201

$ ./join_tab.pl rororo.txt
id2 PTHR10302:SF0;PTHR10302     2-119;2-119     7.00E-42;7.00E-42       T;T     IPR011344;IPR000424     Single-stranded DNA-binding;Primosome PriB/single-strand
id1 PTHR34107   7-187   9.50E-16        T

$

Сценарий:

$ cat ./join_tab.pl
perl -lane '
$id=$F[0];
$fs="$F[5]-$F[6]";
$f11="$F[11] $F[12]";
@t4 = @{$kv1{$id}}; push(@t4,$F[4]); $kv1{$id}=[@t4];
@t56 = @{$kv2{$id}}; push(@t56,$fs); $kv2{$id}=[@t56];
@t7 = @{$kv3{$id}}; push(@t7,$F[7]); $kv3{$id}=[@t7];
@t8 = @{$kv4{$id}}; push(@t8,$F[8]); $kv4{$id}=[@t8];
@t10 = @{$kv5{$id}}; push(@t10,$F[10]); $kv5{$id}=[@t10];
@t11 = @{$kv6{$id}}; push(@t11,$f11); $kv6{$id}=[@t11];
END {
while( ($x,$y) = each(%kv1))
{
 @t4=@{$kv1{$x}};  @t56=@{$kv2{$x}};
 @t7 = @{$kv3{$x}};  @t8 = @{$kv4{$x}};
 @t10 = @{$kv5{$x}};  @t11 = @{$kv6{$x}};
 print "$x ", join(";",@t4), "\t",join(";",@t56), "\t",join(";",@t7),"\t",join(";",@t8),"\t",join(";",@t10),"\t",join(";",@t11)   ;
}

} ' $1
$
0 голосов
/ 02 февраля 2019

Это не просто, но возможно.

Во-первых, вам нужны два массива.Один из них - массив 'ids' , а другой - массив 'data' .

Для каждой строки необходимо обновить массив 'ids' (поэтомуон будет содержать все возможные идентификаторы):

  ids[$1] = [$1]

Затем в массиве 'data' вы должны хранить сцепленные данные.Индексы этого массива будут «поддельными» многомерными:

  data[$1,5] = data[$1,5] ? data[$1,5] "; " $5 : $5
  data[$1,6] = data[$1,6] ? data[$1,6] "; " $6 : $6
  data[$1,78] = data[$1,78] ? data[$1,78] "; " $7 "-" $8 : $7 "-" $8
  data[$1,9] = data[$1,9] ? data[$1,9] "; " $9 : $9
  data[$1,10] = data[$1,10] ? data[$1,10] "; " $10 : $10
  data[$1,12] = data[$1,12] ? data[$1,12] "; " $12 : $12
  data[$1,13] = data[$1,13] ? data[$1,13] "; " $13 : $13

В блоке 'END' вы должны выполнить итерацию массива 'ids' , но принятьзначения из 'data' array:

END {
  for (i in ids)
    print i, data[i,$5], data[i,$6], data[i,$78], data[i,$9], data[i,$10], data[i,$12], data[i,$13]
}

PS: если вы используете более новые версии gawk , есть более простой способ получить результат, потому что эти версии поддерживаютистинные многомерные массивы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...