Contando valores entre dois valores definidos por duas colunas

Contando valores entre dois valores definidos por duas colunas

Eu tenho dados armazenados em três colunas como esta:

3651 3631 3913
3667 3996 4276
3674 4486 4605
3707 4706 5095
3720 5174 5326
3750 5439 5899
3755 5928 6263
3767 6437 7069
3779 7157 7232
3882 7384 7450
3886 7564 7649
3900 7762 7835
4006 7942 7987
4015 8236 8325
4026 8417 8464
4065 8571 8737
4156 6790 7069
4493 7157 7450
4541 7564 7649
4551 7762 7835
4597 7942 7987
4756 8236 8325
4776 8417 8464

onde a 1ª coluna é um valor específico, a 2ª coluna é o início e a 3ª coluna é o fim. Existem 825.849 linhas na 1ª coluna e 58.386 na 2ª e 3ª. Preciso contar valores a partir do 1º se estiverem entre o início e o fim.

Eu sei que no meu arquivo os primeiros 12 valores específicos da coluna nº 1 estão entre o primeiro início e o fim, os próximos 5 estão entre o segundo início e o fim e assim por diante. Preciso verificar o arquivo inteiro. Eu tentei com isso e funciona, mas muito lento:

coords='final_exons.txt'

snp=( $( cat $coords | awk '{print $1}') )
exon_start=( $( cat $coords | awk '{print $2}') )
exon_end=( $( cat $coords | awk '{print $3}') )

i=0
counter=0
for value in ${exon_end[@]}; do
    new_val=$counter
    counter=0
    let "i++"
    for snps in ${snp[@]}; do

        if [[ $value > $snps ]]; then
            #statements
            let "counter++"
            #$counter=$(echo "scale=2; $counter-$new_val" | bc)
        else
            #$new_val=$(echo "scale=2; $counter-$")
            break
        fi
    done
    #echo "NOWENOWE $new_val "
    #echo "COUNTER $value : $counter "
    final=$(echo "scale=2; sqrt(($counter-$new_val)^2)" | bc)
    echo "Exon $i : $final SNPs"
done

Agradecemos antecipadamente por quaisquer dicas e sugestões

link para dados completos

Responder1

  1. Coloque cada valor em uma linha, mas marque "início" e "fim" anexando-os Sou E. Agora classifique os valores numericamente. Você obteria algo como
3631S
3651
3667
...
3900
3913E
3996S
4006
...
  1. Conte as ocorrências entre a Se um Evalor finalizado.

Escreva o roteiro e seja feliz!

awk '
    {print $1} 
    $3!="" {print $2"S"; print $3"E"} 
' final_exons.txt | sort -n | awk '
    !/E|S/ {count++; next}
    /S/ {count=0; next}
    /E/ {print line++": "count}'

A primeira awke sortexecute o passo 1. Há um $3!=""teste (também pode ser $2!="") porque há mais linhas na 1ª coluna do que na 2ª ou 3ª.

O segundo awkcorresponde ao passo 2. Ele zera o contador se ler linhas com S, incrementa se a linha não tiver marcador e o imprime (junto com o número da linha) se ler a linha com E.

A saída quando executada no arquivo de amostra fornecido é 0: 12; 1: 5; 2: 4; 3: 2; ...; 22: 0.

Responder2

Eu poderia usar um awk:

awk '{if( ($1 > $2) && ($1 < $3) ){print NR" "$1" "$2" "$3}}' final_exons.txt

Mas se col1 e (col2 e col3) forem tratados separadamente, é melhor separá-los em arquivos separados. Ou coloque os dados no banco de dados e faça o teste de intervalo dentro dele. Mas a maneira mais eficiente seria carregar os dados no array regular e os loops de teste serem realizados em alguma outra linguagem de script (php, python, perl ...)

informação relacionada