R语言多TXT文件列缺失补NA:现有代码修改求助
问题与解决方案
问题背景
有多份列结构不统一的TXT文件,部分列仅存在于部分文件中,需用R处理后输出包含指定8列(D_T、City_Name、Temp、Pres、Wind_Hor、Wind_Ver、Rainf、S_Moist)的CSV文件,缺失列填充NA并计算月度平均值。现有代码运行时报错:
Error in get(x, envir = .GlobalEnv) : object 'Mi/Mi_2020-01_0100.txt' not found
错误原因
adj_col_names函数未闭合,导致后续代码被错误嵌套在函数内部,引发变量作用域问题read_the_files中skip参数指定的表头字符串与实际文件表头不符,导致读取失败write.csv参数顺序错误,未传入待输出的数据框- 部分列名不匹配(如文件3中的
Wind_Vert与目标列名Wind_Ver不一致) D/T列是数字格式,未转换为日期类型就使用floor_date,引发类型错误
代码修改点
- 闭合函数语法:补充
adj_col_names函数缺失的闭合大括号,修复代码嵌套错误 - 修正文件读取逻辑:移除
read_the_files中错误的skip参数,改用header=TRUE让fread自动识别表头 - 统一列名:将文件3中的
Wind_Vert重命名为目标列名Wind_Ver,确保列匹配 - 修复输出函数参数:调整
write.csv的参数顺序,传入待输出的avg_mn数据框,添加row.names=FALSE避免输出冗余行号 - 日期格式转换:将数字格式的
D/T列用ymd转换为日期类型,保证floor_date能正常计算月度分组 - 补充函数返回值:在
adj_col_names中添加return(x)确保处理后的数据能正确传递
修改后的完整代码
library(data.table) library(tidyr) library(dplyr) library(lubridate) setwd("D:/Test3") dirlist <- list.files(full.names = FALSE, no.. = TRUE) # 读取文件函数 read_the_files <- function(filelist){ lapply(filelist, function(file) { # 自动识别表头,移除错误的skip参数 fread(file, header = TRUE, sep = "auto") }) } # 列名调整与数据清洗函数 adj_col_names <- function(dt_list){ lapply(dt_list, FUN = function(x){ # 替换[]为()避免语法问题 colnames(x) <- gsub("\\[", "(", colnames(x)) colnames(x) <- gsub("\\]", ")", colnames(x)) # 统一列名:Wind_Vert -> Wind_Ver if ("Wind_Vert" %in% colnames(x)) { setnames(x, "Wind_Vert", "Wind_Ver") } # 根据质量码和范围清洗Temp数据 if ("Temp1" %in% colnames(x)) { x[Temp1 != 5, Temp := NA] x[Temp < 0 | Temp > 40, Temp := NA] } # 根据质量码和范围清洗Pres数据 if ("Pres1" %in% colnames(x)) { x[Pres1 != 5, Pres := NA] x[Pres < 1000 | Pres > 1300, Pres := NA] } return(x) # 返回处理后的data.table }) } # 遍历目录处理文件 for (idx in seq_along(dirlist)){ # 获取当前目录下所有txt文件的完整路径 filelist <- list.files(path = dirlist[idx], full.names = TRUE, recursive = TRUE, pattern = ".txt$") dt_ <- read_the_files(filelist) dt.tidied <- adj_col_names(dt_) # 合并数据,缺失列填充NA merged <- rbindlist(dt.tidied, fill = TRUE, use.names = TRUE) # 指定输出列 sel_col <- c('D/T', 'City_Name', 'Temp', 'Pres', 'Wind_Hor', 'Wind_Ver', 'Rainf', 'S_Moist') # 计算月度平均值 avg_mn <- merged %>% select(any_of(sel_col)) %>% as_tibble() %>% # 将数字格式的D/T转换为日期类型 mutate(`D/T` = ymd(`D/T`)) %>% group_by(D_T = lubridate::floor_date(`D/T`, "1 month")) %>% summarise(across(where(is.numeric), ~ if(mean(is.na(.x)) > 0.1) NA else mean(.x, na.rm = TRUE))) # 写入CSV文件,修复参数顺序 write.csv(avg_mn, file = paste0(dirlist[idx],"_mn.csv"), row.names = FALSE) }
内容的提问来源于stack exchange,提问作者Alexia k Boston
相关产品推荐
相关产品推荐

