R语言实现多工作簿指定工作表合并及文件名年份提取
解决你的两个R语言问题:合并Excel工作表与年份提取
嘿,我来帮你搞定这两个问题!先从合并Excel工作表的问题说起,然后再处理年份正则提取的事儿。
一、合并多Excel文件的指定工作表
你的代码目前只拿到一个工作表的数据,主要有几个小问题:
- 初始化的
data.1带NA空行,而且每次循环都把新数据和这个空行绑定,还会覆盖之前的合并结果 - 没有正确获取工作表名称,
sheet.names[j]会出错 - 没有累积合并数据,每次循环都重置
data_merge
下面是修正后的代码,我加了详细注释:
library(XLConnect) # 设置Excel文件所在的文件夹路径 file_path <- "C:/Users/kushaa/Documents/Frost_casestudy/" # 只读取.xlsx和.xls文件,同时获取完整文件路径(避免加载工作簿时出错) files <- list.files(path = file_path, pattern = "\\.xlsx$|\\.xls$", full.names = TRUE) # 指定要读取的工作表索引 sheet.index <- c(3,6,9) # 定义最终数据框的列名 colname <- c("Country","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","FY","truck_type") # 初始化一个空的数据框,用来存放合并后的结果 data_merge <- data.frame(matrix(ncol = length(colname), nrow = 0)) names(data_merge) <- colname # 遍历每个Excel文件 for (i in seq_along(files)){ # 加载当前工作簿 wb <- loadWorkbook(files[i]) # 获取当前工作簿的所有工作表名称 sheet_names <- getSheets(wb) # 遍历指定的工作表索引 for (j in seq_along(sheet.index)){ # 读取第j个指定的工作表,从第5行开始,无表头 ss <- readWorksheet(wb, sheet = sheet.index[j], startRow = 5, header = FALSE) # 把当前工作表名称作为truck_type,重复对应行数 truck_type <- rep(sheet_names[sheet.index[j]], nrow(ss)) # 组合数据并设置列名 df <- cbind(ss, truck_type) names(df) <- colname # 将当前工作表的数据追加到合并数据框中 data_merge <- rbind(data_merge, df) } } # 移除可能存在的空行(比如工作表末尾的空白行) data_merge <- data_merge[complete.cases(data_merge$Country), ]
这样修改后,就能把所有指定的工作表数据都合并到一个dataframe里,而且truck_type也能正确对应LCV、HCV这些工作表名称啦。
二、正则提取正确的年份
你当前的正则会匹配从第一个数字到最后一个数字的所有内容,所以拿到的是长串数字。我们需要的是每个文件名里最后出现的四位年份数字,可以用Perl风格的正则来实现:
# 提取每个文件名中最后出现的四位数字(即目标年份) years <- regmatches(files, regexpr("[0-9]{4}(?!.*[0-9]{4})", files, perl = TRUE)) years
运行后就能得到你想要的结果:
[1] "2014" "2012" "2013"
正则解释:
[0-9]{4}:匹配连续的四位数字(?!.*[0-9]{4}):正向否定预查,确保这个四位数字后面没有其他四位数字(也就是找到最后一个四位数字)perl = TRUE:启用Perl风格正则,支持预查语法
如果你的文件名里的目标年份都是跟在_vo或_by前面,也可以用更精准的正则:
years <- regmatches(files, regexpr("([0-9]{4})(?=_vo|_by)", files, perl = TRUE))
这个也能得到同样的结果,你可以根据自己所有文件名的规律选择合适的正则。
内容的提问来源于stack exchange,提问作者sree




