Python 从NCBI BLASTp解析表
我想将一个两列文件转换为一个由0和1组成的表,以便为PCA(主成分分析)做好准备。输入文件由第一列中的细菌名称和第二列中的细菌描述符组成 可能的方法:将输入文件存储在散列中,然后对每列执行某种“uniq”命令,并将它们添加到输出文件中。要完成此操作,对于输出文件中的每个组合,如果在文件1哈希中找到细菌名称和描述符,则添加0或1 输入文件(以制表符分隔): 所需输出(制表符分隔):Python 从NCBI BLASTp解析表,python,perl,awk,blast,Python,Perl,Awk,Blast,我想将一个两列文件转换为一个由0和1组成的表,以便为PCA(主成分分析)做好准备。输入文件由第一列中的细菌名称和第二列中的细菌描述符组成 可能的方法:将输入文件存储在散列中,然后对每列执行某种“uniq”命令,并将它们添加到输出文件中。要完成此操作,对于输出文件中的每个组合,如果在文件1哈希中找到细菌名称和描述符,则添加0或1 输入文件(以制表符分隔): 所需输出(制表符分隔): 快速python脚本: #!/usr/bin/env python # -*- coding: utf-8 -*-
快速
python
脚本:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import fileinput
from collections import defaultdict
output = defaultdict(list)
proteins = set()
for line in fileinput.input():
bacteria, protein = line.strip().split()
proteins.update([protein])
output[bacteria].append(protein)
# Print header
print ' '*12,
for header in sorted(proteins):
print '{:25}'.format(header),
print
# Print table
for key in output:
print '{:12}'.format(key),
for header in sorted(proteins):
if header in output[key]:
print '{:22}'.format(1),
else:
print '{:22}'.format(0),
print
产出:
$ python table.py inputfile
protein:plasmid:147856 protein:plasmid:149679 protein:proph:183386
bacteria_2 0 0 1
bacteria_3 1 0 1
bacteria_1 0 1 1
以下是GNU awk的一种方法:
awk '{
header[$2]++;
bacteria[$1]++;
map[$1,$2]++
}
END {
x=asorti(header,header_s);
for(i=1;i<=x;i++) {
printf "\t%s\t", header_s[i]
}
print ""
y=asorti(bacteria,bacteria_s);
for(j=1;j<=y;j++) {
printf "%s\t\t", bacteria_s[j];
for (z=1;z<=x;z++) {
printf "%s\t\t\t\t", (map[bacteria_s[j],header_s[z]])?"1":"0"
}
print ""
}
}' file
protein:plasmid:147856 protein:plasmid:149679 protein:proph:183386
bacteria_1 0 1 1
bacteria_2 0 0 1
bacteria_3 1 0 1
awk '
!is_present[$1]++ {bacteria[++x] = $1}
!is_present[$2]++ {protein[++y] = $2}
{map[$1,$2]++}
END {
for(i=1; i<=y; i++) {
printf "\t%s\t", protein[i]
}
print "";
for(j=1; j<=x; j++) {
printf "%s\t\t", bacteria[j];
for(a=1; a<=y; a++) {
printf "%s\t\t\t\t", (map[bacteria[j], protein[a]])?"1":"0"
}
print ""
}
}' file
你似乎忘记问问题了。你正在发布非常类似的问题。我建议您尝试在perl、awk或python中获得一些魔力,并研究给出的答案。否则,你将永远依赖于人们来回答你的具体问题。这是真正的fedorqui。我想花点时间研究人们给我的答案,特别是perl,这是我的一个弱点。awk:调用未定义函数asorti input record number 6,file 1 source line number7@popnard正如我在解决方案中提到的,这需要
GNU
的awk
变体。您是在solaris
还是mac
?@popnard添加了一个awk
解决方案,因为您没有GNU awk
我在mac上,很抱歉,但感谢您添加这两个版本。它工作得很好,只是添加了一些自定义,使其只分隔一个。回溯(最后一次调用):文件“table.py”,第11行,在细菌中,protein=line.strip()unpack@popnard是的,这就是当您的实际输入文件与您发布的示例文件看起来不同时发生的情况。。。。我猜您的实际输入包含空行?我刚刚粘贴了一个以制表符分隔的表,并对其应用了“代码”格式。自动将我的选项卡替换为空格。
awk '{
header[$2]++;
bacteria[$1]++;
map[$1,$2]++
}
END {
x=asorti(header,header_s);
for(i=1;i<=x;i++) {
printf "\t%s\t", header_s[i]
}
print ""
y=asorti(bacteria,bacteria_s);
for(j=1;j<=y;j++) {
printf "%s\t\t", bacteria_s[j];
for (z=1;z<=x;z++) {
printf "%s\t\t\t\t", (map[bacteria_s[j],header_s[z]])?"1":"0"
}
print ""
}
}' file
protein:plasmid:147856 protein:plasmid:149679 protein:proph:183386
bacteria_1 0 1 1
bacteria_2 0 0 1
bacteria_3 1 0 1
awk '
!is_present[$1]++ {bacteria[++x] = $1}
!is_present[$2]++ {protein[++y] = $2}
{map[$1,$2]++}
END {
for(i=1; i<=y; i++) {
printf "\t%s\t", protein[i]
}
print "";
for(j=1; j<=x; j++) {
printf "%s\t\t", bacteria[j];
for(a=1; a<=y; a++) {
printf "%s\t\t\t\t", (map[bacteria[j], protein[a]])?"1":"0"
}
print ""
}
}' file