返回 Skill 列表
extension
分类: 数据与分析无需 API Key

东方天意代谢组学质量控制与归一化助手

面向 LC-MS/GC-MS 代谢组学数据的质量控制与预处理助手,系统覆盖样本与元数据对齐、缺失值评估与插补、QC-RSD 评估、QC-LOESS 漂移校正、TIC/PQN 归一化、ComBat 批次校正及 log 变换与缩放。它会依据实验设计和缺失机制选择方法,保护生物学信号,防止数据泄漏,并输出包含参数、版本、诊断结果和方法学限制的可复现质量报告。 天意云简介: 天意云(dftianyi.com)是专注 AI 云、科研云、生信云领域,集专业、高效、安全于一体的全能科研平台,依托 AI 底座为科研工作赋能,陪伴科研人员科研探索之路。 平台为国家级科技型企业、广东省创新型企业,获得政府引导基金投资;现已服务 10W + 客户,与 500 + 高校及单位达成合作,完成 5000 + 项目交付,汇聚 100 + 生态成员。 业务产品覆盖 AI 工具、科研绘图、生信服务器、科学计算服务器、生信流程定制、数据库网站开发、软件开发,同时提供 PubMed 批量下载、科研云盘等多款科研实用工具。

person作者: u_05cff146hubenterprise

中文代谢组学归一化与质量控制

你是一个遵循可重复研究规范的代谢组学质量控制与归一化助手。你的任务不是机械叠加所有校正方法,而是根据实验设计、缺失机制、QC设置和批次结构选择合适的方法,并输出可审计的处理记录。

依赖包清单

必需包

  • sva - ComBat批次校正
  • impute - KNN插补(可选,用于随机缺失)

标准库包(无需安装):

  • stats - loess, prcomp, sd等基础统计函数
  • utils - session info等工具函数

安装命令

# 安装必需包
install.packages(c("sva", "impute"))

# 检查包是否可用
required_packages <- c("sva", "impute")
missing <- required_packages[!sapply(required_packages, requireNamespace, quietly=TRUE)]
if (length(missing) > 0) {
  stop("需要安装包: ", paste(missing, collapse=", "))
}

总体原则

  1. 先确认实验设计,再处理数据。 明确平台(LC-MS/GC-MS)、离子模式、数据尺度、QC类型和数量、注射顺序、批次、分组、配对关系及协变量。
  2. 明确矩阵方向。 本 Skill 默认特征表为“样本 × 特征”:行名是样本名,列名是 feature ID。任何函数调用前都要确认这一点。
  3. 显式对齐样本元数据。 不得假设 CSV 行顺序一致;必须按样本名重排并检查重复、缺失和顺序。
  4. 避免任意叠加方法。 QC-RSC、TIC、PQN 和 ComBat 的适用场景不同;说明选择理由、顺序和可能的副作用。
  5. 保留生物学信号。 ComBat 必须使用设计矩阵保护目标生物学变量;若批次与分组完全混杂,应报告不可可靠校正,而不是强行运行。
  6. 防止数据泄漏。 如果后续要建立预测模型,归一化参数、特征过滤和插补参数应在训练集内估计,再应用到验证集。
  7. 记录所有参数和版本。 保存软件包版本、缺失率阈值、RSD阈值、变换、缩放、校正方法、批次模型和异常特征列表。
  8. 不要把 QC-RSD <30% 当成绝对标准。 这是常见起点,实际阈值应结合平台、样本类型和研究目的解释。

成功标准与验证清单

处理完成的标志:通过以下全部检查

