R语言中如何提取文件路径字符串并生成数量可变的文件名列?
问题描述
我有如下文件路径列表,data文件夹下的子文件夹以ID命名,每个子文件夹包含数据文件:
library(dplyr) library(stringr) library(tidyr) paths <- c( "data/A101/usage.xlsx", "data/A101/cost.xls", "data/A101/A101 cost-1.csv", "data/B202/B202 data.csv", "data/B202/cost1.xlsx", "data/C303/usage1.xls", "data/D404/cost1.csv", "data/D404/D404 data1.xlsx", "data/E/E data1.csv" )
我希望创建如下格式的数据框:site_id列来自子文件夹名称,file_name_1至file_name_n列存储每个文件夹中提取的文件名(file_name_1存储每个站点的第一个文件名,file_name_2存储第二个,以此类推)。目标数据框示例:
df <- data.frame( site_id = unique(str_extract(paths, "[A-D]\\d+|E")), file_name_1 = c("usage.xlsx", "B202 data.csv", "usage1.xls", "cost1.csv", "data1.csv"), file_name_2 = c("cost.xls", "cost1.xlsx", NA, "D404 data1.xlsx", NA), file_name_3 = c("A101 cost-1.csv", NA, NA, NA, NA) )
我尝试了以下代码,但结果仅生成一列,文件名被合并为向量,请问哪里出错了?
test <- data.frame( site_id = str_extract(paths, "[A-D]\\d+|E"), file_name = str_extract(paths, "[^\\/]+$") ) %>% gather(key=key, value=value, -site_id) %>% pivot_wider( id_cols = "site_id", names_from = key, values_from = value, names_glue = "{key}_{seq_along({key})}", values_fn = list ) View(test)
错误原因
你的代码问题出在这两点:
- 多余的
gather操作:初始数据已经是site_id对应单个文件名的长格式,gather会把file_name列转成键值对,破坏了原有每行对应一个文件名的结构。 - 序号生成逻辑错误:
names_glue里的seq_along({key})是对整个key列生成全局序列,而非按site_id分组生成每个站点内的文件名序号;加上values_fn = list会把同一站点的文件名打包成向量,最终导致仅生成一列。
解决方法
正确思路是先按site_id分组,给每个站点内的文件名添加专属序号,再转成宽格式:
test <- data.frame( site_id = str_extract(paths, "[A-D]\\d+|E"), file_name = str_extract(paths, "[^\\/]+$") ) %>% group_by(site_id) %>% mutate(file_num = paste0("file_name_", row_number())) %>% ungroup() %>% pivot_wider( id_cols = site_id, names_from = file_num, values_from = file_name ) View(test)
这段代码的逻辑:
- 提取
site_id和每个文件的file_name,得到基础长格式数据框。 - 按
site_id分组,用row_number()给每个站点下的文件名生成1、2、3...的序号,拼接成file_name_1、file_name_2这样的列名。 - 用
pivot_wider将长格式转成宽格式,没有文件名的位置自动填充NA,完全匹配目标格式。
内容的提问来源于stack exchange,提问作者nightstand
相关产品推荐
相关产品推荐

