如何用AWK循环遍历列统计匹配次数并计算样本匹配率?
批量计算样本列与Min.alle列的匹配率(AWK实现)
需求说明
处理制表符分隔的基因数据文件,文件从第5列开始的样本列数量无上限。需要统计每行第3列(Min.alle)与每个样本列的字符匹配总次数,再除以数据总行数(排除表头)得到匹配率,最终输出指定格式的结果。
解决方案代码
BEGIN { FS = OFS = "\t" } NR == 1 { # 保存表头的样本列名称,初始化计数数组 sample_id_header = $1 for (i = 5; i <= NF; i++) { sample_names[i] = $i match_counts[i] = 0 } next } { total_data_rows++ current_sample_id = $1 # 遍历所有样本列,统计匹配次数 for (i = 5; i <= NF; i++) { if ($3 == $i) { match_counts[i]++ } } } END { # 输出结果表头 printf "%s", sample_id_header for (i = 5; i <= NF; i++) { printf "%s%s", OFS, sample_names[i] } print "" # 输出分隔线 printf "%s", "----------" for (i = 5; i <= NF; i++) { printf "%s%s", OFS, "---------" } print "" # 输出匹配率结果 printf "%s", current_sample_id for (i = 5; i <= NF; i++) { match_rate = match_counts[i] / total_data_rows printf "%s%.1f", OFS, match_rate } print "" }
代码说明
- BEGIN块:设置输入输出分隔符为制表符,保证文件处理的格式一致性。
- 表头处理:遍历第5列到最后一列,保存每个样本列的名称,同时初始化对应列的匹配计数为0。
- 数据行处理:每处理一行数据,总行数加1;逐个对比当前行
Min.alle列与样本列的字符,匹配则对应计数加1。 - END块:按要求格式输出结果,包括表头、分隔线,以及每个样本的匹配率(匹配次数除以数据总行数,保留1位小数)。
示例输出
针对提供的测试数据,运行代码后会输出:
SampleID Sample1 Sample2 Sample3 ---------- --------- --------- --------- 311 0.4 0.6 0.0
内容的提问来源于stack exchange,提问作者Milos
相关产品推荐
相关产品推荐

