mcpField
G
geo-database

geo-database

github.com/jackspace数据与数据库1636 次安装12 周前更新
代码仓库

关于 geo-database

GEO Database 技能为基因表达和功能基因组学研究提供 GEO 数据检索、下载与分析指导,适合需要将 GEO 数据用于计算分析的研究人员。涵盖数据集、样本和表达谱等不同层级。

主要功能

  1. 01按关键词和条件搜索 GEO
  2. 02检索基因表达谱
  3. 03下载并解析系列数据
  4. 04批量获取元数据
  5. 05指导表达数据分析

适用场景

  1. 01查找特定条件的转录组数据
  2. 02比较多个研究中的表达谱
  3. 03筛选差异表达基因
  4. 04跨数据集开展荟萃分析

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jackspace/claudeskillz --skill geo-database

安装后在 Claude Code 中输入/geo-database确认已加载。

附带文件SKILL.json

详细介绍

GEO 数据库

概述

基因表达综合数据库(GEO)是 NCBI 用于存储高通量基因表达和功能基因组学数据的公共资源库。GEO 收录了超过 264,000 项研究,其中包含来自基于芯片和基于测序实验的 800 多万个样本。

何时使用此技能

在搜索基因表达数据集、获取实验数据、下载原始文件和处理后文件、查询表达谱,或将 GEO 数据整合到计算分析工作流中时,应使用此技能。

核心功能

1. 了解 GEO 数据组织方式

GEO 使用不同的登录号类型按层级组织数据:

系列(GSE): 一项包含一组相关样本的完整实验

  • 示例:GSE123456
  • 包含实验设计、样本和整体研究信息
  • GEO 中最大的组织单位
  • 当前数量:264,928+ 个系列

样本(GSM): 单个实验样本或生物学重复

  • 示例:GSM987654
  • 包含单个样本的数据、实验方案和元数据
  • 与平台和系列相关联
  • 当前数量:8,068,632+ 个样本

平台(GPL): 所用的微阵列或测序平台

  • 示例:GPL570(Affymetrix Human Genome U133 Plus 2.0 Array)
  • 描述技术以及探针/特征注释
  • 多项实验共用
  • 当前数量:27,739+ 个平台

数据集(GDS): 格式一致的精选数据集

  • 示例:GDS5678
  • 按研究设计组织、可进行实验比较的样本
  • 已经过差异分析处理
  • GEO 数据的子集(4,348 个精选数据集)
  • 适合快速比较分析

表达谱: 与序列特征相关联的基因特异性表达数据

  • 可按基因名称或注释查询
  • 可交叉引用 Entrez Gene
  • 支持跨所有研究进行以基因为中心的搜索
2. 搜索 GEO 数据

GEO 数据集搜索:

按关键词、生物体或实验条件搜索研究:

from Bio import Entrez

# Configure Entrez (required)
Entrez.email = "[email protected]"

# Search for datasets
def search_geo_datasets(query, retmax=20):
    """Search GEO DataSets database"""
    handle = Entrez.esearch(
        db="gds",
        term=query,
        retmax=retmax,
        usehistory="y"
    )
    results = Entrez.read(handle)
    handle.close()
    return results

# Example searches
results = search_geo_datasets("breast cancer[MeSH] AND Homo sapiens[Organism]")
print(f"Found {results['Count']} datasets")

# Search by specific platform
results = search_geo_datasets("GPL570[Accession]")

# Search by study type
results = search_geo_datasets("expression profiling by array[DataSet Type]")

GEO 表达谱搜索:

查找基因特异性表达模式:

# Search for gene expression profiles
def search_geo_profiles(gene_name, organism="Homo sapiens", retmax=100):
    """Search GEO Profiles for a specific gene"""
    query = f"{gene_name}[Gene Name] AND {organism}[Organism]"
    handle = Entrez.esearch(
        db="geoprofiles",
        term=query,
        retmax=retmax
    )
    results = Entrez.read(handle)
    handle.close()
    return results

