如何按站点ID筛选保留含separated短语的目标文件路径?
问题描述
我有如下文件路径的示例数据:
paths <- c("data/A101/bill1.xlsx", "data/A101/bill1-separated.xlsx", "data/B215/usage2.csv", "data/B215/usage2-separated.xlsx", "data/A101/bill2.xls", "data/A101/bill2-separated.xlsx", "data/C145/account1.xlsx", "data/C145/account1-separated.xlsx", "data/A101/bill3.xlsx", "data/B215/usage1.csv", "data/B215/usage3.xls", "data/C145/account2.xlsx") %>% sort()
数据文件夹下有带站点标识的子文件夹,每个子文件夹对应站点专属数据。比如data/A101/文件夹包含5个数据文件:bill1-separated.xlsx、bill1.xlsx、bill2.xls、bill2-separated.xlsx、bill3.xlsx。
我的需求是:
- 当同一文件的原版本和带
separated的分离版同时存在时,只保留带separated的文件路径; - 若只有原文件存在,则保留原文件路径。
比如bill1-separated.xlsx和bill1.xlsx同时存在时,仅保留bill1-separated.xlsx的路径。
期望得到的结果如下:
desired <- c(NA_character_, "data/A101/bill1-separated.xlsx", NA_character_, "data/B215/usage2-separated.xlsx", NA_character_, "data/A101/bill2-separated.xlsx", NA_character_, "data/C145/account1-separated.xlsx", "data/A101/bill3.xlsx", "data/B215/usage1.csv", "data/B215/usage3.xls", "data/C145/account2.xlsx") %>% sort()
我尝试用ifelse和grepl来筛选,但没成功,尝试的代码如下:
library(stringr) library(dplyr) # attempt temp <- data.frame(path = paths) temp %>% mutate( file = str_extract(paths, "\/.*\/(.+)", group=1), attempt = ifelse(!grepl("separated", file), NA, # nest another ifelse? but not sure what condition/regex to use path ) )
解决方案
可以通过提取每个文件的**基础标识(去掉-separated和后缀)**分组,在每组内优先选择带separated的文件,无分离版则保留原文件,最后匹配原路径列表生成结果。
具体代码实现:
library(dplyr) library(stringr) temp <- tibble(path = paths) %>% # 提取站点文件夹路径,确保同站点文件不跨组 mutate( site_dir = str_extract(path, "^data/[A-Z0-9]+/"), # 提取纯文件名(去掉站点路径) filename = str_remove(path, "^data/[A-Z0-9]+/"), # 生成基础标识:去掉-separated后缀和文件扩展名 base_id = str_remove(filename, "-separated\\..+$|\\..+$") ) %>% # 按站点+基础标识分组 group_by(site_dir, base_id) %>% mutate( # 标记是否为分离版文件 is_separated = str_detect(filename, "-separated"), # 每组确定保留的路径:有分离版则留分离版,否则留原文件 keep_path = if(any(is_separated)) path[is_separated] else path ) %>% ungroup() %>% # 匹配原路径列表,不需要的路径设为NA mutate(result = ifelse(path %in% keep_path, path, NA_character_)) # 提取最终结果并排序 final_result <- temp$result %>% sort() # 验证是否与期望结果一致 all.equal(final_result, desired)
代码说明
site_dir:提取文件所在的站点文件夹,避免不同站点的同名文件被归为一组;base_id:通过正则表达式去除-separated后缀和文件扩展名,得到每个文件的唯一核心标识,用于分组匹配原文件和分离版;- 分组后检查是否存在分离版文件,存在则保留该路径,否则保留原文件路径;
- 最后将原路径列表中不符合要求的条目设为NA,得到与预期一致的结果。
内容的提问来源于stack exchange,提问作者nightstand
相关产品推荐
相关产品推荐

