2行ごとに合計を計算し、その合計が特定の値より小さい場合は、他の値に置き換えます。

2行ごとに合計を計算し、その合計が特定の値より小さい場合は、他の値に置き換えます。

200万行と12列の遺伝子型行列(テーブルスペースを含む)があります。列は個人で、行はSNPです。 1人あたりのSNPごとに2行あります。 1つは参照対立遺伝子の数、もう1つは代替対立遺伝子の数です(2行ごとにSNPに対応します。つまり、行1と2はSNP 1、行3と4に対応することを意味します)。 SNP2に対応し、5行と6行はSNP 3)に対応します。

以下は例です(2つのSNPと8人の個人)。

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  

各SNPについて、参照対立遺伝子と代替対立遺伝子の合計が20未満であれば、両方の対立遺伝子を0に変え、20以上であれば維持したい。これが私が望む出力です

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  

これを正確に行う方法を知っていますか?

答え1

アイデアは、2つの配列に連続した行を格納し、そのインデックスに基づいて配列要素を比較することです。

"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
}

その後実行

awk -f twenty.awk data.file | column -t > data.file.twenty

関連情報