# Find TP53 expression across studies
tp53_results = search_geo_profiles("TP53", organism="Homo sapiens")
print(f"Found {tp53_results['Count']} expression profiles for TP53")

高级搜索模式:

# Combine multiple search terms
def advanced_geo_search(terms, operator="AND"):
    """Build complex search queries"""
    query = f" {operator} ".join(terms)
    return search_geo_datasets(query)

# Find recent high-throughput studies
search_terms = [
    "RNA-seq[DataSet Type]",
    "Homo sapiens[Organism]",
    "2024[Publication Date]"
]
results = advanced_geo_search(search_terms)

# Search by author and condition
search_terms = [
    "Smith[Author]",
    "diabetes[Disease]"
]
results = advanced_geo_search(search_terms)
3. 使用 GEOparse 获取 GEO 数据(推荐)

GEOparse 是用于访问 GEO 数据的主要 Python 库:

安装:

pip install GEOparse

基本用法:

import GEOparse

# Download and parse a GEO Series
gse = GEOparse.get_GEO(geo="GSE123456", destdir="./data")

# Access series metadata
print(gse.metadata['title'])
print(gse.metadata['summary'])
print(gse.metadata['overall_design'])

# Access sample information
for gsm_name, gsm in gse.gsms.items():
    print(f"Sample: {gsm_name}")
    print(f"  Title: {gsm.metadata['title'][0]}")
    print(f"  Source: {gsm.metadata['source_name_ch1'][0]}")
    print(f"  Characteristics: {gsm.metadata.get('characteristics_ch1', [])}")

# Access platform information
for gpl_name, gpl in gse.gpls.items():
    print(f"Platform: {gpl_name}")
    print(f"  Title: {gpl.metadata['title'][0]}")
    print(f"  Organism: {gpl.metadata['organism'][0]}")

处理表达数据:

import GEOparse
import pandas as pd

# Get expression data from series
gse = GEOparse.get_GEO(geo="GSE123456", destdir="./data")

# Extract expression matrix
# Method 1: From series matrix file (fastest)
if hasattr(gse, 'pivot_samples'):
    expression_df = gse.pivot_samples('VALUE')
    print(expression_df.shape)  # genes x samples

# Method 2: From individual samples
expression_data = {}
for gsm_name, gsm in gse.gsms.items():
    if hasattr(gsm, 'table'):
        expression_data[gsm_name] = gsm.table['VALUE']

expression_df = pd.DataFrame(expression_data)
print(f"Expression matrix: {expression_df.shape}")

访问补充文件:

import GEOparse

gse = GEOparse.get_GEO(geo="GSE123456", destdir="./data")

# Download supplementary files
gse.download_supplementary_files(
    directory="./data/GSE123456_suppl",
    download_sra=False  # Set to True to download SRA files
)

# List available supplementary files
for gsm_name, gsm in gse.gsms.items():
    if hasattr(gsm, 'supplementary_files'):
        print(f"Sample {gsm_name}:")
        for file_url in gsm.metadata.get('supplementary_file', []):
            print(f"  {file_url}")

筛选和提取子集数据:

import GEOparse

gse = GEOparse.get_GEO(geo="GSE123456", destdir="./data")

# Filter samples by metadata
control_samples = [
    gsm_name for gsm_name, gsm in gse.gsms.items()
    if 'control' in gsm.metadata.get('title', [''])[0].lower()
]

treatment_samples = [
    gsm_name for gsm_name, gsm in gse.gsms.items()
    if 'treatment' in gsm.metadata.get('title', [''])[0].lower()
]

print(f"Control samples: {len(control_samples)}")
print(f"Treatment samples: {len(treatment_samples)}")

# Extract subset expression matrix
expression_df = gse.pivot_samples('VALUE')
control_expr = expression_df[control_samples]
treatment_expr = expression_df[treatment_samples]
4. 使用 NCBI E-utilities 访问 GEO

E-utilities 提供对 GEO 元数据的底层编程访问:

E-utilities 基本工作流:

from Bio import Entrez
import time

