如何让tstrsplit在data.table中逐行提取文件名的最后后缀?
提取data.table中文件名的后缀
原代码问题分析
你的代码出错核心原因:
tstrsplit(filename, "\\.")返回的是整个列所有行拆分结果组成的列表,并非逐行的独立向量;length(tstrsplit(filename, "\\."))计算的是这个列表的总长度(即行数),不是每行拆分后的片段数量;- 后续
[chunks]是对整个列表按索引取元素,而非针对每行自己的拆分结果取最后一段,导致逻辑错位。
解决方案
以下是几种高效可行的实现方式:
方法1:结合tstrsplit与sapply逐行取最后片段
利用tstrsplit的列表返回结构,用sapply遍历每行的拆分结果,直接取最后一个元素:
files0 <- data.table(filename=c("simple_file.csv","file with.two dots.xls")) files0[, extension := sapply(tstrsplit(filename, "\\."), tail, n = 1)]
方法2:正则表达式(最高效)
无需拆分,直接通过正则匹配最后一个点之后的内容,适合大规模数据集:
# base R 原生实现 files0[, extension := sub(".*\\.(.*)$", "\\1", filename)] # stringr 包简化实现(需先安装加载) library(stringr) files0[, extension := str_remove(str_extract(filename, "\\.[^.]+$"), "\\.")]
正则说明:
.*\\.(.*)$:匹配最后一个点之前的所有内容,捕获点之后的部分;\\.[^.]+$:直接匹配最后一个点及之后的非点字符,再移除开头的点。
方法3:data.table逐行强制处理(by = .I)
通过by = .I让代码逐行执行,每行单独处理自己的文件名:
files0[, extension := { split_parts <- tstrsplit(filename, "\\.")[[1]] split_parts[length(split_parts)] }, by = .I]
内容的提问来源于stack exchange,提问作者kdarras
相关产品推荐
相关产品推荐