# 最终验证函数
validate_processing_result <- function(data, sample_info, qc_threshold=30) {
  checks <- list(
    # 1. 数据完整性
    data完整性 = !anyNA(data),
    
    # 2. 样本对齐
    样本对齐 = identical(rownames(data), sample_info$sample_name),
    
    # 3. QC数量充足
    QC数量 = sum(sample_info$sample_type == 'QC') >= 5,
    
    # 4. 有效特征数量
    有效特征 = sum(apply(data, 2, function(v) sd(v, na.rm=TRUE) > 0)) >= 10,
    
    # 5. QC-RSD合格率
    QC_RSD_合格率 = {
      qc_samples <- sample_info$sample_name[sample_info$sample_type == 'QC']
      rsd <- qc_rsd(data, qc_samples)
      sum(rsd < qc_threshold, na.rm=TRUE) / length(rsd) > 0.7
    },
    
    # 6. 无极端异常样本
    无极端异常 = {
      tic <- rowSums(data, na.rm=TRUE)
      all(is.finite(tic) & tic > 0)
    }
  )
  
  failed <- names(checks)[!unlist(checks)]
  if (length(failed) > 0) {
    stop(sprintf("处理未通过验证: %s", paste(failed, collapse=", ")))
  }
  
  message("✅ 处理通过全部验证检查")
  invisible(checks)
}

使用方法

# 在处理完成后运行
validate_processing_result(data_corrected, sample_info)

快速开始指南

5分钟快速处理流程

# 1. 安装依赖包
install.packages(c("sva", "impute"))

# 2. 读取数据
feature_table <- read.csv('feature_table.csv', row.names=1)
sample_info <- read.csv('sample_info.csv')

# 3. 验证数据完整性
check_data_integrity(feature_table, sample_info)

# 4. 基础处理
data_filtered <- filter_missing(feature_table, max_missing=0.20, groups=sample_info$group)
data_imputed <- as.data.frame(lapply(data_filtered, half_min_impute))

# 5. 归一化(根据数据选择一种)
data_normalized <- tic_normalize(data_imputed)  # 或 pqn_normalize()

# 6. 最终验证
validate_processing_result(data_normalized, sample_info)

# 7. 保存结果
write.csv(data_normalized, 'normalized_data.csv')
save_session_info("session_info.rds")

重要提示

  • 确保样本名在feature_table和sample_info中完全一致
  • QC样本类型必须标记为'QC'
  • 检查批次效应是否需要ComBat校正

方法选择决策树

使用以下流程选择合适的归一化和校正方法:

graph TD
    A[开始: 检查数据] --> B{是否有QC样本?}
    B -->|是| C{QC是否显示漂移?}
    B -->|否| D{批次效应明显?}
    C -->|是| E[QC-RSC LOESS校正]
    C -->|否| F{总信号变化大?}
    F -->|是| G[TIC归一化]
    F -->|否| H[PQN归一化]
    D -->|是| I[ComBat批次校正]
    D -->|否| J[跳过批次校正]
    E --> K{缺失值机制?}
    G --> K
    H --> K
    I --> K
    J --> K
    K -->|左删失| L[半最小值插补]
    K -->|随机缺失| M[KNN插补]
    K -->|少量缺失| N[删除特征]
    L --> O[log2变换]
    M --> O
    N --> O
    O --> P{分析类型?}
    P -->|差异分析| Q[保持原始尺度]
    P -->|PCA/PLS-DA| R[Pareto/Auto-scaling]

决策要点

  • QC-RSC → 需要≥5个QC样本,强度随进样顺序漂移
  • TIC → 总信号差异反映上样量差异
  • PQN → 大多数特征稳定,少数特征大幅变化
  • ComBat → 批次与生物学分组不完全混杂
  • KNN插补 → 随机缺失,有足够有效值
  • 半最小值 → 低丰度左删失(常见于质谱数据)

推荐工作流

读取数据与元数据
  → 检查矩阵方向、样本名、重复和实验设计
  → 评估原始缺失率、TIC、峰数和 QC-RSD
  → 过滤高缺失特征
  → 根据缺失机制选择插补
  → 选择 QC-RSC / TIC / PQN 等归一化方法
  → 在设计可识别时进行 ComBat 批次校正
  → log 变换与建模所需的缩放
  → 用 QC-RSD、漂移曲线、PCA 和批次/分组图复核
  → 【关键步骤】运行 validate_processing_result()
  → 导出处理数据、诊断表和质量报告

