自定义函数出现“Object not found”错误:design.matrix未找到问题排查
错误原因及解决方案
错误原因分析
- 参数不匹配:函数定义的输入参数为
df.input,但调用时使用df = test,导致函数内部无法正确获取输入数据集(若为笔误则忽略,但属于潜在问题)。 - 未定义变量
df:topTable中number = nrow(df)的df未定义,函数中对应的输入数据集是df.input,此处属于变量名错误。 - 缺失
protein.meta对象:代码中尝试合并protein.meta与结果,但该对象既不是函数参数也未在函数内定义,会触发报错中断循环,进而导致后续迭代中变量查找异常。 - 依赖包未显式加载:
str_split属于stringr包,函数未加载该包,若环境未预先加载会导致treatment分割失败。 - 拼写错误:
constrast.matrix应为contrast.matrix,虽不直接引发错误,但不符合代码规范。 - 硬编码重复数:
group创建时硬编码每组2个重复,若数据重复数变化会导致设计矩阵与数据不匹配。
修复后的函数代码
library(limma) library(stringr) library(dplyr) mod.t.test <- function( df.input, control, treatment, protein.meta = NULL # 添加可选参数,允许传入蛋白元数据 ){ # 定义对比数据集 control <- as.character(control) treatment <- str_split(treatment, pattern = "\\s+|;|,")[[1]] comparison <- data.frame(control, treatment, stringsAsFactors = FALSE) # 存储所有结果的列表 result_list <- list() # 执行校正t检验循环 for (n in 1:nrow(comparison)){ # 子集化对比数据 dat <- df.input %>% dplyr::select(matches(paste0("^", comparison$control[n], "|^", comparison$treatment[n]))) # 构建分组向量(自动识别重复数) control_cols <- grep(paste0("^", comparison$control[n]), colnames(dat)) treatment_cols <- grep(paste0("^", comparison$treatment[n]), colnames(dat)) group <- factor(c(rep(comparison$control[n], length(control_cols)), rep(comparison$treatment[n], length(treatment_cols))), levels = c(comparison$control[n], comparison$treatment[n])) cat("=== 对比", n, ":", comparison$treatment[n], "vs", comparison$control[n], "===\n") cat("分组信息:\n") print(group) # 构建设计矩阵 design.matrix <- model.matrix(~0 + group) row.names(design.matrix) <- colnames(dat) cat("\n设计矩阵:\n") print(design.matrix) # 构建对比矩阵(修正拼写错误) contrast.matrix <- makeContrasts( contrasts = paste(colnames(design.matrix)[2], "-", colnames(design.matrix)[1], sep = ""), levels = design.matrix ) cat("\n对比矩阵:\n") print(contrast.matrix) # 拟合模型并计算校正t检验 dat.fit <- lmFit(dat, design = design.matrix) dat.fit2 <- contrasts.fit(fit = dat.fit, contrasts = contrast.matrix) dat.fit2 <- eBayes(dat.fit2, robust = TRUE) # 提取显著性结果(修正nrow(df)为nrow(dat)) dat.significance <- topTable(dat.fit2, coef = colnames(contrast.matrix), adjust.method = "fdr", number = nrow(dat), sort.by = "none", confint = TRUE) %>% dplyr::select(logFC, AveExpr, `P.Value`, `adj.P.Val`) dat.significance <- dat.significance %>% mutate(UniprotID = rownames(dat.significance)) %>% relocate(UniprotID) # 将UniprotID移至第一列 # 合并蛋白元数据(若传入) if (!is.null(protein.meta)) { dat.significance <- left_join(protein.meta, dat.significance, by = "UniprotID") } # 存储结果到列表 result_name <- paste(comparison$treatment[n], comparison$control[n], sep = "_vs_") result_list[[result_name]] <- dat.significance cat("\n=== 完成对比", n, "===\n\n") } # 返回结果列表 return(result_list) }
关键修复说明
- 参数匹配修正:调用时使用
df.input = test,或修改函数参数名为df以匹配调用习惯。 - 未定义变量修复:将
nrow(df)改为nrow(dat),确保返回所有结果行。 protein.meta处理:设为可选参数,用left_join合并(比cbind更安全,避免行顺序问题),不传入则跳过合并。- 依赖包显式加载:添加
library(stringr)和library(dplyr),确保函数独立运行。 - 自动识别重复数:通过列名匹配自动计算每组重复数,提升函数通用性。
- 结果存储优化:改用列表存储所有比较结果,避免环境变量混乱,方便后续处理。
- 拼写错误修正:将
constrast.matrix改为contrast.matrix。
调用示例
# 假设test是你的数据集 results <- mod.t.test(df.input = test, control = "vehicle", treatment = "treatment1,treatment2") # 查看treatment1 vs vehicle的结果 print(results$treatment1_vs_vehicle) # 查看treatment2 vs vehicle的结果 print(results$treatment2_vs_vehicle)
内容的提问来源于stack exchange,提问作者Chemist learns to code
相关产品推荐
相关产品推荐

