如何在R循环中为DataFrame添加错误信息列?
在R循环处理文件时记录错误/警告到DataFrame
核心思路
用tryCatch()捕获循环中每个文件处理时产生的警告和错误,将这些信息存入新增的message列,同时保证循环不会因单个文件出错而中断。
修改步骤及代码
1. 初始化DataFrame时新增message列
修改store的定义,添加用于存储消息的列,避免字符串自动转因子:
store <- data.frame( "Filename"=NA, "pval"=NA, "numpar.full"=NA, "dev"=NA, "p.estim"=NA, "message"=NA, # 新增列记录错误/警告 stringsAsFactors = FALSE )
2. 用tryCatch包裹文件处理逻辑
将循环内的所有处理代码放入tryCatch结构中,分别捕获警告和错误:
- 用
withCallingHandlers收集所有警告(支持多警告场景) - 用
error分支捕获错误,记录信息并确保循环继续
修改后的完整循环代码:
for(file in files){ print(file) dataname <- strsplit(file,split='[.]')[[1]][1] current_msg <- character(0) # 初始化当前文件的消息容器 tryCatch({ # 捕获并收集警告 withCallingHandlers({ library(data.table) setwd(codedir) source("func.modelfit_no_confidence.R") setwd(datadir) data.orig <- as.data.table(read.csv(paste(dataname,'.csv',sep=''))) colnames <- names(data.orig) if(!any(colnames=='inoc.size') || !any(colnames=='num.inf') || !any(colnames=='num.tot')){ stop ("The input data does not contain the necessary columns. Please ensure data contains columns inoc.size, num.inf, and num.tot.") } setkey(data.orig,inoc.size) data <- data.orig if(sum(data$inoc.size==0)>0){ data <- data[inoc.size!=0] warning("Controls with inoculum size zero have been excluded.") } if(sum(data$num.inf==data$num.tot)>1){ ind.end <- first(which(data$num.inf==data$num.tot)) warning("Data point(s) at highest inoc.size have been excluded.") } else{ ind.end <- length(data$num.inf) } if(sum(data$num.inf==0)>1){ ind.start <- last(which(data$num.inf==0)) warning("Data point(s) at lowest inoc.size have been excluded.") } else{ ind.start <- 1} data <- data[ind.start:ind.end] setwd(resultsdir) attach(data) sat.model.fit <- fit.sat(inoc.size,num.inf,num.tot) IAH.model.fit <- fit.IAH(inoc.size,num.inf,num.tot) detach(data) logL.sat <- sat.model.fit$logL.tot numpar.full <- length(data$inoc.size) logL.reduc <- IAH.model.fit$logL.tot numpar.reduc <- 1 dev <- 2*(logL.sat - logL.reduc) pval <- 1-pchisq(dev, df=numpar.full-numpar.reduc) save(data, sat.model.fit, IAH.model.fit, dev, pval, file=paste("results_",dataname,".Rdata",sep="")) library(Hmisc) Nmin <- min(data$inoc.size)*0.1 Nmax <- max(data$inoc.size)*10 Nvals <- 10^seq(from=log10(Nmin),to=log10(Nmax),by=0.1) # 存储计算结果到store store[counter,c("Filename","pval","numpar.full","dev","p.estim")] <- c(dataname, pval, numpar.full, dev, IAH.model.fit$p.estim) }, warning = function(w) { current_msg <<- c(current_msg, w$message) invokeRestart("muffleWarning") # 阻止警告默认输出到控制台 }) }, error = function(e) { # 捕获错误信息并标记 current_msg <<- c(current_msg, paste("ERROR:", e$message)) }) # 将收集到的消息合并为字符串存入store store$message[counter] <- if(length(current_msg) == 0) "无" else paste(current_msg, collapse = "; ") print(store) counter <- counter + 1 }
关键说明
withCallingHandlers可以捕获处理过程中产生的所有警告,避免控制台冗余输出,同时把每个警告的消息存入容器tryCatch的error分支会捕获致命错误,记录错误信息后,循环自动跳转到下一个文件,不会中断整个流程- 最终将所有消息用分号分隔合并,存入
store$message列,方便后续批量查看每个文件的处理状态
内容的提问来源于stack exchange,提问作者K.W
相关产品推荐
相关产品推荐