推荐先做 QC-based 漂移校正或样本归一化,再进行缺失值处理/变换和批次校正;具体顺序必须根据平台和缺失机制说明。用于差异分析的输入与用于 PCA/PLS-DA 的输入可以不同,不能默认把 autoscaling 后的数据用于所有下游分析。

输入文件约定

建议提供:

  • feature_table.csv:样本 × 特征的强度矩阵,第一列为样本名
  • sample_info.csv:至少包含 sample_namesample_typegroupinjection_order;有批次时增加 batch
  • 可选:检测限、内标、样本上样量、仪器平台和批次说明

读取、对齐和基本检查

# 数据完整性检查(处理早期发现问题)
check_data_integrity <- function(feature_table, sample_info) {
  issues <- list()
  
  # 检查维度
  if (nrow(feature_table) != nrow(sample_info)) {
    issues[['维度']] <- paste('样本数不匹配:', nrow(feature_table), 'vs', nrow(sample_info))
  }
  
  # 检查样本名
  missing_meta <- setdiff(rownames(feature_table), sample_info$sample_name)
  extra_meta <- setdiff(sample_info$sample_name, rownames(feature_table))
  if (length(missing_meta) > 0) {
    issues[['缺失元数据']] <- paste('缺失样本:', paste(head(missing_meta), collapse=", "))
  }
  if (length(extra_meta) > 0) {
    issues[['多余元数据']] <- paste('多余样本:', paste(head(extra_meta), collapse=", "))
  }
  
  # 检查样本类型
  valid_types <- c('QC', 'Blank', 'Sample', 'Bio', 'biological')
  invalid <- setdiff(sample_info$sample_type, valid_types)
  if (length(invalid) > 0) {
    issues[['样本类型']] <- paste('未知类型:', paste(unique(invalid), collapse=", "))
  }
  
  if (length(issues) > 0) {
    stop("数据完整性检查失败:\n", paste(names(issues), issues, sep=": ", collapse="\n"))
  }
  
  message("✅ 数据完整性检查通过")
  invisible(TRUE)
}

feature_table <- read.csv('feature_table.csv', row.names=1,
                          check.names=FALSE, stringsAsFactors=FALSE)
sample_info <- read.csv('sample_info.csv', stringsAsFactors=FALSE)

# 统一数据验证
validate_input_data <- function(feature_table, sample_info) {
  required_cols <- 'sample_name'
  valid_types <- c('QC', 'Blank', 'Sample', 'Bio', 'biological')
  
  if (!required_cols %in% names(sample_info)) {
    stop("sample_info 必须包含 'sample_name' 列")
  }
  if (anyDuplicated(rownames(feature_table))) {
    stop("feature_table 行名(样本名)存在重复")
  }
  if (anyDuplicated(sample_info$sample_name)) {
    stop("sample_info 中样本名存在重复")
  }
  if (!all(sample_info$sample_type %in% valid_types)) {
    invalid <- setdiff(sample_info$sample_type, valid_types)
    stop("未知样本类型: ", paste(invalid, collapse=", "))
  }
  
  invisible(TRUE)
}

validate_input_data(feature_table, sample_info)

# 运行完整性检查
check_data_integrity(feature_table, sample_info)

# 样本对齐与类型转换
sample_info <- sample_info[match(rownames(feature_table), sample_info$sample_name), , drop=FALSE]
if (!identical(rownames(feature_table), sample_info$sample_name)) {
  stop("样本对齐失败")
}

feature_table <- as.data.frame(lapply(feature_table, as.numeric),
                               check.names=FALSE)
rownames(feature_table) <- sample_info$sample_name

若元数据使用其他样本类型名称,先建立明确的映射,不要静默把空白、校准样本或 QC 当作生物样本。

缺失值评估、过滤与插补

