如何将连续数字折叠成范围并获得平均值

如何将连续数字折叠成范围并获得平均值

我有许多 .txt 文件,其中包含 4 列和数千行的以下信息:

chr10 73121691 18 SLC29A3
chr10 73121692 14 SLC29A3
chr10 73121693 10 SLC29A3
chr10 73120590 15 SLC29A3
chr10 73120591 15 SLC29A3
chr10 73120592 6 SLC29A3
chr10 12345678 25 COL1A1
chr10 12345679 8 COL1A1
chr10 12345680 6 COL1A1
chr17 48431036 5 LRP5
chr17 48431037 8 LRP5
chr17 48431038 5 LRP5

我想要的输出如下:

chr10 73121691 - 73121693 , 14, SLC29A3
chr10 73120590 - 73120592 , 12, SLC29A3
chr10 12345679 - 12345680 , 13, COL1A1
chr17 48431036 - 48431038 , 6, LRP5

连续数字的 chr# 范围、第 3 列的平均值以及与该范围关联的名称。

是否有一个脚本可以用来一次性对多个文件执行此操作?

谢谢

答案1

每个生物信息学家都需要数据整合在他们的工具包中:)

$ datamash -W groupby 1 min 2 max 2 mean 3 unique 4 < tmp/data.txt
chr10   73121691        73121693        14      SLC29A3
chr17   48431036        48431038        6       LRP5

命令行参数中的数字指的是列。因此,我们按第 1 列进行分组,给出第 2 列的最小值和最大值(范围)、第 3 列的平均值以及第 4 列中相应条目的逗号分隔列表。

答案2

这可能是您想要的,具体取决于问题的答案我的评论:

$ cat tst.awk
$2 != (prev[2] + 1) {
    if (NR > 1) {
        prt()
    }
    split($0,beg)
    sum = cnt = 0
}
{
    split($0,prev)
    sum += $3
    cnt++
}
END { prt() }

function prt(   ave) {
    ave = (cnt ? sum / cnt : 0)
    print prev[1], beg[2], "-", prev[2], "," ave ",", prev[4]
}

$ awk -f tst.awk file
chr10 73121691 - 73121693 ,14, SLC29A3
chr10 73120590 - 73120592 ,12, SLC29A3
chr10 12345678 - 12345680 ,13, COL1A1
chr17 48431036 - 48431038 ,6, LRP5

相关内容