由于使用睿远的发布的代码,但是会出现以下这种情况。
举例,原本基因名为evm.TU.PTG000033L.1 新的基因ID为TgSBT1。那么检测到evm.TU.PTG000033L.10这种也会替换将前面的evm.TU.PTG000033L.1的替换掉就变成TgSBT10。
于是,想了一个稍微笨一点方法。
首先是提取基因在染色体上的位置,通过excel排序生成一个包含老基因和新基因名的文件。再根据文件来进行替换。
1、先是生成染色体位置的文件
# 读取基因ID列表
with open('D:/1、博士期间/9、博士-实验以及项目/1、扦插苗转录组实验/比较雌树和雄树的差异/6、基因家族分析/SBT基因家族/TgSBT_gene_id.txt', 'r') as f:
gene_ids = set(line.strip() for line in f)
# 用于记录已经输出过的基因ID
output_gene_ids = set()
# 打开GFF文件和输出文件
with open('D:/1、博士期间/9、博士-实验以及项目/1、扦插苗转录组实验/香榧根腐病转录组/0、香榧cds.pep序列/Tgra.chr.TU.gff.txt', 'r') as gff_file, open('D:/1、博士期间/9、博士-实验以及项目/1、扦插苗转录组实验/比较雌树和雄树的差异/6、基因家族分析/SBT基因家族/gene_location', 'w') as output_file:
for line in gff_file:
if line.startswith('#'):
continue # 跳过注释行
fields = line.strip().split('\t')
attributes = fields[8]
# 解析属性字段,查找基因ID
for attr in attributes.split(';'):
if attr.startswith('ID='):
gene_id = attr[3:]
if gene_id in gene_ids and gene_id not in output_gene_ids:
chromosome = fields[0]
start = fields[3]
end = fields[4]
# 写入输出文件
output_file.write(f'{gene_id}\t{chromosome}\t{start}\t{end}\n')
# 记录已经输出过的基因ID
output_gene_ids.add(gene_id)
2、通过excel排序后,添加基因家族新的ID,生成新的文件,第一列为old_id,第二列为new_id。

3、在通过比对GFF文件中的ID,进行替换。

因为基因ID前面是=,后面是;所以在代码中,明确识别=与;之间的基因ID,这样不会出现上述的问题。这样就生成的新的GFF文件。
# 定义读取 ID 映射文件的函数
def read_id_mapping(mapping_file):
id_mapping = {}
try:
with open(mapping_file, 'r', encoding='utf-8') as f:
for line in f:
try:
# 按逗号分割每行,获取旧 ID 和新 ID
old_id, new_id = line.strip().split(',')
id_mapping[old_id] = new_id
except ValueError:
# 打印格式错误的行
print(f"Invalid line in mapping file: {line.strip()}")
except FileNotFoundError:
print(f"Error: The mapping file {mapping_file} was not found.")
return id_mapping
# 定义替换 GFF 文件中 ID 的函数
def replace_ids_in_gff(gff_file, id_mapping, output_file):
try:
with open(gff_file, 'r', encoding='utf-8') as infile, open(output_file, 'w', encoding='utf-8') as outfile:
for line in infile:
if line.startswith('#'): # 跳过注释行
outfile.write(line)
continue
# 按制表符分割每行,获取各字段
fields = line.strip().split('\t')
attributes = fields[8].split(';')
new_attributes = []
for attr in attributes:
if '=' in attr:
# 提取属性名和值
key, value = attr.split('=', 1)
# 检测是否存在映射关系
if value in id_mapping:
# 如果旧 ID 存在于映射字典中,替换为新 ID
new_value = id_mapping[value]
new_attributes.append(f'{key}={new_value}')
else:
new_attributes.append(attr)
else:
new_attributes.append(attr)
# 更新属性字段
fields[8] = ';'.join(new_attributes)
# 将处理后的行写入输出文件
outfile.write('\t'.join(fields) + '\n')
except FileNotFoundError:
print(f"Error: The GFF file {gff_file} was not found.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# 主程序
if __name__ == "__main__":
# 替换为你的 ID 映射文件路径
mapping_file = r"D:/1、博士期间/9、博士-实验以及项目/1、扦插苗转录组实验/比较雌树和雄树的差异/6、基因家族分析/SBT基因家族/按顺序命名新的基因ID.csv"
# 替换为你的 GFF 文件路径
gff_file = r"D:/1、博士期间/9、博士-实验以及项目/1、扦插苗转录组实验/香榧根腐病转录组/0、香榧cds.pep序列/Tgra.chr.TU.gff.txt"
# 替换为你想要保存的输出文件路径
output_file = r"D:/1、博士期间/9、博士-实验以及项目/1、扦插苗转录组实验/比较雌树和雄树的差异/6、基因家族分析/SBT基因家族/new.id.gff.txt"
# 读取 ID 映射文件
id_mapping = read_id_mapping(mapping_file)
# 替换 GFF 文件中的 ID
if id_mapping:
replace_ids_in_gff(gff_file, id_mapping, output_file)
#代码均有AI生成,只要给与明确、详细的指令,就可以得到成功的代码!