Yuanclaw / docs /GSEA_ID_MISMATCH_FIX.md
huashu's picture
Export YuanSeq to Hugging Face without binary assets
7e6a9d1

GSEA模块ID类型不匹配问题修复

日期: 2025-12-26 问题: 用户选择ENTREZID格式的GMT文件但选择SYMBOL作为ID类型时,应用崩溃


问题描述

当用户:

  1. 上传ENTREZID格式的GMT文件(基因ID是数字如12985)
  2. 但在UI中选择了"Gene Symbol"作为ID类型
  3. 运行GSEA时,尝试将GMT中的ENTREZID转换为SYMBOL

错误信息:

Error in $<-.data.frame: 替换数据里有657808行,但数据有882938

修复方案

1. 添加tryCatch错误捕获

位置: modules/gsea_analysis.R:82-136

tryCatch({
  # 创建ENTREZID到SYMBOL的映射
  entrez_to_symbol <- setNames(res_clean$SYMBOL, res_clean$ENTREZID)

  # 转换GMT文件
  gmt$gene_symbol <- entrez_to_symbol[as.character(gmt$gene)]

  # 统计和检查
  ...
}, error = function(e) {
  # 捕获错误并提供用户友好的提示
  showNotification("GMT ID类型不匹配!请选择正确的ID类型", type = "error")
  return(NULL)
})

2. 映射率检查和警告

# 统计转换结果
n_total <- nrow(gmt)
n_mapped <- sum(!is.na(gmt$gene_symbol))
n_unmapped <- sum(is.na(gmt$gene_symbol))

cat(sprintf("📊 转换结果: %d/%d 成功映射 (%.1f%%), %d 无法映射\n",
           n_mapped, n_total, n_mapped/n_total*100, n_unmapped))

if (n_mapped < n_total * 0.5) {
  # 如果超过50%无法映射,警告用户
  showNotification("⚠️ GMT文件中超过50%的基因无法映射!\n\n建议:选择'Entrez ID'",
                  type = "warning", duration = 10)
  # 不中断,继续使用部分数据
}

3. 详细的控制台输出

🔄 检测到GMT使用ENTREZID,正在转换为SYMBOL...
📊 GMT文件: 882938 行
📊 映射关系: 14610 个ENTREZID -> 14610 个SYMBOL
📊 转换结果: 657808/882938 成功映射 (74.5%), 225130 无法映射
✅ GMT转换完成: 186 个基因集, 657808 个基因

4. 用户友好的错误提示

当映射率过低时(<50%):

⚠️ GMT文件中超过50%的基因无法映射!

您的GMT文件使用ENTREZID格式,但您选择了SYMBOL。

建议:
1. 在'GMT中的ID类型'中选择'Entrez ID'
2. 或者使用SYMBOL格式的GMT文件

当前映射:25.0% (100/400)

当转换完全失败时:

❌ GMT ID类型不匹配!

错误:替换数据里有657808行,但数据有882938

您的GMT文件使用ENTREZID格式,但您选择了SYMBOL。

请选择'Entrez ID'作为ID类型。

使用建议

推荐配置

情况1: GMT文件使用ENTREZID(数字ID)

GMT中的ID类型: Entrez ID ✅

情况2: GMT文件使用SYMBOL(基因名)

GMT中的ID类型: Gene Symbol ✅

不推荐的配置

❌ GMT文件: ENTREZID格式
   ID类型选择: Gene Symbol
   结果: 映射率可能很低,性能差

如何判断GMT文件格式

  1. 打开GMT文件查看前几行:

    GO_0008150\t12985/71897/330122
    GO_0019220\t54448/20299/14825
    

    如果是纯数字 → ENTREZID格式

    GO_0008150\tCsf3/Lypd6b/Cxcl3
    GO_0019220\tIl1r2/Tnf/Il6
    

    如果是基因名 → SYMBOL格式

  2. 查看文件名:

    • msigdb_v7.5.1_entrez.gmt → ENTREZID
    • msigdb_v7.5.1_symbols.gmt → SYMBOL

修复后的行为

场景1: ID类型匹配

GMT: ENTREZID
用户选择: Entrez ID
结果: ✅ 直接运行,无需转换

场景2: ID类型不匹配,但映射率可接受

GMT: ENTREZID (882,938 行)
用户选择: SYMBOL
映射: 657,808/882,938 (74.5%)
结果: ⚠️ 警告,但继续运行

场景3: ID类型不匹配,映射率过低

GMT: ENTREZID (1,000,000 行)
用户选择: SYMBOL
映射: 100,000/1,000,000 (10%)
结果: ⚠️ 警告,提示用户调整选择
      但仍继续运行(使用部分数据)

场景4: 转换失败

GMT: ENTREZID
用户选择: SYMBOL
错误: 数据框维度不匹配
结果: ❌ 错误提示 + 友好建议
      停止运行,等待用户调整

技术细节

错误捕获流程

  1. 检测ID类型: grepl("^[0-9]+$", sample_genes)
  2. 创建映射: setNames(res_clean$SYMBOL, res_clean$ENTREZID)
  3. 转换GMT: entrez_to_symbol[as.character(gmt$gene)]
  4. 统计映射率: 计算成功映射的百分比
  5. 决策:
    • < 50%: 警告但继续
    • 0: 错误并停止
    • 其他: 正常运行

容错机制

  1. tryCatch: 捕获所有错误
  2. 警告而非错误: 映射率>50%时继续运行
  3. 友好的UI提示: 清楚说明问题和解决方案
  4. 详细日志: 控制台输出完整信息

测试步骤

  1. 测试正常情况:

    • GMT: ENTREZID
    • 选择: Entrez ID
    • 预期: ✅ 正常运行
  2. 测试ID不匹配但可接受:

    • GMT: ENTREZID
    • 选择: SYMBOL
    • 预期: ⚠️ 警告但继续运行
  3. 测试完全错误:

    • 使用错误格式的GMT
    • 预期: ❌ 错误提示 + 停止运行

总结

修复的问题

  1. ✅ 应用不再崩溃
  2. ✅ 提供清晰的错误信息
  3. ✅ 建议正确的配置
  4. ✅ 在某些情况下容错继续运行
  5. ✅ 详细的调试输出

用户体验改进

  • ❌ 之前: 应用崩溃,用户不知道原因
  • ✅ 现在: 友好的错误提示 + 解决方案

控制台输出

🔄 检测到GMT使用ENTREZID,正在转换为SYMBOL...
📊 GMT文件: 882938 行
📊 映射关系: 14610 个ENTREZID -> 14610 个SYMBOL
📊 转换结果: 657808/882938 成功映射 (74.5%), 225130 无法映射
⚠️ 映射率过低,建议用户调整ID类型选择
✅ GMT转换完成: 186 个基因集, 657808 个基因

版本: 3.3 Final 状态: ✅ 完全修复 兼容性: 向后兼容,不影响正常使用