使用awk计算滑动窗口的中位数

问题描述 投票:2回答:2

我需要产生数百万行的滑动窗口并计算第3列的中位数。我的数据看起来像这样,第1列始终是相同的,第2列等于行号,第3列是我需要的信息中位数为:

HiC_scaffold_1  1   34
HiC_scaffold_1  2   34
HiC_scaffold_1  3   36
HiC_scaffold_1  4   37
HiC_scaffold_1  5   38
HiC_scaffold_1  6   39
HiC_scaffold_1  7   40
HiC_scaffold_1  8   40
HiC_scaffold_1  9   40
HiC_scaffold_1  10  41
HiC_scaffold_1  11  41
HiC_scaffold_1  12  41
HiC_scaffold_1  13  44
HiC_scaffold_1  14  44
HiC_scaffold_1  15  55

并且我需要这样的结果,假设滑动窗口为4并四舍五入到最接近的整数。在实际数据集中,我可能会使用1000的滑动窗口:

HiC_scaffold_1  4   35
HiC_scaffold_1  5   37
HiC_scaffold_1  6   38
HiC_scaffold_1  7   39
HiC_scaffold_1  8   40
HiC_scaffold_1  9   40
HiC_scaffold_1  10  40
HiC_scaffold_1  11  41
HiC_scaffold_1  12  41
HiC_scaffold_1  13  41
HiC_scaffold_1  14  43
HiC_scaffold_1  15  44

我发现以下脚本here用于执行我想要的操作,但出于均值而不是中位数:]

awk -v OFS="\t" 'BEGIN {
        window = 4
        slide = 1
}

{
        mod = NR % window
        if (NR <= window) {
                count++
        } else {
                sum -= array[mod]
        }
        sum += $3
        array[mod] = $3
}

(NR % slide) == 0 {
        print $1, NR, sum / count
}
' file.txt

和此脚本用于从here用awk计算中位数:

sort -n -k3 file.txt |
awk '{
        arr[NR] = $3
}

END {
        if (NR % 2 == 1) {
                print arr[(NR + 1) / 2]
        } else {
                print $1 "\t" $2 "\t" (arr[NR / 2] + arr[NR / 2 + 1]) / 2
        }
}
'

但是我无法让他们一起工作。另一个问题是中位数计算需要排序的输入。我也找到了这种datamash解决方案,但我不知道如何使它在滑动窗口中有效地工作。

我需要产生一百万行的滑动窗口并计算第3列的中位数。我的数据看起来像这样,第1列始终是相同的,第2列等于行号,并且...

bash awk median sliding-window
2个回答
1
投票
以下带有GNU awk的脚本似乎会生成您提供的输出:

0
投票
以下使用GNU awk(gawk)。该程序由wsize(窗口大小)参数化-这里是4:
© www.soinside.com 2019 - 2024. All rights reserved.