Awk - Compare o valor de uma coluna com uma variável, conte quantas vezes ela passa para cada ID

0

Estou tentando encontrar uma solução, mas agora preciso de ajuda.

Primeiro, como entrada, eu tenho um arquivo grande (5.5G) com essa estrutura:

scaffold4691_size302    2       T       1
scaffold4691_size302    3       A       1
scaffold4691_size302    4       a       1
scaffold4691_size302    5       a       1
scaffold4691_size302    6       g       2
scaffold4691_size302    7       c       2
scaffold4691_size302    8       c       2
scaffold4692_size187    68      g       4
scaffold4692_size187    69      c       4
scaffold4692_size187    70      a       4
scaffold4692_size187    71      a       4

O que eu quero é contar para cada ID da PRIMEIRA coluna ($ 1), quantas vezes o valor na QUARTA coluna ($ 4) é maior ou igual a X (por exemplo, X = 4 no modelo de brinquedo).

Então, como entrada, espero:

scaffold4691_size302    0
scaffold4691_size187    4

Eu poderia facilmente fazê-lo em python, pois estou mais confortável com ele, mas o tamanho é muito grande.

Até agora, fiz isso:

awk 'NR>1 { scf=$1; { if ($4>=4){count++;}}} {print scf "\t" count}' toyModel

Mas isso me devolve toda a linha e uma contagem total. Quero saber como atualizar a contagem para um novo ID.

    
por dilution 14.03.2017 / 17:13

2 respostas

3

Você precisa acumular as contagens por id e imprimir o resultado depois de processar o arquivo:

awk '!counts[$1] { counts[$1] = 0 }; $4 >= 4 { counts[$1]++ }; END { for (key in counts) print key, counts[key] }' toyModel

A primeira declaração garante que medimos os ids que nunca correspondem ao critério (terminando com 0 output). O segundo incrementa a contagem de linhas correspondentes. A última declaração itera sobre as chaves (ids) e imprime a contagem de chaves e correspondência.

Se o tamanho for muito grande para essa abordagem (a matriz counts ficar muito grande) e seus IDs forem contíguos no arquivo, você poderá usar essa abordagem:

awk 'curid != $1 { if (NR > 1) print curid, count; curid = $1; count = 0 }; $4 >= 4 { count++ }; END { print curid, count }' toyModel

Isso mantém o ID e a contagem atuais e os imprime sempre que o ID muda (e no final). Sempre que o quarto campo for maior que 4, a contagem será incrementada e, sempre que o ID for alterado, a contagem será redefinida.

    
por 14.03.2017 / 17:18
0
perl -lane '$h{$F[0]} += $F[3] >= 4 ? 1 : 0}{print "$_\t$h{$_}" for keys %h' toyModel
    
por 14.03.2017 / 17:58