使用GEOparse合并探针与Gene ID时替换ID_REF为ENTREZ_GENE_ID失败求助
解决GEOparse中替换ID_REF为ENTREZ_GENE_ID的问题
我看了你这段代码,发现几个关键问题导致你没法成功把ID_REF替换成ENTREZ_GENE_ID,咱们一步步来修正:
1. 先修正基础数据赋值的错误
你现在把gse1.phenotype_data同时赋值给了gse2.gsm和gse3.gsm,这会让后两个数据集的样本数据完全错乱,应该分别使用各自GSE对象的表型数据:
# 修正样本数据赋值 gse1.gsm = gse1.phenotype_data gse2.gsm = gse2.phenotype_data # 原来误用了gse1的表型数据,现在改成gse2自己的 gse3.gsm = gse3.phenotype_data # 同理改为gse3自身的表型数据
2. 利用GPL注释表实现ID映射
替换ID_REF的核心是拿到GPL文件里的探针(ID_REF)和ENTREZ_GENE_ID的对应关系,GEOparse已经把GPL的注释存在gpl.table里了,咱们需要先提取这个映射关系,再和表达矩阵合并。
以GSE99039(GPL570)为例,步骤如下:
步骤1:提取GPL的注释映射
首先从GPL表中筛选出需要的列,注意有些探针可能对应多个基因,或者没有对应的ENTREZ ID,需要做简单清洗:
# 处理GSE99039的GPL注释 gpl570 = gse1.gpls['GPL570'].table # 提取ID_REF和ENTREZ_GENE_ID,过滤掉空值的行 gene_mapping = gpl570[['ID_REF', 'ENTREZ_GENE_ID']].dropna(subset=['ENTREZ_GENE_ID']) # 处理一个探针对应多个基因的情况(比如用逗号分隔的,这里取第一个基因ID) gene_mapping['ENTREZ_GENE_ID'] = gene_mapping['ENTREZ_GENE_ID'].str.split(',').str[0]
步骤2:将表达矩阵与映射表合并
把你之前过滤后的表达矩阵和这个映射表合并,然后替换索引为ENTREZ_GENE_ID,同时处理重复的基因ID(比如取平均值合并):
# 修正索引方式:用loc替代已弃用的ix samples = gse1.pivot_samples("VALUE").loc[expressed_probes] # 合并表达矩阵和基因映射表 samples_with_gene = samples.merge(gene_mapping, left_index=True, right_on='ID_REF') # 设置索引为ENTREZ_GENE_ID,移除多余的ID_REF列 samples_with_gene = samples_with_gene.set_index('ENTREZ_GENE_ID').drop('ID_REF', axis=1) # 合并同一ENTREZ ID对应的多个探针数据(取平均值) samples_final = samples_with_gene.groupby(level=0).mean()
3. 完整修正后的代码片段
把这些修正整合到你的代码里,针对每个GSE数据集重复类似逻辑即可:
# Import tools import GEOparse import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # download datasets gse1 = GEOparse.get_GEO(geo="GSE99039", destdir="C:/Users/Highf_000/PycharmProjects/TFTest") gse2 = GEOparse.get_GEO(geo="GSE6613", destdir="C:/Users/Highf_000/PycharmProjects/TFTest") gse3 = GEOparse.get_GEO(geo="GSE72267", destdir="C:/Users/Highf_000/PycharmProjects/TFTest") # 修正样本数据赋值 gse1.gsm = gse1.phenotype_data gse2.gsm = gse2.phenotype_data gse3.gsm = gse3.phenotype_data # 处理GSE99039的表达矩阵和ID映射 with open("GSE99039_GPL570.csv") as f: GSE99039_GPL570 = f.read().splitlines() pivoted_control_samples = gse1.pivot_samples('VALUE')[GSE99039_GPL570] pivoted_control_samples_average = pivoted_control_samples.median(axis=1) # 过滤探针 print("Number of probes before filtering: ", len(pivoted_control_samples_average)) expression_threshold = pivoted_control_samples_average.quantile(0.25) expressed_probes = pivoted_control_samples_average[pivoted_control_samples_average >= expression_threshold].index.tolist() print("Number of probes above threshold: ", len(expressed_probes)) # 过滤后的表达矩阵 samples = gse1.pivot_samples("VALUE").loc[expressed_probes] # 提取GPL注释映射 gpl570 = gse1.gpls['GPL570'].table gene_mapping = gpl570[['ID_REF', 'ENTREZ_GENE_ID']].dropna(subset=['ENTREZ_GENE_ID']) gene_mapping['ENTREZ_GENE_ID'] = gene_mapping['ENTREZ_GENE_ID'].str.split(',').str[0] # 合并并替换ID samples_with_gene = samples.merge(gene_mapping, left_index=True, right_on='ID_REF') samples_with_gene = samples_with_gene.set_index('ENTREZ_GENE_ID').drop('ID_REF', axis=1) samples_final = samples_with_gene.groupby(level=0).mean() # 现在samples_final的索引就是ENTREZ_GENE_ID了 print(samples_final.head())
关键注意事项
- 不同GPL平台的注释列名可能有差异(比如有些用
Entrez_Gene_ID大小写不同),可以先通过print(gpl.table.columns)确认列名。 - 处理多基因对应单探针的情况时,除了取第一个,你也可以根据需求选择丢弃这类探针或保留所有基因。
- 避免使用已弃用的
ix索引方法,改用loc(标签索引)或iloc(位置索引)。
内容的提问来源于stack exchange,提问作者Chad Highfill




