Мне нужно создать скользящее окно из миллионов строк и рассчитать медиану столбца 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
Я нашел следующий скрипт здесь для того, что я хочу, но для среднего значения, а не для медианы:
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
и этот скрипт для вычисления медианы с помощью 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
}
}
'
, но я не могу заставить их работать вместе. Еще одна проблема заключается в том, что медианный расчет требует отсортированного ввода. Я также нашел это решение datama sh, но я не знаю, как заставить работать эффективно с помощью скользящего окна.