乐于分享
好东西不私藏

一文搞定GEO数据分析:从下载到生存分析前处理全流程(手把手教程)

一文搞定GEO数据分析:从下载到生存分析前处理全流程(手把手教程)


GEO数据库下载与表达矩阵处理全流程;以GSE26942为例


前言

GEO(Gene Expression Omnibus)是 NCBI 维护的基因表达数据库,收录了海量公开的芯片和测序数据。

本文以 GSE26942(胃癌相关数据集)为例,手把手演示如何用 R 语言完成数据的下载与预处理。

第一步:下载 GEO 数据

使用 GEOquery 包可以一行代码完成数据下载,若本地已存在文件则自动读取,无需重复下载。

# 如未安装,先运行下面两行# BiocManager::install("GEOquery")# install.packages("stringr")library(GEOquery)library(stringr)setwd('./GEO_data')gset <- getGEO("GSE26942",               destdir = ".",               AnnotGPL = FALSE,               getGPL  = FALSE)#本地读取技巧:若已手动下载 GSE26942_series_matrix.txt.gz,可直接用gset <- getGEO(filename = "GSE26942_series_matrix.txt.gz",AnnotGPL = F, destdir = "./",getGPL=F)

第二步:提取表达矩阵 & 判断是否需要 log 转换

芯片数据常见两种形态:原始强度值(通常 > 100) 和已 log 转换值(分布在 0~15 左右)。直接用分位数判断,避免二次 log 导致数据失真。

dat <- exprs(gset)ex  <- datqx  <- as.numeric(quantile(ex, c(0,.25,.5,.75,.99,1), na.rm=TRUE))LogC <- (qx[5] > 100) ||        (qx[6] - qx[1] > 50 && qx[2] > 0) ||        (qx[2] > 0 && qx[2] < 1 && qx[4] > 1 && qx[4] < 2)if (LogC) {  ex[which(ex <= 0)] <- NA  dat <- log2(ex)  cat("✓ log2 转换完成\n")else {  cat("✓ 数据已转换,无需处理\n")}

第三步:探针 ID → 基因 Symbol 注释

芯片数据以探针ID为行名,必须借助 GPL 平台注释文件将其转换为基因 Symbol,才能与其他数据集对接分析。 

GPL 文件下载地址:进入 https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GPL6947,页面底部找到 “Full Table” 下载 .txt 文件,文件名类似 GPL6947-XXXXX.txt

读取 GPL 注释文件并提取 Symbolgpl <- read.table("GPL6947-13512.txt",                   header = TRUE, fill = TRUE,                   sep = "\t", comment.char = "#",                   quote = "")ids <- gpl[, c("ID""Symbol")]colnames(ids) <- c('probe_id''symbol')# 提取 Symbol(部分平台用 "///" 分隔多字段)ids$symbol <- trimws(str_split(ids$symbol, '///', simplify=TRUE)[,1])# 过滤无注释探针ids <- ids[ids$symbol != '' & ids$symbol != '---', ]

第四步:多探针取最大值(或均值)去重

一个基因可能对应多个探针,常见处理策略有两种,选其一即可:

参数
说明
aggregate(. ~ symbol, max)
取最大值
aggregate(. ~ symbol, mean)
取均值
# 过滤 + 合并ids   <- ids[ids$probe_id %in% rownames(dat), ]dat   <- dat[ids$probe_id, ]dat   <- cbind(ids, dat)# 去重:取每个基因表达量最大的探针dat <- aggregate(. ~ symbol, data = dat, max)# 整理行名,去掉辅助列rownames(dat) <- dat[, 1]dat <- dat[, -c(12)]

第五步:导出最终矩阵

final_data <- data.frame(ID = rownames(dat), dat)write.table(final_data,            file  = "GSE26942_expr.txt",            sep   = "\t",            quote = FALSE,            row.names = FALSE)

第六步:提取临床信息

用 pData() 提取样本的临床信息,先用 colnames() 看一下有哪些字段,然后导出为CSV文件备用。

pd <- pData(gset)colnames(pd)write.csv(pd, 'clinical_GSE26942.csv', row.names = TRUE)

第七步:不包含完整信息

这个数据集有个特殊情况:GEO页面上存的临床信息不包含完整的生存数据,需要去读文章的补充材料。 

对应的文章发表在 Nature Communications,补充表格就是这个xlsx文件: 这里用patient ID作为关联键,把两个表合并,然后重命名为我们熟悉的 OS 和 OS.time,这样后续做生存分析就可以直接用了。

dat_surv <- read_excel("41467_2018_4179_MOESM5_ESM.xlsx")pd <- pd %>%  rownames_to_column("ID") %>%  rename(Patients_ID = `patient:ch1`) %>%  select(ID, Patients_ID)pd1 <- merge(pd, dat_surv, by = 'Patients_ID')pd1 <- pd1 %>%  rename(OS = `Death (1=yes, 0=no)`,         OS.time = `OS.m`) %>%  select(ID, OS, OS.time)write.csv(pd1,file = "cli_GSE26942.csv",row.names = F)

六、小结

本流程以 GSE26942 为例,系统梳理了 GEO 数据从下载、表达矩阵处理到临床信息整合的完整分析步骤。

核心思路是:数据获取 → 标准化处理 → 注释转换 → 去重整合 → 临床匹配 → 输出可分析矩阵

🔔 本文数据及完整代码已整理好,关注公众号后私信回复「GEO数据处理下载」即可免费领取,觉得有帮助欢迎转发分享 🌱

‘写作不易,求赞鸡腿~🍗’