You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:32:58