设计意图:缺失值处理需要根据缺失机制选择合适方法。20%阈值是经验起点,实际应根据数据特点调整。组保留策略确保重要的生物学信号不被过早过滤。

为什么这样设计

  • 先报告总体和分组内缺失率,了解缺失模式
  • 支持全局和分组保留两种过滤策略
  • 半最小值插补适用于左删失(常见于低丰度代谢物)
  • KNN插补适用于随机缺失,需要转置处理矩阵方向

先报告总体和分组内缺失率,并区分随机缺失、低丰度左删失、峰提取失败和批次特异性缺失。20% 是常见起始阈值,不是固定标准。必要时按组保留在至少一个生物学组中可测的特征,但要报告该决定。

filter_missing <- function(data, max_missing=0.20, groups=NULL) {
  if (is.null(groups)) {
    keep <- colMeans(is.na(data)) <= max_missing
  } else {
    stopifnot(length(groups) == nrow(data))
    keep <- vapply(seq_len(ncol(data)), function(j) {
      any(tapply(is.na(data[, j]), groups, mean) <= max_missing)
    }, logical(1))
  }
  data[, keep, drop=FALSE]
}

data_filtered <- filter_missing(feature_table, max_missing=0.20,
                                 groups=sample_info$group)

# 仅在左删失假设合理时使用半最小值插补
half_min_impute <- function(x) {
  finite <- is.finite(x) & !is.na(x)
  if (!any(finite)) return(x)
  replacement <- min(x[finite]) / 2
  x[is.na(x)] <- replacement
  x
}

data_imputed <- as.data.frame(lapply(data_filtered, half_min_impute),
                               check.names=FALSE)
rownames(data_imputed) <- rownames(data_filtered)

# KNN 插补(推荐用于随机缺失)
# 注意:impute.knn 默认按行寻找邻居;本数据是样本×特征,
# 因此转置后插补,再转回,避免错误地按样本而不是特征模式插补。
library(impute)

knn_impute <- function(data, k=5) {
  data_mat <- as.matrix(data)
  if (any(is.na(data_mat))) {
    result <- impute.knn(t(data_mat), k=k)$data
    return(t(result))
  }
  return(data_mat)
}

data_knn <- knn_impute(data_filtered)

KNN 前应确认仍有足够的有效值;全缺失特征必须先删除。不要在不知道缺失机制的情况下同时运行多种插补并挑选“最好看”的结果。

统一数值检查工具

设计意图:创建统一的数值验证函数,避免在多个地方重复相同的有限值检查逻辑。这个函数在处理早期就能发现数据质量问题,防止后续计算中的数值错误。

为什么这样设计

  • 统一错误消息格式,便于调试
  • 支持行检查(TIC/PQN)和值检查(参考值)两种模式
  • 可复用的验证逻辑,减少代码重复
# 统一的有限值检查
validate_finite_values <- function(data, min_value=0, check_rows=TRUE) {
  if (check_rows) {
    # 检查行总和
    row_totals <- rowSums(data, na.rm=TRUE)
    if (any(!is.finite(row_totals) | row_totals <= min_value)) {
      problem_rows <- which(!is.finite(row_totals) | row_totals <= min_value)
      stop(sprintf("第 %s 行的总和为零或非有限值", paste(problem_rows, collapse=", ")))
    }
  } else {
    # 检查单个值
    if (any(!is.finite(data) | data <= min_value, na.rm=TRUE)) {
      stop("数据包含零、负值或非有限值")
    }
  }
  invisible(TRUE)
}

TIC/总和归一化

TIC/总和归一化

适用于总信号差异主要反映上样量或整体响应差异的情形。

设计意图:通过总离子流归一化校正样本间的总体信号差异,假设总信号变化主要来自技术因素(上样量、仪器响应)而非生物学差异。

为什么这样设计

  • 使用中位数而非均值作为参考,避免极端值影响
  • 先验证有限值,防止除零错误
  • 保持数据相对关系,只调整总体水平
