unix Команда awk для объединения двух таблиц на основе совпадающих столбцов - PullRequest
2 голосов
/ 07 января 2020

Я пытаюсь объединить две таблицы. Столбец 7 в Таблице A имеет соответствующие записи в Столбце 1 в Таблице B. Я хочу извлечь значения из столбца 3 в TableB и добавить их в соответствующую строку в TableA (основываясь на его значении в столбце 7).

Важно, что некоторые значения появляются несколько раз в столбце 7 TableA, и они все должны получить то же значение, которое было извлечено из таблицы B.

Таблица A имеет 10 столбцов формата:

OTU_8   dbj|AB021887.1| 3.04e-84    100.000 315 0   AB021887
OTU_142 dbj|AB021887.1| 5.05e-82    99.412  307 0   AB021887
OTU_124 gb|AF156149.1|  4.97e-25    76.106  119 0   AF156149
OTU_145 gb|AF156149.1|  2.28e-33    78.319  147 0   AF156149
OTU_27  gb|AF156151.1|  2.36e-18    84.000  97.1    0   AF156151

В TableB четыре столбца:

AB021887        AB021887.1      7936    12248848
AF156149        AF156149.1      114741  7682414
AF156151        AF156151.1      114754  7682418
AP014556        AP014556.1      62819   1237088233
AP017673        AP017673.1      29170   1089667374
AP017981        AP017981.1      1450757 1148885259
AW360743        AW360743.1      10090   6865393

I пробовал следующую команду:

awk 'NR==FNR{a[$7]=$0; next} ($1 in a) {print a[$1],$3}' TableA TableB > TableC

Однако он игнорирует дубликаты в таблице A и вместо

OTU_8   dbj|AB021887.1| 3.04e-84    100.000 315 0   AB021887      7936
OTU_142 dbj|AB021887.1| 5.05e-82    99.412  307 0   AB021887      7936
OTU_124 gb|AF156149.1|  4.97e-25    76.106  119 0   AF156149      114741
OTU_145 gb|AF156149.1|  2.28e-33    78.319  147 0   AF156149      114741
OTU_27  gb|AF156151.1|  2.36e-18    84.000  97.1    0   AF156151      114754

я получаю только

OTU_8   dbj|AB021887.1| 3.04e-84    100.000 315 0   AB021887      7936
OTU_124 gb|AF156149.1|  4.97e-25    76.106  119 0   AF156149      114741
OTU_27  gb|AF156151.1|  2.36e-18    84.000  97.1    0   AF156151      114754

Я был бы очень признателен любая помощь.

Ответы [ 2 ]

3 голосов
/ 07 января 2020

a[$7]=$0; next просто запоминает последнее значение для $7 и перезаписывает любое предыдущее значение. Вы можете исправить это, изменив отношения (если, конечно, у вас нет дубликатов в другом файле).

awk 'NR==FNR{a[$1]=$3; next} ($7 in a) {print $0, a[$7]}' TableB TableA > TableC
2 голосов
/ 07 января 2020

Я бы использовал join для этого:

join -1 7 -o 1.1,1.2,1.3,1.4,1.5,1.6,1.7,2.3 <(sort tableA -k7) <(sort tableB -k1)

Не забудьте отсортировать входные файлы, опция -1 7 делает соединение на седьмом поле таблицы A, опция -o упорядочивает выходные столбцы

Выходные данные:

OTU_142 dbj|AB021887.1| 5.05e-82 99.412 307 0 AB021887 7936
OTU_8 dbj|AB021887.1| 3.04e-84 100.000 315 0 AB021887 7936
OTU_124 gb|AF156149.1| 4.97e-25 76.106 119 0 AF156149 114741
OTU_145 gb|AF156149.1| 2.28e-33 78.319 147 0 AF156149 114741
OTU_27 gb|AF156151.1| 2.36e-18 84.000 97.1 0 AF156151 114754
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...