如何修改str_detect匹配模式以同时匹配双循环索引构建文件列表?
解决方案
修改原代码的方案
原代码的核心问题是str_detect仅匹配了j,未结合k做双重匹配。你可以构造同时包含j和k的正则表达式,精确匹配文件名格式:
library(readxl) library(stringr) nm1 = c(LETTERS[1:2]) nm2 = c(letters[3:5]) Files <- list.files(pattern = "\\.xls$") # 先获取所有目标xls文件路径 # 提前初始化结构正确的分层空列表 result_list <- setNames(lapply(nm1, function(x) setNames(vector("list", length(nm2)), nm2)), nm1) for (i in Files) { for (j in nm1) { for (k in nm2) { # 构造精确匹配的正则:开头是j,中间固定为_(ele)_,结尾是k加.xls pattern <- paste0("^", j, "_(ele)_", k, "\\.xls$") if (str_detect(i, pattern)) { result_list[[j]][[k]] <- read_excel(i) } } } }
说明:
- 提前初始化列表结构,避免赋值时出现维度错误
- 用
^和$确保完全匹配文件名,\\.转义正则中的通配符点号 - 匹配成功后直接将读取的Excel数据存入对应层级
更简洁的替代实现方案
方案1:tidyverse风格(purrr+stringr)
library(readxl) library(stringr) library(purrr) Files <- list.files(pattern = "\\.xls$") # 从文件名中提取分组标识(A/B和c/d/e) file_info <- tibble(file = Files) %>% mutate( group1 = str_extract(file, "^[A-Z]"), # 提取开头的大写字母 group2 = str_extract(file, "[a-z](?=\\.xls$)") # 提取.xls前的小写字母 ) # 分层读取并生成嵌套列表 result_list <- file_info %>% split(.$group1) %>% map(function(g1_data) { g1_data %>% split(.$group2) %>% map(function(g2_data) { read_excel(g2_data$file) }) })
方案2:Base R原生实现
library(readxl) Files <- list.files(pattern = "\\.xls$") # 提取两个分组的标识 group1 <- sub("_(ele)_.*\\.xls$", "", Files) group2 <- sub("^.*_(ele)_", "", Files) group2 <- sub("\\.xls$", "", group2) # 先按一级分组拆分,再按二级分组读取文件 result_list <- lapply(split(Files, group1), function(g1_files) { g1_subgroups <- sub("^.*_(ele)_", "", g1_files) g1_subgroups <- sub("\\.xls$", "", g1_subgroups) lapply(split(g1_files, g1_subgroups), read_excel) })
这两个方案无需多层嵌套循环,通过先提取分组信息再拆分读取,代码更简洁易维护,也避免了不必要的重复判断。
内容的提问来源于stack exchange,提问作者12666727b9
相关产品推荐
相关产品推荐