Entrez.email = "[email protected]"

# Step 1: Search for GEO entries
def search_geo(query, db="gds", retmax=100):
    """Search GEO using E-utilities"""
    handle = Entrez.esearch(
        db=db,
        term=query,
        retmax=retmax,
        usehistory="y"
    )
    results = Entrez.read(handle)
    handle.close()
    return results

# Step 2: Fetch summaries
def fetch_geo_summaries(id_list, db="gds"):
    """Fetch document summaries for GEO entries"""
    ids = ",".join(id_list)
    handle = Entrez.esummary(db=db, id=ids)
    summaries = Entrez.read(handle)
    handle.close()
    return summaries

# Step 3: Fetch full records
def fetch_geo_records(id_list, db="gds"):
    """Fetch full GEO records"""
    ids = ",".join(id_list)
    handle = Entrez.efetch(db=db, id=ids, retmode="xml")
    records = Entrez.read(handle)
    handle.close()
    return records

# Example workflow
search_results = search_geo("breast cancer AND Homo sapiens")
id_list = search_results['IdList'][:5]

summaries = fetch_geo_summaries(id_list)
for summary in summaries:
    print(f"GDS: {summary.get('Accession', 'N/A')}")
    print(f"Title: {summary.get('title', 'N/A')}")
    print(f"Samples: {summary.get('n_samples', 'N/A')}")
    print()

使用 E-utilities 进行批量处理:

from Bio import Entrez
import time

Entrez.email = "[email protected]"

def batch_fetch_geo_metadata(accessions, batch_size=100):
    """Fetch metadata for multiple GEO accessions"""
    results = {}

    for i in range(0, len(accessions), batch_size):
        batch = accessions[i:i + batch_size]

        # Search for each accession
        for accession in batch:
            try:
                query = f"{accession}[Accession]"
                search_handle = Entrez.esearch(db="gds", term=query)
                search_results = Entrez.read(search_handle)
                search_handle.close()

                if search_results['IdList']:
                    # Fetch summary
                    summary_handle = Entrez.esummary(
                        db="gds",
                        id=search_results['IdList'][0]
                    )
                    summary = Entrez.read(summary_handle)
                    summary_handle.close()
                    results[accession] = summary[0]

                # Be polite to NCBI servers
                time.sleep(0.34)  # Max 3 requests per second

            except Exception as e:
                print(f"Error fetching {accession}: {e}")

    return results

# Fetch metadata for multiple datasets
gse_list = ["GSE100001", "GSE100002", "GSE100003"]
metadata = batch_fetch_geo_metadata(gse_list)
5. 通过 FTP 直接访问数据文件

GEO 数据的 FTP URL:

可通过 FTP 直接下载 GEO 数据:

import ftplib
import os

def download_geo_ftp(accession, file_type="matrix", dest_dir="./data"):
    """Download GEO files via FTP"""
    # Construct FTP path based on accession type
    if accession.startswith("GSE"):
        # Series files
        gse_num = accession[3:]
        base_num = gse_num[:-3] + "nnn"
        ftp_path = f"/geo/series/GSE{base_num}/{accession}/"

        if file_type == "matrix":
            filename = f"{accession}_series_matrix.txt.gz"
        elif file_type == "soft":
            filename = f"{accession}_family.soft.gz"
        elif file_type == "miniml":
            filename = f"{accession}_family.xml.tgz"

    # Connect to FTP server
    ftp = ftplib.FTP("ftp.ncbi.nlm.nih.gov")
    ftp.login()
    ftp.cwd(ftp_path)

    # Download file
    os.makedirs(dest_dir, exist_ok=True)
    local_file = os.path.join(dest_dir, filename)

    with open(local_file, 'wb') as f:
        ftp.retrbinary(f'RETR {filename}', f.write)

    ftp.quit()
    print(f"Downloaded: {local_file}")
    return local_file

# Download series matrix file
download_geo_ftp("GSE123456", file_type="matrix")

# Download SOFT format file
download_geo_ftp("GSE123456", file_type="soft")

