R语言批量合并无时间戳CSV数据集时for循环/lapply报错如何解决
错误排查
你当前的代码存在以下几处核心问题,直接触发报错和运行异常:
- lapply逻辑错误:lapply会把
filenames列表里的单个文件名依次传给处理函数,但是你在AddTS函数内部还在调用filenames[i],这里的i没有定义,无法识别有效文件路径,直接触发文件不存在报错。 - 不必要的文件名拼接错误:你在
n.readLines里给文件名加了paste(..., sep = ",")/sep = ",|\\s|-"的操作,相当于把原本正常的文件名和分隔符拼接成了不存在的文件名,自然找不到对应文件。 - for循环结果未存储:你在for循环里每次都直接覆盖
Card1变量,没有把每个文件的处理结果追加到列表里,自然最后只保留最后一次运行的结果,看起来像只运行了一次。 - 正则匹配逻辑错误:你提取时间的正则
[SPU Data Filename = ]?是匹配方括号里的任意单个字符,不是匹配整个前缀,会导致时间提取失败。 - 路径隐患:
list.files设置了full.names=FALSE,如果工作目录和文件存储目录不一致也会触发找不到文件的问题,建议直接用绝对路径更稳妥。
修正后完整代码
# 加载依赖包 library(tidyverse) library(lubridate) # 设置工作目录 setwd("C:/Users/rottweiller/Desktop/Practicing R") # 获取所有目标文件的绝对路径,避免路径找不到问题 filenames <- list.files(path = "C:/Users/rottweiller/Desktop/Practicing R", pattern = "c1h|c1p", full.names = TRUE) # 重写处理单个文件的函数 AddTS <- function(single_file){ # 读取文件前3行表头,不需要额外拼接文件名 header_lines <- readLines(single_file, n = 3) # 提取采样频率:第三行的数字 frq1 <- as.integer(gsub("\\D", "", header_lines[3])) # 提取时间字符串:第二行里的日期时间部分,修正正则匹配 time_str <- str_extract(header_lines[2], "\\d{2}\\D{3}\\d{4} ,\\d{2} -\\d{2} -\\d{2}") # 清理时间字符串里的空格、横杠和逗号 time_clean <- gsub("\\s|-|,", "", time_str) # 解析为时间格式 SUTC1 <- parse_date_time(time_clean, orders = "dmYHMS") # 读取数据主体,跳过前79行表头 C1 <- read.delim(single_file, header = FALSE, sep = ",", skip = 79) # 替换无穷值为0 C1 <- C1 %>% mutate(across(where(is.numeric), ~ifelse(is.infinite(.), 0, .))) # 生成时间列 TS1 <- SUTC1 + (1/frq1)*seq_len(nrow(C1)) # 合并时间列和数据 Card1 <- cbind(TS1, C1) return(Card1) } # 方法1:用lapply批量处理后拼接(推荐) combined <- bind_rows(lapply(filenames, AddTS)) # 方法2:用for循环实现,结果存入列表再拼接 # result_list <- list() # for(i in seq_along(filenames)){ # result_list[[i]] <- AddTS(filenames[i]) # } # combined <- bind_rows(result_list)
额外说明
- 如果你确认所有文件的表头行数固定是79行,上面的代码可以直接运行;如果不同文件表头行数有差异,可以先统计每个文件的表头行数再调整
skip参数。 - 重写后的函数去掉了冗余的
reader包依赖,用R原生的readLines更稳定,减少包兼容问题。
内容的提问来源于stack exchange,提问作者rottweiller
相关产品推荐
相关产品推荐

