【发布时间】:2020-07-05 00:31:06
【问题描述】:
我需要生成一个包含数百万行的滑动窗口并计算第 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 行被忽略了?
-
datamash 很棒,但它没有窗口;全有或全无。
-
输出从第 4 行开始,因为第 4 行是可以生成滑动窗口 4 的第一行。最后的中位数是最后一行和前三行的中位数。
标签: bash awk median sliding-window