如何将BAM文件样本名映射到注释文件的Tumor_Sample_Barcode列?
问题:生物信息学流程中注释文件样本列填充错误
问题描述
我有一个两步生物信息学流程:
- 步骤1(代码1)生成
.marked.bam格式的输出文件,并按目录结构存储。 - 步骤2(代码2)处理下游生成的注释文件
annotated.hg38_multianno.txt,需要将对应样本名填充到文件的Tumor_Sample_Barcode列中。
当前Tumor_Sample_Barcode列未正确填充,显示的是占位值(比如annovar_output),而不是从.marked.bam文件名中提取的真实样本名。
目标
将annotated.hg38_multianno.txt文件的Tumor_Sample_Barcode列,替换为从代码1生成的.marked.bam文件名中提取的正确样本名(样本名取自*.marked.bam的*部分,例如Sample1.marked.bam对应的样本名为Sample1)。
示例输入
样本列表
Sample1,Polyp Sample2,Normal Sample3,Polyp
BAM文件
Sample1.marked.bam Sample2.marked.bam Sample3.marked.bam
期望输出
每个annotated.hg38_multianno.txt文件的Tumor_Sample_Barcode列应填入对应样本名,示例如下:
| Column A | Column B | Tumor_Sample_Barcode |
|---|---|---|
| Cell 1 | Cell 2 | Sample1 |
| Cell 3 | Cell 4 | Sample2 |
当前使用的代码
代码1:生成.marked.bam文件
# 从.marked.bam文件中提取样本名 for bam_file in "$OUTPUT_DIR"/*.marked.bam; do sample_name=$(basename "$bam_file" | sed 's/\.marked\.bam$//') echo "处理样本的BAM文件: $sample_name" # 处理并生成每个样本的注释文件... done
代码2:处理注释文件
# 遍历每个注释文件,从其父目录提取样本名 for ANNOTATED_FILE in $(find "$ANNOVAR_OUTPUT_DIR" -name "annotated.hg38_multianno.txt"); do SAMPLE_NAME=$(basename "$(dirname "$ANNOTATED_FILE")") # 填充"Tumor_Sample_Barcode"列 awk -v OFS='\t' -v sample_name="$SAMPLE_NAME" ' NR == 1 { # 列不存在则添加 col = -1 for (i = 1; i <= NF; i++) if ($i == "Tumor_Sample_Barcode") col = i if (col == -1) { print $0, "Tumor_Sample_Barcode" col = NF + 1 } else { print $0 } } NR > 1 { $col = sample_name print $0 } ' "$ANNOTATED_FILE" > "${ANNOTATED_FILE}.temp" mv "${ANNOTATED_FILE}.temp" "$ANNOTATED_FILE" done
解决方案
问题出在代码2的样本名提取逻辑:当前从注释文件的父目录名获取样本名,但该目录名并非实际样本名(比如是annovar_output)。正确做法是关联BAM文件与对应注释文件,从BAM文件名提取样本名后填充到注释文件中。
修改后的代码2
假设每个样本的注释文件存储在与BAM文件对应的目录下,或可通过样本名关联两者,我们先收集所有BAM文件的样本名,再匹配对应注释文件进行填充:
# 建立样本名到注释文件路径的映射 declare -A sample_map for bam_file in "$OUTPUT_DIR"/*.marked.bam; do sample_name=$(basename "$bam_file" | sed 's/\.marked\.bam$//') # 假设注释文件路径为$ANNOVAR_OUTPUT_DIR/$sample_name/annotated.hg38_multianno.txt sample_map["$sample_name"]="$ANNOVAR_OUTPUT_DIR/$sample_name/annotated.hg38_multianno.txt" done # 遍历样本,填充注释文件 for sample_name in "${!sample_map[@]}"; do annotated_file="${sample_map[$sample_name]}" if [ -f "$annotated_file" ]; then awk -v OFS='\t' -v sample="$sample_name" ' NR == 1 { col = -1 for (i=1; i<=NF; i++) if ($i == "Tumor_Sample_Barcode") col = i if (col == -1) { print $0, "Tumor_Sample_Barcode" col = NF + 1 } else { print $0 } } NR > 1 { $col = sample print $0 } ' "$annotated_file" > "${annotated_file}.temp" mv "${annotated_file}.temp" "$annotated_file" echo "已更新样本 $sample_name 的Tumor_Sample_Barcode列" else echo "警告:未找到样本 $sample_name 的注释文件:$annotated_file" fi done
适配说明
如果注释文件的存储路径与样本名的关联方式不同,可修改sample_map的赋值逻辑,比如通过查找包含样本名的注释文件:
annotated_file=$(find "$ANNOVAR_OUTPUT_DIR" -name "*${sample_name}*annotated.hg38_multianno.txt")
内容的提问来源于stack exchange,提问作者Melissa
相关产品推荐
相关产品推荐