使用 wget 或 curl 下载:

# Download series matrix file
wget ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE123nnn/GSE123456/matrix/GSE123456_series_matrix.txt.gz

# Download all supplementary files for a series
wget -r -np -nd ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE123nnn/GSE123456/suppl/

# Download SOFT format family file
wget ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE123nnn/GSE123456/soft/GSE123456_family.soft.gz
6. 分析 GEO 数据

质量控制和预处理:

import GEOparse
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Load dataset
gse = GEOparse.get_GEO(geo="GSE123456", destdir="./data")
expression_df = gse.pivot_samples('VALUE')

# Check for missing values
print(f"Missing values: {expression_df.isnull().sum().sum()}")

# Log transformation (if needed)
if expression_df.min().min() > 0:  # Check if already log-transformed
    if expression_df.max().max() > 100:
        expression_df = np.log2(expression_df + 1)
        print("Applied log2 transformation")

# Distribution plots
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
expression_df.plot.box(ax=plt.gca())
plt.title("Expression Distribution per Sample")
plt.xticks(rotation=90)

plt.subplot(1, 2, 2)
expression_df.mean(axis=1).hist(bins=50)
plt.title("Gene Expression Distribution")
plt.xlabel("Average Expression")

plt.tight_layout()
plt.savefig("geo_qc.png", dpi=300, bbox_inches='tight')

差异表达分析:

import GEOparse
import pandas as pd
import numpy as np
from scipy import stats

gse = GEOparse.get_GEO(geo="GSE123456", destdir="./data")
expression_df = gse.pivot_samples('VALUE')

# Define sample groups
control_samples = ["GSM1", "GSM2", "GSM3"]
treatment_samples = ["GSM4", "GSM5", "GSM6"]

# Calculate fold changes and p-values
results = []
for gene in expression_df.index:
    control_expr = expression_df.loc[gene, control_samples]
    treatment_expr = expression_df.loc[gene, treatment_samples]

    # Calculate statistics
    fold_change = treatment_expr.mean() - control_expr.mean()
    t_stat, p_value = stats.ttest_ind(treatment_expr, control_expr)

    results.append({
        'gene': gene,
        'log2_fold_change': fold_change,
        'p_value': p_value,
        'control_mean': control_expr.mean(),
        'treatment_mean': treatment_expr.mean()
    })

# Create results DataFrame
de_results = pd.DataFrame(results)

# Multiple testing correction (Benjamini-Hochberg)
from statsmodels.stats.multitest import multipletests
_, de_results['q_value'], _, _ = multipletests(
    de_results['p_value'],
    method='fdr_bh'
)

# Filter significant genes
significant_genes = de_results[
    (de_results['q_value'] < 0.05) &
    (abs(de_results['log2_fold_change']) > 1)
]

print(f"Significant genes: {len(significant_genes)}")
significant_genes.to_csv("de_results.csv", index=False)

相关性和聚类分析:

import GEOparse
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.cluster import hierarchy
from scipy.spatial.distance import pdist

gse = GEOparse.get_GEO(geo="GSE123456", destdir="./data")
expression_df = gse.pivot_samples('VALUE')

# Sample correlation heatmap
sample_corr = expression_df.corr()

plt.figure(figsize=(10, 8))
sns.heatmap(sample_corr, cmap='coolwarm', center=0,
            square=True, linewidths=0.5)
plt.title("Sample Correlation Matrix")
plt.tight_layout()
plt.savefig("sample_correlation.png", dpi=300, bbox_inches='tight')

# Hierarchical clustering
distances = pdist(expression_df.T, metric='correlation')
linkage = hierarchy.linkage(distances, method='average')

plt.figure(figsize=(12, 6))
hierarchy.dendrogram(linkage, labels=expression_df.columns)
plt.title("Hierarchical Clustering of Samples")
plt.xlabel("Samples")
plt.ylabel("Distance")
plt.xticks(rotation=90)
plt.tight_layout()
plt.savefig("sample_clustering.png", dpi=300, bbox_inches='tight')
7. 批量处理多个数据集

