R语言批量读取TCGA数据并整合表达矩阵的方法

一只小鹿
一只小鹿
发布时间:2026-10-16 | 6人浏览过
原创

在处理TCGA等大型生物数据集时,手动逐个读取文件效率极低。本文详解如何利用R语言编写脚本,自动遍历文件夹、解析JSON元数据以匹配TCGA ID,并使用data.table包高效读取每个文件的关键列,最后通过for循环或lapply将结果整合为标准的基因表达矩阵。

准备条件与环境配置

处理此类任务通常需要安装并加载以下核心包:

  • jsonlite:用于解析TCGA提供的metadata JSON文件。
  • data.table:提供极速的文件读取函数fread,适合处理大文件。

确保本地目录结构清晰,通常分为源数据目录(如rawdata/)、中间处理目录(如data_in_one/)和输出目录。getwd()命令用于获取当前工作目录路径。

第一步:整理原始文件至单一目录

原始TCGA数据通常分散在多个子文件夹中,为方便统一读取,需先将其复制到同一个文件夹内。

第1步:创建目标文件夹并复制文件

目的:将所有需要处理的计数文件集中到一个平面目录,避免嵌套路径带来的复杂性。

操作逻辑:

  1. 使用dir.create()创建目标文件夹(例如data_in_one)。
  2. 列出源目录(如rawdata/)下的所有子文件夹名称。
  3. 构建每个子文件夹的绝对路径,并查找其中的特定模式文件(如包含*.counts的文件)。
  4. 使用file.copy()将找到的文件复制到目标文件夹。
# 创建目标文件夹
dir.create("data_in_one") 

# 查看原路径内容
print(dir("rawdata/")) 

# 遍历原始子文件夹
for (dirname in dir("rawdata/")){  
  # 1. 构建单个源文件夹的绝对路径
  mydir <- paste0(getwd(), "/rawdata/", dirname)
  
  # 2. 查找符合模式的文件(例如 *.counts 文件)
  file <- list.files(mydir, pattern = "*.counts")
  
  # 3. 构建完整文件路径
  myfile <- paste0(mydir, "/", file)
  
  # 4. 复制到统一的目标文件夹
  file.copy(myfile, "data_in_one")  
}

第二步:解析元数据并建立ID映射

文件名通常包含UUID,而分析时需要的是标准化的TCGA ID(如TCGA-XX-XXXX-01A-...)。这部分需要从metadata JSON中提取对应关系。

第2步:从JSON读取关联信息并提取TCGA ID

入口: metadata.cart.json 文件。

动作:

  1. 使用jsonlite::fromJSON()读取元数据。
  2. 筛选出file_name和associated_entities字段。
  3. 遍历行,从associated_entities列表中提取entity_submitter_id,即TCGA ID。
  4. 将TCGA ID添加到新的第三列。
library(jsonlite)

# 读取metadata
metadata <- jsonlite::fromJSON("data/metadata.cart.2021-05-28.json")

# 提取关键列
metadata_id <- metadata[, c("file_name", "associated_entities")]

# 初始化新列用于存储TCGA ID
# 注意:这里假设metadata_id已经准备好,仅展示填充逻辑
for (i in 1:nrow(metadata_id)){
  print(i)
  # 从复杂的嵌套列表中提取 submitter_id
  metadata_id[i, 3] <- metadata_id$associated_entities[i][[1]]$entity_submitter_id
}

# 重命名新列为 TCGA_id
colnames(metadata_id)[3] <- "TCGA_id"

第3步:排序以确保文件与ID对齐

重要参数: files变量需与上一步复制文件的顺序一致。

由于文件系统读取顺序可能不固定,需确保metadata_id的行顺序与实际读取的files向量顺序完全一致。通常做法是将文件名设为行名,然后按实际文件名向量排序。

# 将文件名设为行名
rownames(metadata_id) <- metadata_id[, 1]

# 按照实际我们要读取的文件顺序(files)重新排列数据框
metadata_id <- metadata_id[files, ]

第三步:定义读取函数并测试

使用data.table::fread可以大幅加快读取速度。我们需要一个函数,只读取文件的第二列(通常是计数值),忽略第一列(Gene ID)以便后续合并。

第4步:构建提取第二列的辅助函数

输入: 文件名。

返回: 数值向量(文件内容的第2列)。

# 如果需要可以使用 data.table 包的 fread
# install.packages("data.table")
library(data.table)

myfread <- function(filename){
  # paste0 拼接完整路径,$V2 选取第二列
  data.table::fread(paste0("data_in_one/", filename))$V2
}

# 测试第一个文件
test <- myfread(files[1])
print(head(test))

第四步:批量读取并整合表达矩阵

这是核心步骤,将每个文件的内容作为一列添加到大容器中。

第5步:方法一 - 使用 for 循环预分配容器

操作说明:

  1. 首先读取第一个文件的第一列(Gene IDs)作为行名基础。
  2. 创建一个空的data.frame,仅包含gene_id列。
  3. 遍历所有文件,将每列结果填入新列。
  4. 循环结束后,设置列名为TCGA ID。
# 1. 提取所有文件的 Gene ID (第一列)
gene_id <- data.table::fread(paste0("data_in_one/", files[1]))$V1

# 2. 创建初始数据框
gene_id <- data.table::fread(paste0("data_in_one/", files[1]))$V1
expr_df <- data.frame(gene_id = gene_id)

# 3. 循环填入每一列
for (i in 1:length(files)){
  print(paste("Reading file:", i))
  expr_df[, i+1] <- myfread(files[i])
}

# 4. 设置列名:第一列为 gene_id,其余为 TCGA ID
colnames(expr_df) <- c("gene_id", metadata_id$TCGA_id)

# 清理:有时尾部存在注释行或空行,可根据实际情况删除
# tail(expr_df$gene_id, 10) # 查看末尾情况
# 示例:去掉最后5行非编码区或注释
expr_df <- expr_df[1:(nrow(expr_df)-5), ]

# 保存结果
save(expr_df, file = "output/BRCA_RNASEQ_exprdf.Rdata")

第6步:方法二 - 使用 lapply + do.call 简化代码

优势: 相比显式for循环,lapply更简洁且不易出错。

  1. 使用lapply对文件列表应用myfread函数,得到一个列表。
  2. 使用do.call(cbind, ...)将列表合并为矩阵。
  3. 转换为data.frame并赋予行列名。
# 1. 对每个文件应用读取函数
dd <- lapply(files, myfread)

# 2. 按列合并
dd_matrix <- do.call(cbind, dd)

# 3. 转为数据框
expr_df <- as.data.frame(dd_matrix)

# 4. 设置列名(TCGA ID)和行名(Gene ID)
colnames(expr_df) <- metadata_id$TCGA_id
rownames(expr_df) <- data.table::fread(paste0("data_in_one/", files[1]))$V1

通过以上步骤,即可将一个目录下零散的表达量文件整合为标准格式的基因表达矩阵,方便后续进行差异表达分析(如DESeq2或edgeR)。以上就是R语言批量读取某路径下文件内容并整合矩阵的详细内容,更多关于R语言数据预处理的技术资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表