求Bash/R方案:匹配ASV插入空行对齐分类学与丰度数据
Bash & R 实现:匹配ASV列表并补全缺失分类信息
现有两个文件:
- File1.txt:包含ASV及其分类学信息的blast结果
- File2.txt:ASV丰度数据的标识符列表(已按固定顺序排列,无需排序)
需要将两个文件的ASV标识符匹配,把分类学信息与丰度信息对应整合。若File2中的ASV在File1中缺失,需插入全为EMPTY的行,确保后续信息对齐。
示例文件
File1.txt
ASV Percent_Identity Evalue Taxid Title 012a3e401584af45819ba1c4409381bb 99.6 7.61e-124 549 Pantoea agglomerans 6095c6c24ff4e87866804d0806340c71 99.6 7.61e-124 77133 Uncultured bacterium 9f94e24e6e7757238df875434b3207f8 100 1.63e-125 77133 Uncultured bacterium 2654ad4af2207cdca21d16a97ddfeace 100 1.63e-125 77133 Uncultured bacterium 1d8e161787abc1c1dce62b190e1493eb 100 1.63e-125 77133 uncultured bacterium bed6fb75e90ee410096bef8c0847f46f 99.2 3.54e-122 77133 Uncultured bacterium
File2.txt
012a3e401584af45819ba1c4409381bb 6095c6c24ff4e87866804d0806340c71 9f94e24e6e7757238df875434b3207f8 2654ad4af2207cdca21d16a97ddfeace 1d8e161787abc1c1dce62b190e1493eb 907b63f00fdcd1a6c51d2e632f8b7fb8 bed6fb75e90ee410096bef8c0847f46f
期望输出File3.txt
ASV Percent_Identity Evalue Taxid Title 012a3e401584af45819ba1c4409381bb 99.6 7.61e-124 549 Pantoea agglomerans 6095c6c24ff4e87866804d0806340c71 99.6 7.61e-124 77133 Uncultured bacterium 9f94e24e6e7757238df875434b3207f8 100 1.63e-125 77133 Uncultured bacterium 2654ad4af2207cdca21d16a97ddfeace 100 1.63e-125 77133 Uncultured bacterium 1d8e161787abc1c1dce62b190e1493eb 100 1.63e-125 77133 uncultured bacterium EMPTY EMPTY EMPTY EMPTY EMPTY bed6fb75e90ee410096bef8c0847f46f 99.2 3.54e-122 77133 Uncultured bacterium
解决方案
1. Bash 实现(使用awk)
利用awk按顺序遍历两个文件,先将File1的ASV信息存入数组,再按File2的顺序输出,缺失时补EMPTY行:
awk ' BEGIN {OFS="\t"} # 设置输出分隔符为制表符(与输入格式一致) NR==FNR { if (NR==1) header=$0; # 保存表头 else asv[$1]=$0; # 将ASV作为键,整行内容作为值存入数组 next } FNR==1 {print header} # 输出表头 { if ($1 in asv) print asv[$1]; # 若ASV存在,输出对应行 else print "EMPTY\tEMPTY\tEMPTY\tEMPTY\tEMPTY"; # 不存在则输出EMPTY行 } ' File1.txt File2.txt > File3.txt
说明:
- 若输入文件用空格分隔而非制表符,可删除
BEGIN {OFS="\t"},awk会自动处理连续空格 - 执行后结果直接写入
File3.txt
2. R 实现
通过读取文件、匹配ASV并补全缺失行:
# 读取文件,假设分隔符为制表符,若为空格可改为sep=" " file1 <- read.table("File1.txt", header=TRUE, sep="\t", stringsAsFactors=FALSE) file2 <- read.table("File2.txt", header=FALSE, stringsAsFactors=FALSE, col.names="ASV") # 初始化结果数据框,结构与file1一致 result <- file1[0,] # 遍历file2的每个ASV,匹配并补全 for (asv_id in file2$ASV) { match_row <- file1[file1$ASV == asv_id, ] if (nrow(match_row) > 0) { result <- rbind(result, match_row) } else { # 构造EMPTY行 empty_row <- data.frame( ASV="EMPTY", Percent_Identity="EMPTY", Evalue="EMPTY", Taxid="EMPTY", Title="EMPTY", stringsAsFactors=FALSE ) result <- rbind(result, empty_row) } } # 写入结果文件,保留原始格式 write.table(rbind(colnames(file1), result), "File3.txt", sep="\t", row.names=FALSE, col.names=FALSE, quote=FALSE)
说明:
- 若文件分隔符为多个空格,可使用
sep="\s+"并配合read.delim函数 - 执行后结果写入
File3.txt,格式与示例完全一致
内容的提问来源于stack exchange,提问作者Katherine Chau
相关产品推荐
相关产品推荐

