R语言中tryCatch()无法填充错误信息至列表的问题排查
问题原因与修复方案
核心问题
你代码里的k列表无法填充,主要是两个原因:
- 空文件不会触发
read.table错误:read.table读取空文件时,会返回一个0行的数据框,并不会抛出错误,所以你的tryCatch的error分支根本不会执行,自然不会往k里写数据。你误以为空文件会导致读取错误,但实际上只有文件不存在、权限不足这类情况才会触发错误。 - 列表存储结构不合理:就算触发错误,你用
<<-交替存储基因和物种到k的方式,不仅容易引发变量作用域的意外问题,最后转成数据框后会变成多列结构,不符合“每条记录对应一个基因+物种”的需求。
修复后的代码
下面是调整后的代码,同时处理文件读取错误和文件存在但内容为空两种情况,并且用更清晰的结构存储结果:
library(dplyr) singletons <- duplicate_singletons %>% filter(Branch == "Singletons") %>% select(-c("dN/dS(w)", "Branch")) species <- c("bovis", "becei", "panamensis", "inopinata", "tropicalis", "remanei", "latens", "tribulationis", "briggsae", "nigoni") species <- as.data.frame(species) %>% rename(Species = species) # 初始化结果数据框,直接存储空文件/读取错误的基因和物种 empty_records <- data.frame(gene_id = character(), Species = character(), stringsAsFactors = FALSE) for(i in 1:nrow(singletons)) { current_gene <- singletons$gene_id[i] for(j in 1:nrow(species)) { current_species <- species$Species[j] # 用file.path拼接路径,避免手动拼接的格式错误 file_path <- file.path( "C:/Users/user/Documents/Travail/Synteny_project/R_files/Singletons", current_gene, "PSL", paste0("elegans_", current_species, ".psl") ) # 捕获读取错误,同时检查读取后的数据框是否为空 record <- tryCatch({ df <- read.table(file_path, sep = "\t") # 数据框为空时返回记录 if(nrow(df) == 0) { data.frame(gene_id = current_gene, Species = current_species) } else { NULL } }, error = function(e) { # 文件不存在等读取错误时返回记录 data.frame(gene_id = current_gene, Species = current_species) }) # 如果有需要记录的情况,添加到结果数据框 if(!is.null(record)) { empty_records <- rbind(empty_records, record) } } }
关键调整点
- 用
file.path拼接文件路径,避免手动用paste0拼接时出现路径分隔符错误 - 同时处理两种需要记录的情况:文件读取失败(如不存在)、文件存在但内容为空(数据框行数为0)
- 直接用一个数据框存储结果,比嵌套列表更直观,后续无需额外转换结构
- 避免使用
<<-这种全局赋值,改用返回值的方式传递结果,减少作用域相关的意外问题 - 循环中明确定义
current_gene和current_species,提升代码可读性
内容的提问来源于stack exchange,提问作者Lilly
相关产品推荐
相关产品推荐