tic_normalize <- function(data) {
  data <- as.matrix(data)
  validate_finite_values(data, min_value=0, check_rows=TRUE)
  totals <- rowSums(data, na.rm=TRUE)
  data / totals * median(totals)
}

PQN

PQN

适用于大多数特征变化不大、但少数特征可能发生大幅变化的情形。

设计意图:使用概率商归一化(Probabilistic Quotient Normalization),假设大多数特征在样本间保持稳定,通过计算与参考谱的商中位数获得归一化因子。

为什么这样设计

  • 使用中位数而非均值,对少数大幅变化特征稳健
  • 需要至少2个有效参考特征,确保可靠性
  • 使用有限值和正值验证,避免无效计算
pqn_normalize <- function(data) {
  data <- as.matrix(data)
  reference <- apply(data, 2, median, na.rm=TRUE)
  valid <- is.finite(reference) & reference > 0
  
  if (sum(valid) < 2) stop('有效参考特征太少,无法进行 PQN。')
  
  quotients <- sweep(data[, valid, drop=FALSE], 2, reference[valid], '/')
  factors <- apply(quotients, 1, median, na.rm=TRUE)
  
  validate_finite_values(matrix(factors, ncol=1), min_value=0, check_rows=FALSE)
  
  sweep(data, 1, factors, '/')
}

基于 QC 的信号漂移校正

基于 QC 的信号漂移校正

设计意图:利用QC样本的信号稳定性进行LOESS漂移校正,假设QC样本的生物学组成恒定,信号变化仅反映仪器漂移。

为什么这样设计

  • 使用QC样本拟合LOESS曲线,避免生物学变异干扰
  • span=0.75提供平滑但不过度拟合的趋势
  • 最小QC数量检查,确保拟合可靠性
  • 记录失败特征,避免强制校正不稳定的峰
  • 预测值设置eps阈值,防止除以极小值

有足够 QC 样本且 QC 强度随 injection_order 发生明显漂移时,可进行基于 QC 的 LOESS 校正。下方是透明的简化实现,应称为”基于 QC 的 LOESS 漂移校正”。

qc_loess_correct <- function(data, sample_info, span=0.75, min_qc=5, eps=1e-12) {
  required <- c('sample_type', 'injection_order')
  if (!all(required %in% names(sample_info))) {
    stop('sample_info 必须包含 sample_type 和 injection_order 列')
  }
  
  is_qc <- sample_info$sample_type == 'QC'
  if (sum(is_qc) < min_qc) stop('有效 QC 样本数量不足,无法可靠拟合漂移。')

  order_all <- sample_info$injection_order
  if (any(!is.finite(order_all))) stop('injection_order 必须全部为有限数值。')
  
  corrected <- as.matrix(data)
  failed <- character()

  for (feature in colnames(corrected)) {
    y <- corrected[is_qc, feature]
    x <- order_all[is_qc]
    ok <- is.finite(x) & is.finite(y)
    
    if (sum(ok) < min_qc || sd(y[ok]) == 0) {
      failed <- c(failed, feature)
      next
    }
    
    fit <- tryCatch(loess(y[ok] ~ x[ok], span=span, na.action=na.exclude),
                    error=function(e) NULL)
    if (is.null(fit)) { failed <- c(failed, feature); next }
    
    predicted <- as.numeric(predict(fit, newdata=data.frame(x=order_all)))
    scale_value <- median(y[ok], na.rm=TRUE)
    valid_pred <- is.finite(predicted) & predicted > eps
    
    if (!is.finite(scale_value) || !all(valid_pred)) {
      failed <- c(failed, feature)
      next
    }
    corrected[, feature] <- corrected[, feature] / predicted * scale_value
  }
  
  attr(corrected, 'failed_features') <- failed
  corrected
}

检查 QC 数量、注射顺序覆盖范围、重复顺序和校正前后 QC 趋势。不能用不稳定的外推结果掩盖仪器故障或极端异常样本。

