I have a file that looks like this:

chr pos value
A   1   23
A   2   32
A   200 32
B   1   41
B   2   28

The file is sorted by chr and pos. The ... is just to show the lots of rows in between. My aim is to compute median of the value column within pos window size of n and within the same chr groups.

This is the expected output for window size 10 (n=10).

chr start end median
A   1     10  21
A   11    20  35
A   191   200 26
B   1     10  34
B   11    20  28

This is the code I have for computing mean over window size 10 for column 4.

cat file | awk '{sum+=$4} (NR%10)==0{print sum/10; sum=0;}'

But median is bit more complicated as it involves sorting values within the window size and picking the middle value.

cat file | sort -n | awk ' { a[i++]=$1; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'

I am not sure how to bring this all together. Specifically, how to sort within window-size inside awk.

The last part is to limit all calculations within chr groups (ie; calculations need to reset when new group begins.). My simplistic solution to this was to split the file into sub files for A,B,C and D. Not ideal when there are too many groups.

  • 1
    Have you considered using non-awk approachs, such as using the --filter option of GNU split with (say) GNU datamash for the stats? e.g. split -l 10 --filter='datamash -g 1 min 2 median 3' data – steeldriver Feb 15 at 14:06
  • @rmf, You'll need to show more data so we can have some input to work with. – glenn jackman Feb 15 at 17:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.