AWK实现按连续坐标合并行并计算列均值的技术求助
解决AWK按连续坐标序列合并行并计算平均值的问题
我懂你的需求——要按第2列里连续递增1的坐标序列分组,把每组合并成「起始坐标-结束坐标」的格式,同时算出该组第3列的平均值,而不是像之前的脚本那样,把同一标识符(第4列)的所有行都合并成一个大区间。之前的脚本没处理连续序列的判断逻辑,我给你写个能精准实现需求的AWK脚本:
awk -F'\t' -v OFS='\t' ' BEGIN { prev_chr = "" prev_pos = -1 prev_id = "" sum = 0 count = 0 start_pos = 0 } { # 当标识符变化,或当前坐标和前一个不连续时,输出上一组数据 if ($4 != prev_id || $2 != prev_pos + 1) { if (count > 0) { print prev_chr, start_pos, prev_pos, sum / count, prev_id } # 重置当前组的跟踪变量 prev_chr = $1 start_pos = $2 prev_pos = $2 prev_id = $4 sum = $3 count = 1 } else { # 属于同一连续组,累加数据 prev_pos = $2 sum += $3 count++ } } END { # 处理最后一组未输出的数据 if (count > 0) { print prev_chr, start_pos, prev_pos, sum / count, prev_id } }' input | sort -V -k1,1 > output
脚本逻辑拆解
- 初始化变量:
BEGIN块里先把跟踪前一行信息、当前组起始坐标、总和、计数的变量都初始化好 - 分组判断:每一行先检查是否和前一行属于同一标识符,且坐标是连续递增1的;如果不满足,就输出上一组的结果,然后重置当前组的变量
- 累加数据:如果属于同一连续组,就更新当前组的结束坐标、总和和计数
- 收尾处理:
END块里输出最后一个还没处理的组
输入输出验证
输入(input):
chr12 9079811 29 A2M chr12 9079812 29 A2M chr12 9079813 29 A2M chr12 9079814 28 A2M chr12 9091202 5 A2M chr12 9091203 5 A2M chr12 9091204 5 A2M chr12 9091390 15 A2M chr12 9091391 15 A2M chr12 9091392 13 A2M
输出(output):
chr12 9079811 9079814 28.75 A2M chr12 9091202 9091204 5 A2M chr12 9091390 9091392 14.3333 A2M
(如果想要和你示例里一致的1位小数,可以把sum/count改成printf("%.1f", sum/count)来调整格式)
内容的提问来源于stack exchange,提问作者Vonton
相关产品推荐
相关产品推荐