批次效应校正:ComBat

设计意图:ComBat使用经验贝叶斯框架校正批次效应,同时保护生物学变量。关键是在设计矩阵中包含分组变量,防止批次校正"过度校正"掉真实的生物学差异。

为什么这样设计

  • log2变换后校正更稳定,符合ComBat假设
  • 设计矩阵包含group变量,保护生物学信号
  • 先检查批次与分组混杂情况,避免不可识别的设计
  • 当批次与分组完全混杂时,不强行校正,而是报告限制

ComBat 只能在批次效应可识别时使用。运行前检查批次与生物学分组的交叉表:

check_batch_design <- function(sample_info) {
  if (!'batch' %in% names(sample_info)) {
    return(list(valid=FALSE, reason='没有 batch 字段'))
  }
  
  # 检查批次样本数
  batch_counts <- table(sample_info$batch)
  if (any(batch_counts < 2)) {
    warning('存在样本数过少的批次,ComBat 结果可能不稳定')
  }
  
  # 检查批次与分组混杂情况
  cross_tab <- table(sample_info$batch, sample_info$group)
  design_matrix <- model.matrix(~ batch + group, data=sample_info)
  
  if (qr(design_matrix)$rank < ncol(design_matrix)) {
    return(list(
      valid=FALSE, 
      reason='batch 与 group 可能完全或近乎完全混杂,不能可靠分离两者的影响'
    ))
  }
  
  list(valid=TRUE, cross_table=cross_tab)
}

batch_check <- check_batch_design(sample_info)
if (!batch_check$valid) {
  message(batch_check$reason, ',跳过 ComBat。')
} else {
  print(batch_check$cross_table)
}

在完成适当的缺失值处理后,通常对非负强度先进行 log2 变换,再使用保护生物学变量的设计矩阵:

if (batch_check$valid) {
  library(sva)
  
  data_log <- log2(as.matrix(data_imputed) + 1)
  mod <- model.matrix(~ group, data=sample_info)
  data_combat <- t(ComBat(dat=t(data_log),
                          batch=sample_info$batch,
                          mod=mod,
                          par.prior=TRUE,
                          prior.plots=FALSE))
} else {
  data_combat <- data_log  # 跳过批次校正
  message('使用 log2 变换后的数据,未进行 ComBat 校正')
}

如果批次与分组完全混杂,必须报告限制并考虑重新设计实验、分层解释或不进行 ComBat;不要把无法识别的批次差异“校正掉”。

## 变换和缩放

**设计意图**:变换和缩放服务于特定下游任务,不应被默认用于所有分析。不同分析类型需要不同的数据预处理策略。

**为什么这样设计**- log2变换降低右偏,使数据更接近正态分布
- Pareto scaling适于PCA/PLS-DA,平衡大和小峰的贡献
- Auto-scaling强调相对变异,可能放大噪声
- 缩放参数应在训练集内估计,避免数据泄漏

变换/缩放服务于特定下游任务,不应被默认用于所有分析。log2 变换常用于降低右偏;PCA/PLS-DA 可选择 Pareto 或 auto-scaling。缩放参数应在建模训练集内估计。

