在R中,使用file.path
,您可以使用正确的平台文件分隔符自动将字符向量转换为完整文件路径:
> file.path("home", "foo", "script.R")
[1] "home/foo/script.R"
我想完全相反:将文件路径拆分为组件的字符向量。到目前为止,我几乎设法使用递归函数,但我发现它不是很优雅:
split_path <- function(file) {
if(!(file %in% c("/", "."))) {
res <- c(basename(file), split_path(dirname(file)))
return(res)
}
else return(NULL)
}
给出了:
> split_path("/home/foo/stats/index.html")
[1] "index.html" "stats" "foo" "home"
你知道任何现有的功能,或者至少有更好的方法来做这样的事情吗?
谢谢!
编辑:我想我最终会坚持这个稍微不同的递归版本,感谢@James,它应该在Windows下处理驱动器号和网络共享:
split_path <- function(path) {
if (dirname(path) %in% c(".", path)) return(basename(path))
return(c(basename(path), split_path(dirname(path))))
}
答案 0 :(得分:11)
您可以使用简单的递归函数来执行此操作,方法是在dirname
没有更改时终止:
split_path <- function(x) if (dirname(x)==x) x else c(basename(x),split_path(dirname(x)))
split_path("/home/foo/stats/index.html")
[1] "index.html" "stats" "foo" "home" "/"
split_path("C:\\Windows\\System32")
[1] "System32" "Windows" "C:/"
split_path("~")
[1] "James" "Users" "C:/"
答案 1 :(得分:3)
试试这个(适用于“/”和“\”):
split_path <- function(path) {
rev(setdiff(strsplit(path,"/|\\\\")[[1]], ""))
}
结果
split_path("/home/foo/stats/index.html")
# [1] "index.html" "stats" "foo" "home"
rev(split_path("/home/foo/stats/index.html"))
# [1] "home" "foo" "stats" "index.html"
修改强>
使用normalizePath
,dirname
和basename
,此版本会有不同的结果:
split_path <- function(path, mustWork = FALSE, rev = FALSE) {
output <- c(strsplit(dirname(normalizePath(path,mustWork = mustWork)),
"/|\\\\")[[1]], basename(path))
ifelse(rev, return(rev(output)), return(output))
}
split_path("/home/foo/stats/index.html", rev=TRUE)
# [1] "index.html" "stats" "foo" "home" "D:"
答案 2 :(得分:2)
您可以使用软件包DescTools
来解决问题:
library(DescTools)
SplitPath('C:/users/losses/development/R/loveResearch/src/signalPreprocess.R')
输出为:
$normpath
[1] "C:\\users\\losses\\development\\R\\loveResearch\\src\\signalPreprocess.R"
$drive
[1] "C:"
$dirname
[1] "/users/losses/development/R/loveResearch/src/"
$fullfilename
[1] "signalPreprocess.R"
$filename
[1] "signalPreprocess"
$extension
[1] "R"
非常方便。