下载并处理多个系列:

import GEOparse
import pandas as pd
import os

def batch_download_geo(gse_list, destdir="./geo_data"):
    """Download multiple GEO series"""
    results = {}

    for gse_id in gse_list:
        try:
            print(f"Processing {gse_id}...")
            gse = GEOparse.get_GEO(geo=gse_id, destdir=destdir)

            # Extract key information
            results[gse_id] = {
                'title': gse.metadata.get('title', ['N/A'])[0],
                'organism': gse.metadata.get('organism', ['N/A'])[0],
                'platform': list(gse.gpls.keys())[0] if gse.gpls else 'N/A',
                'num_samples': len(gse.gsms),
                'submission_date': gse.metadata.get('submission_date', ['N/A'])[0]
            }

            # Save expression data
            if hasattr(gse, 'pivot_samples'):
                expr_df = gse.pivot_samples('VALUE')
                expr_df.to_csv(f"{destdir}/{gse_id}_expression.csv")
                results[gse_id]['num_genes'] = len(expr_df)

        except Exception as e:
            print(f"Error processing {gse_id}: {e}")
            results[gse_id] = {'error': str(e)}

    # Save summary
    summary_df = pd.DataFrame(results).T
    summary_df.to_csv(f"{destdir}/batch_summary.csv")

    return results

# Process multiple datasets
gse_list = ["GSE100001", "GSE100002", "GSE100003"]
results = batch_download_geo(gse_list)

跨研究进行荟萃分析:

import GEOparse
import pandas as pd
import numpy as np

def meta_analysis_geo(gse_list, gene_of_interest):
    """Perform meta-analysis of gene expression across studies"""
    results = []

    for gse_id in gse_list:
        try:
            gse = GEOparse.get_GEO(geo=gse_id, destdir="./data")

            # Get platform annotation
            gpl = list(gse.gpls.values())[0]

            # Find gene in platform
            if hasattr(gpl, 'table'):
                gene_probes = gpl.table[
                    gpl.table['Gene Symbol'].str.contains(
                        gene_of_interest,
                        case=False,
                        na=False
                    )
                ]

                if not gene_probes.empty:
                    expr_df = gse.pivot_samples('VALUE')

                    for probe_id in gene_probes['ID']:
                        if probe_id in expr_df.index:
                            expr_values = expr_df.loc[probe_id]

                            results.append({
                                'study': gse_id,
                                'probe': probe_id,
                                'mean_expression': expr_values.mean(),
                                'std_expression': expr_values.std(),
                                'num_samples': len(expr_values)
                            })

        except Exception as e:
            print(f"Error in {gse_id}: {e}")

    return pd.DataFrame(results)

# Meta-analysis for TP53
gse_studies = ["GSE100001", "GSE100002", "GSE100003"]
meta_results = meta_analysis_geo(gse_studies, "TP53")
print(meta_results)

安装和设置

Python 库
# Primary GEO access library (recommended)
pip install GEOparse

# For E-utilities and programmatic NCBI access
pip install biopython

# For data analysis
pip install pandas numpy scipy

# For visualization
pip install matplotlib seaborn

# For statistical analysis
pip install statsmodels scikit-learn
配置

设置 NCBI E-utilities 访问:

from Bio import Entrez

# Always set your email (required by NCBI)
Entrez.email = "[email protected]"

# Optional: Set API key for increased rate limits
# Get your API key from: https://www.ncbi.nlm.nih.gov/account/
Entrez.api_key = "your_api_key_here"

# With API key: 10 requests/second
# Without API key: 3 requests/second

常见用例

转录组学研究
  • 下载特定条件下的基因表达数据
  • 比较不同研究中的表达谱
  • 识别差异表达基因
  • 对多个数据集进行荟萃分析
药物反应研究
  • 分析药物处理后的基因表达变化
  • 识别药物反应生物标志物
  • 比较药物在不同细胞系或患者中的作用
  • 构建药物敏感性的预测模型
