Parsing 从单个字符串高效地计算统计信息(bowtie2提供的bam文件)
我的目标是有效地将包含短DNA测序读取的bowtie2映射的bam文件转换为一个简单的表,该表包含映射开始和百分比标识。我即将完成这项工作,但是我的解决方案非常缓慢,无法处理重要的异常。我会逐步解释情况: 我们从这样的字符串开始Parsing 从单个字符串高效地计算统计信息(bowtie2提供的bam文件),parsing,optimization,bioinformatics,Parsing,Optimization,Bioinformatics,我的目标是有效地将包含短DNA测序读取的bowtie2映射的bam文件转换为一个简单的表,该表包含映射开始和百分比标识。我即将完成这项工作,但是我的解决方案非常缓慢,无法处理重要的异常。我会逐步解释情况: 我们从这样的字符串开始 FCC5G2YACXX:5:1101:1224:2059#NNNNNNNN 97 genome 96003934 24 118M4D11M = 96004135 0 GCA....ACG P\..GW^EO AS:i:-2
FCC5G2YACXX:5:1101:1224:2059#NNNNNNNN 97 genome 96003934 24 118M4D11M = 96004135 0 GCA....ACG P\..GW^EO AS:i:-28 XN:i:0 XM:i:2 XO:i:1 XG:i:4 NM:i:6 MD:Z:54G53T9^TACA11 YT:Z:UP
我们只取第四列和MD:Z:54G53T9^TACA11
部分,后者表示匹配(数字)和不匹配(字母)。除非字母前面有一个“^”,否则字母是引用序列中的删除项
然后我将其计算成如下字符串9600393498.00
其中第一列与原始输入的第四列相同,第二列为匹配项,除以匹配项和不匹配项之和
因为我更喜欢bash/zsh脚本,所以我执行了以下操作
if_sam2tab() {
tab=$(echo $1 | rev | cut -d '.' -f 2- | rev)
if [ ! -e ./bowtie_results/$tab.tab ]
then echo -e "rstart\tmatch\tmismatch" > ./bowtie_results/$tab.tab
while read -r l
do rstart=$(echo $l | cut -f 4 -d " " )
t=$(echo $l | grep -o 'MD:Z:[0-9A-Z]*' )
match=$(echo ${t: 5} | tr '[a-zA-Z]' '+' | bc )
mismatch=$(echo ${t: 5} | tr -d '[0-9]\n' | wc -c )
sum=$(echo "$match + $mismatch" | bc )
id=$(echo "scale=2; $match / $sum *100" | bc )
echo -e "$rstart\t$id" >> ./bowtie_results/$tab.tab
done < <(grep 'MD:Z' ./bowtie_results/$1 )
fi
}
if_sam2tab(){
表=$(回显$1 |版次|切割-d'.-f 2 |版次)
如果[!-e./bowtie_结果/$tab.tab]
然后echo-e“rstart\tmatch\tmismatch”>。/bowtie_results/$tab.tab
而read-rl
do rstart=$(echo$l | cut-f 4-d“”)
t=$(echo$l | grep-o'MD:Z:[0-9A-Z]*'))
match=$(echo${t:5}|tr'[a-zA-Z]''+'| bc)
不匹配=$(echo${t:5}|tr-d'[0-9]\n'|wc-c)
总和=$(回显“$匹配+$不匹配”| bc)
id=$(echo“scale=2;$match/$sum*100”| bc)
echo-e“$rstart\t$id”>>。/bowtie_results/$tab.tab
完成<
- 使用二进制数据(bam文件)输入和输出要快得多,但您有一个sam文件(平面版本)
以前已经注释过的,总是用编译语言(C,C++等)编写的程序比脚本(EJ,BASH,AWK等)要快。
我在awk
中显示了一个脚本,供您尝试
awk '{
split($18,v,/[\^:]/);
nmatch = split(v[3],vmatch, /[^0-9]/);
cmatch=0;
for(i=1; i<=nmatch; i++) cmatch+=vmatch[i];
printf("%s"OFS"%.2f\n", $4, cmatch*100/(cmatch+nmatch-1));
}' file.sam
awk'{
拆分($18,v,/\^://);
n匹配=分割(v[3],v匹配,/[^0-9]/);
cmatch=0;
对于(i=1;iJose对前面答案的补充:MD字符串不一定是第18列。因此,我在Jose的awk脚本中添加了一行,以查找MD字符串,而不考虑该行中的位置。毫无疑问,在该过程中添加regex步骤将使其整体速度减慢
awk '{
match($0, /MD:Z:[0-9A-Z\^]*/,m );
split(m[0],v,/[\^:]/);
nmatch = split(v[3],vmatch, /[^0-9]/);
cmatch=0;
for(i=1; i<=nmatch; i++) cmatch+=vmatch[i];
printf("%s"OFS"%.2f\n", $4, cmatch*100/(cmatch+nmatch-1));
}'
awk'{
匹配($0,/MD:Z:[0-9A-Z\^]*/,m);
分裂(m[0],v,/[\^:]/);
n匹配=分割(v[3],v匹配,/[^0-9]/);
cmatch=0;
对于(i=1;术语< >代码>有效< /COD>和<代码> shell脚本不一致。Shell脚本总是非常慢。通常使用shell时不关心速度。如果是,那么考虑移动到脚本语言。BAM文件?像山姆文件如何…谢谢您看一下!确实我知道shell脚本不是。如果速度很重要,那该怎么办。我更喜欢shell脚本,因为它是我所熟悉的唯一一种,而且通常足够快,可以学习一些有趣的生物学。我选择不在问题中详细说明这一点,以保持它的简洁性和相关性。一旦这篇论文发表,我希望能找到一些时间来学习脚本语言。你的解决方案这似乎很有效!谢谢你的时间。我会花一些时间来剖析这段代码到底做了什么,乍一看,这在生物学上似乎很好。
awk '{
match($0, /MD:Z:[0-9A-Z\^]*/,m );
split(m[0],v,/[\^:]/);
nmatch = split(v[3],vmatch, /[^0-9]/);
cmatch=0;
for(i=1; i<=nmatch; i++) cmatch+=vmatch[i];
printf("%s"OFS"%.2f\n", $4, cmatch*100/(cmatch+nmatch-1));
}'