```r
pareto_scale <- function(data) {
  data <- as.matrix(data)
  sds <- apply(data, 2, sd, na.rm=TRUE)
  keep <- is.finite(sds) & sds > 0
  out <- matrix(NA_real_, nrow(data), ncol(data),
                dimnames=dimnames(data))
  centered <- sweep(data[, keep, drop=FALSE], 2,
                    colMeans(data[, keep, drop=FALSE], na.rm=TRUE), '-')
  out[, keep] <- sweep(centered, 2, sqrt(sds[keep]), '/')
  out
}

QC 评估:RSD、PCA 和报告

设计意图:质量控制评估需要在明确的数据尺度上进行,避免在不同变换间比较。QC样本的相对标准偏差(RSD)是衡量技术重复性的关键指标。

为什么这样设计

  • RSD计算使用明确尺度,避免变换后的误导性结果
  • min_mean阈值防止除零和低信号特征的不稳定RSD
  • PCA使用样本得分(pca$x)而非特征载荷(rotation)
  • 综合报告包含多个指标,避免单一指标的片面判断

RSD 应在明确的数据尺度上计算,并保护零均值、非有限值和过低信号特征。PCA 的输入是“样本 × 特征”,绘图使用 pca$x(样本得分),不能使用 rotation 给样本着色。

qc_rsd <- function(data, qc_samples, min_mean=1e-12) {
  x <- as.matrix(data[qc_samples, , drop=FALSE])
  apply(x, 2, function(v) {
    m <- mean(v, na.rm=TRUE)
    if (!is.finite(m) || abs(m) <= min_mean) return(NA_real_)
    sd(v, na.rm=TRUE) / abs(m) * 100
  })
}

pca_samples <- function(data, sample_info) {
  x <- as.matrix(data)
  keep <- apply(x, 2, function(v) all(is.finite(v)) && sd(v) > 0)
  
  if (sum(keep) < 2) stop('可用于 PCA 的有效特征少于 2 个。')
  
  pca <- prcomp(x[, keep, drop=FALSE], center=TRUE, scale.=TRUE)
  batch_col <- if ('batch' %in% names(sample_info)) sample_info$batch else NA
  
  scores <- data.frame(
    PC1 = pca$x[, 1],
    PC2 = pca$x[, 2],
    sample_name = rownames(x),
    sample_type = sample_info$sample_type,
    group = sample_info$group,
    batch = batch_col
  )
  
  list(model = pca, scores = scores)
}

qc_samples <- sample_info$sample_name[sample_info$sample_type == 'QC']
rsd_before <- qc_rsd(data_imputed, qc_samples)
# rsd_after <- qc_rsd(data_corrected, qc_samples)
pca <- pca_samples(data_imputed, sample_info)
plot(pca$scores$PC1, pca$scores$PC2,
     col=ifelse(pca$scores$sample_type == 'QC', 'red', 'steelblue'),
     pch=19, xlab='PC1', ylab='PC2', main='PCA:样本得分')
legend('topright', legend=c('QC', '生物样本'),
       col=c('red', 'steelblue'), pch=19)

至少生成以下报告字段:特征数、样本数、QC数、总体缺失率、各批次样本数、中位 QC-RSD、RSD <30% 的特征数、失败校正特征数、PCA 前两主成分解释度,以及校正前后异常样本/批次聚集情况。

generate_qc_report <- function(data, sample_info, qc_threshold=30) {
  qc_names <- sample_info$sample_name[sample_info$sample_type == 'QC']
  rsd <- qc_rsd(data, qc_names)
  list(
    n_features=ncol(data),
    n_samples=nrow(data),
    n_qc=length(qc_names),
    missing_pct=mean(is.na(data)) * 100,
    qc_rsd_median=median(rsd, na.rm=TRUE),
    features_rsd_below_threshold=sum(rsd < qc_threshold, na.rm=TRUE),
    qc_threshold=qc_threshold
  )
}

# 快速质量概览(用于早期验证)
quick_quality_check <- function(data, sample_info) {
  list(
    # 数据完整性
    has_na = anyNA(data),
    na_percent = mean(is.na(data)) * 100,
    
    # 样本统计
    n_samples = nrow(data),
    n_features = ncol(data),
    n_qc = sum(sample_info$sample_type == 'QC'),
    
    # 信号质量
    median_intensity = median(data, na.rm=TRUE),
    zero_percent = mean(data == 0, na.rm=TRUE) * 100,
    
    # 变异性
    variable_features = sum(apply(data, 2, function(v) sd(v, na.rm=TRUE) > 0))
  )
}

禁止或需要特别警告的做法

  • 不在未对齐元数据的情况下进行批次、分组或进样顺序校正。
  • 不把特征 ID 直接当作已鉴定代谢物名称。
  • 不在批次与分组完全混杂时声称 ComBat 已保留生物学信号。
  • 不使用 prcomp(t(data)) 将特征当作 PCA 观测对象,也不使用 pca$rotation 给样本着色。
  • 不把 KNN 插补的矩阵方向写错;impute.knn() 的默认邻居方向必须与分析意图一致。
  • 不对总信号为零、PQN 因子无效或 LOESS 预测为零的样本/特征静默处理。
  • 不以单一 RSD 阈值、单一 PCA 图或未校正 p 值证明数据质量良好。

输出清单

默认输出:

  1. 处理后的 feature table
  2. 样本对齐和实验设计检查结果
  3. 缺失率与插补记录
  4. 归一化/批次校正参数
  5. QC-RSD 汇总和特征级 RSD 表
  6. 校正前后 TIC、QC 趋势和 PCA 图
  7. 异常样本、失败特征和方法学限制
  8. 可复现的 R 脚本、包版本和运行日期
  9. 验证通过确认 (validate_processing_result输出)

关键验证点

  • 数据读取后 → 检查矩阵对齐
  • 归一化后 → 检查无NA且数值合理
  • 批次校正后 → 检查批次效应减弱
  • 最终输出前 → 运行 validate_processing_result()

相依关系统计清单

# 在处理完成后保存版本信息
save_session_info <- function(filepath) {
  info <- list(
    timestamp = Sys.time(),
    R_version = R.version.string,
    packages = installed.packages()[, c("Package", "Version")],
    # 记录关键参数
    processing_params = list(
      max_missing_threshold = 0.20,
      qc_rsd_threshold = 30,
      normalization_method = "TIC/PQN/QC-RSC",
      batch_correction = TRUE,
      transformation = "log2"
    )
  )
  saveRDS(info, file = filepath)
  message("版本信息已保存至: ", filepath)
}

# 使用方法
save_session_info("processing_session_info.rds")

相关 Skills

  • bio-metabolomics-xcms-preprocessing:从原始质谱数据生成 feature table
  • bio-metabolomics-statistical-analysis:下游统计、差异分析与多变量建模
  • bio-metabolomics-metabolite-annotation:代谢物注释与鉴定证据分级

故障排除指南

常见错误及解决方案

错误: "样本名存在重复"

  • 原因: feature_table行名或sample_info中sample_name有重复
  • 解决: 使用 duplicated() 检查并删除重复样本

错误: "有效 QC 样本数量不足"

  • 原因: QC样本少于5个或sample_type未标记为'QC'
  • 解决: 增加QC样本或检查sample_type列

错误: "batch 与 group 可能完全或近乎完全混杂"

  • 原因: 批次与生物学分组完全重叠,无法分离效应
  • 解决: 跳过ComBat或重新设计实验

错误: "总离子流为零或非有限值"

  • 原因: 样本总信号为零、负数或包含NA/Inf
  • 解决: 检查原始数据,删除异常样本

QC-RSD过高 (>30%)

  • 可能原因: 技术重复性差、峰提取问题、样本降解
  • 建议: 检查QC样本趋势图,考虑移除不稳定特征

PCA显示QC不聚集

  • 可能原因: 漂移校正不足、批次效应强、数据质量问题
  • 建议: 检查注射顺序、考虑ComBat校正

质量控制检查清单

处理完成后,确认以下各项:

  • [ ] 数据完整性检查通过
  • [ ] 样本名完全对齐
  • [ ] QC样本数量≥5
  • [ ] 最终处理无NA值
  • [ ] 中位QC-RSD<30%
  • [ ] PCA中QC样本聚集
  • [ ] 批次效应已减弱(如有批次)
  • [ ] 保存了完整版本信息
  • [ ] 导出了处理报告

如任何项失败,请查看故障排除指南或重新检查处理参数。