疾病生物学
  • 研究疾病组织与正常组织中的基因表达
  • 识别疾病相关表达特征
  • 比较患者亚组和疾病阶段
  • 分析表达与临床结局的相关性
生物标志物发现
  • 筛选诊断或预后标志物
  • 在独立队列中验证生物标志物
  • 比较标志物在不同平台上的表现
  • 整合表达数据与临床数据

核心概念

SOFT(Simple Omnibus Format in Text): GEO 的主要文本格式,包含元数据和数据表。可使用 GEOparse 轻松解析。

MINiML(MIAME Notation in Markup Language): GEO 数据的 XML 格式,用于程序化访问和数据交换。

系列矩阵(Series Matrix): 以制表符分隔的表达矩阵,样本为列,基因为行,探针为行。获取表达数据最快捷的格式。

MIAME 合规性: 微阵列实验最低信息要求(Minimum Information About a Microarray Experiment)——GEO 对所有提交数据强制要求的标准化注释。

表达值类型: 不同类型的表达测量值(原始信号、归一化值、对数转换值)。务必检查平台和处理方法。

平台注释: 将探针/特征 ID 映射到基因。对于表达数据的生物学解读至关重要。

GEO2R 网页工具

如需快速分析且无需编写代码,可使用 GEO2R:

速率限制和最佳实践

NCBI E-utilities 速率限制:

  • 不使用 API 密钥:每秒 3 次请求
  • 使用 API 密钥:每秒 10 次请求
  • 在请求之间加入延迟:time.sleep(0.34)(不使用 API 密钥)或 time.sleep(0.1)(使用 API 密钥)

FTP 访问:

  • FTP 下载没有速率限制
  • 批量下载的首选方式
  • 可使用 wget -r 下载整个目录

GEOparse 缓存:

  • GEOparse 会自动将下载的文件缓存到 destdir
  • 后续调用会使用缓存数据
  • 定期清理缓存以节省磁盘空间

最佳实践:

  • 使用 GEOparse 访问系列级数据(最简单)
  • 使用 E-utilities 搜索元数据并执行批量查询
  • 使用 FTP 直接下载文件并执行批量操作
  • 在本地缓存数据,避免重复下载
  • 使用 Biopython 时,务必设置 Entrez.email

资源

references/geo_reference.md

全面的参考文档,涵盖:

  • E-utilities API 规范和端点的详细说明
  • SOFT 和 MINiML 文件格式的完整文档
  • GEOparse 高级用法模式和示例
  • FTP 目录结构和文件命名约定
  • 数据处理流程和归一化方法
  • 常见问题排查和错误处理
  • 特定平台的注意事项和特性

如需深入了解技术细节、复杂查询模式或处理不常见的数据格式,请参阅此参考文档。

重要说明

数据质量注意事项
  • GEO 接受用户提交的数据,质量标准各不相同
  • 务必检查平台注释和处理方法
  • 核实样本元数据和实验设计
  • 谨慎处理不同研究之间的批次效应
  • 考虑重新处理原始数据以确保一致性
文件大小警告
  • 系列矩阵文件可能很大(大型研究的文件可超过 1 GB)
  • 补充文件(例如 CEL 文件)可能非常大
  • 下载前请预留充足的磁盘空间
  • 可考虑分批下载样本
数据使用和引用
  • GEO 数据可免费用于研究
  • 使用 GEO 数据时,务必引用原始研究
  • 引用 GEO 数据库:Barrett 等人(2013),Nucleic Acids Research
  • 检查各数据集是否有使用限制
  • 遵循 NCBI 的程序化访问指南
常见陷阱
  • 不同平台使用不同的探针 ID(需要注释映射)
  • 表达值可能是原始值、标准化值或经过对数转换的值(请检查元数据)
  • 不同研究的样本元数据格式可能不一致
  • 并非所有系列都有系列矩阵文件(较早提交的数据)
  • 平台注释可能已过时(基因已更名、ID 已弃用)

其他资源

评论

支持 Markdown