awk para consolidar um arquivo tabular grande?

1

Eu tenho um arquivo com 21 campos tabulares em colunas. As abas 14 e 15 são conjuntos de dados que são repetidos várias vezes para variáveis na aba 10 (até ":") e a aba 11 tem dados numéricos descritivos para a aba 10.

Veja um exemplo da entrada:

399 3   0   0   0   0   0   0   -   chromosome_1_Contig0.1980:10701-11103   402 0   402 gi|952977790|ref|NM_001317128.1|    849 447 849 1   402 0   447
281 0   0   0   0   0   0   0   -   chromosome_1_Contig0.1980:11209-11490   281 0   281 gi|952977790|ref|NM_001317128.1|    849 166 447 1   281 0   166
166 0   0   0   0   0   0   0   -   chromosome_1_Contig0.1980:11588-11754   166 0   166 gi|952977790|ref|NM_001317128.1|    849 0   166 1   166 0   0
51  0   0   0   0   0   0   0   +   chromosome_1_Contig0.3916:1547-1598 51  0   51  gi|733214878|ref|NM_001303082.1|    708 0   51  1   51  0   0
132 0   0   0   0   0   0   0   +   chromosome_1_Contig0.3916:3201-3333 132 0   132 gi|733214878|ref|NM_001303082.1|    708 282 414 1   132 0   282
294 0   0   0   0   0   0   0   +   chromosome_1_Contig0.3916:3412-3706 294 0   294 gi|733214878|ref|NM_001303082.1|    708 414 708 1   294 0   414
103 4   0   0   0   0   0   0   +   chromosome_1_unplaced_Contig0.3951:379-486  107 0   107 gi|526117967|ref|NM_001281232.1|    1518    1236    1343    1   107 0   1236
212 1   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12366:214-427 213 0   213 gi|526117831|ref|NM_001281196.1|    1025    738 951 1   213 0   738
178 2   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12366:633-813 180 0   180 gi|526117831|ref|NM_001281196.1|    1025    558 738 1   180 0   558
243 1   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12366:909-1153    244 0   244 gi|526117831|ref|NM_001281196.1|    1025    314 558 1   244 0   314
313 1   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12504:1668-1887   314 0   314 gi|526117831|ref|NM_001281196.1|    1025    0   314 1   314 0   0

Gostaria de obter um novo arquivo tabular resumido a partir do qual;

para linhas nas quais os valores nas guias 10 até ":" e 14 são os mesmos em uma nova linha, a guia 11 é somada para essa combinação. Gostaria de manter as linhas nas quais essas combinações aparecem apenas uma vez. Isso me dá três novas guias resumidas. Então eu gostaria de incluir a aba anterior 15 e em uma nova aba a diferença entre a nova aba 3 e a antiga aba 15. A saída deve ficar assim:

Exemplo de saída

:

old_tab_10  old_tab_14  sumof_old_tab11 old_tab15   (old_tab15)-(sumof_old_tab11)
chromosome_1_Contig0.1980   gi|952977790|ref|NM_001317128.1|    849 849 0
chromosome_1_Contig0.3916   gi|733214878|ref|NM_001303082.1|    477 708 231
chromosome_1_unplaced_Contig0.3951  gi|526117967|ref|NM_001281232.1|    107 1518    1411
chromosome_1_unplaced_Contig0.12366 gi|526117831|ref|NM_001281196.1|    637 1025    388
chromosome_1_unplaced_Contig0.12504 gi|526117831|ref|NM_001281196.1|    314 1025    711

Eu comecei a brincar com algo nas linhas de

awk '{S[$14]+=$11;N[$14]+} END{for(i in S){print i, N[i]}}' 

então percebi que isso está muito fora das minhas capacidades, eu nem sei como separar os campos para as duas guias e ":" e se isso é uma boa ideia ou se seria melhor usar uma abordagem diferente para separar o ":".

    
por hatziiod 04.07.2016 / 16:02

3 respostas

1

Você pode usar split para extrair as duas partes do campo 10 em uma matriz (aqui chamada arr10 ) assim:

split($10, arr10, ":")

Em seguida, você pode criar um índice a partir de uma combinação do primeiro elemento desse array e de todo o elemento 14. Usando esse índice, você pode criar dois novos arrays, por exemplo, sum_of_11 e old_15 :

sum_of_11[arr10[1]"\t"$14] += $11 # sum of all rows that have this index
old_15[arr10[1]"\t"$14] = $15     # just the value in the single most recent row

Juntando (e definindo OFS = "\t" ):

awk '{ split($10, arr10, ":");
       sum_of_11[arr10[1]"\t"$14] += $11;
       old_15[arr10[1]"\t"$14] = $15
     } END {
       OFS = "\t";
       for (i in sum_of_11) {
         print i, sum_of_11[i], old_15[i], old_15[i] - sum_of_11[i]
       }
     }' file

Resultado:

chromosome_1_Contig0.3916   gi|733214878|ref|NM_001303082.1|    477 708 231
chromosome_1_unplaced_Contig0.12366 gi|526117831|ref|NM_001281196.1|    637 1025    388
chromosome_1_unplaced_Contig0.3951  gi|526117967|ref|NM_001281232.1|    107 1518    1411
chromosome_1_unplaced_Contig0.12504 gi|526117831|ref|NM_001281196.1|    314 1025    711
chromosome_1_Contig0.1980   gi|952977790|ref|NM_001317128.1|    849 849 0
    
por 05.07.2016 / 11:47
0

Na verdade, você está no caminho certo. No entanto, você precisa usar o campo dez como um índice para sua estrutura de dados:

awk '{data[$10] = $14} END { for (d in data) print d " " data[d]; }'

Se você precisar distinguir vários campos, use algo como

data[$10, "14"] = "x"; data[$10, "11"] = "y"
    
por 05.07.2016 / 11:12
0

usando como arquivo awk

 { split($10,A,":") ;
  B[A[1]]=$14 ; C[A[1]] += $11  }
 END { for ( a in B ) printf "%s\t%s\t%d\n",a,B[a],C[a] ;}

chromosome_1_unplaced_Contig0.12366 gi|526117831|ref|NM_001281196.1|        637
chromosome_1_unplaced_Contig0.12504 gi|526117831|ref|NM_001281196.1|        314
chromosome_1_unplaced_Contig0.3951  gi|526117967|ref|NM_001281232.1|        107
chromosome_1_Contig0.1980   gi|952977790|ref|NM_001317128.1|        849
chromosome_1_Contig0.3916   gi|733214878|ref|NM_001303082.1|        477

Eu não sabia quieto sobre outros requisitos. no entanto

  • split($10,A,":") irá dividir o 10º campo na matriz A, de acordo com ":"
  • B[A[1]]=$14 ; é bastante simples

o arquivo de programa é chamado usando

awk -f se.awk data
    
por 05.07.2016 / 11:42