compute soma cada 2 linhas e as substitui por outro valor se a soma for menor que um valor específico

2

Eu tenho uma matriz genotípica (com espaço tabular), com 2 milhões de linhas e 12 colunas. Colunas são indivíduos e as linhas são SNPs. Eu tenho 2 linhas por cada SNP para cada indivíduo, um é o número de alelo de referência e o outro número de alelo alternativo (cada 2 linhas correspondem a um SNP, o que significa que as linhas 1 e 2 correspondem a SNP 1, linhas 3 e 4 correspondem a SNP2, linhas 5 e 6 correspondem a SNP 3).

Este é um exemplo, (2 SNPs e 8 indivíduos):

head genotype
2   3   1   0   0   3   5   3       
18  15  19  18  16  15  13  17      
2   1   0   0   0   1   1   1           
18  19  18  16  20  17  17  23  

Para cada SNP se a soma de alelo de referência e alternativa for menor que 20, eu quero substituir ambos os alelos por 0 e, se forem iguais ou maiores que 20, quero mantê-los. Esta é minha saída desejada

head (desired_output)
    2   0   1   0   0   0   0   3       
    18  0   19  0   0   0   0   17      
    2   1   0   0   0   0   0   1           
    18  19  0   0   20  0   0   23  

Alguma ideia de como fazer isso com precisão?

    
por Anna1364 08.12.2017 / 20:05

1 resposta

1

A idéia é salvar linhas consecutivas em duas matrizes e comparar os elementos da matriz pelos índices correspondentes.

Salve isso em um arquivo, diga "twenty.awk"

#/usr/bin/env awk

# ref https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html
function join(array, start, end, sep,    result, i)
{
    if (sep == "")
        sep = " "
    else if (sep == SUBSEP) # magic value
        sep = ""
    result = array[start]
    for (i = start + 1; i <= end; i++)
        result = result sep array[i]
    return result
}

{
    split($0, a)
    getline

    for (i=1; i<=NF; i++)
        if (a[i] + $i < 20)
            a[i] = $i = 0

    print join(a, 1, NF)
    print
}

Em seguida, execute com

awk -f twenty.awk data.file | column -t > data.file.twenty
    
por 08.12.2017 / 20:31