【发布时间】:2014-03-30 21:59:52
【问题描述】:
在 R 中如何获取文件夹中的文件列表,而不是目录?
我尝试过使用 dir()、list.files()、list.dirs() 和不同的选项,
但它们似乎都不起作用。
【问题讨论】:
在 R 中如何获取文件夹中的文件列表,而不是目录?
我尝试过使用 dir()、list.files()、list.dirs() 和不同的选项,
但它们似乎都不起作用。
【问题讨论】:
setdiff(list.files(), list.dirs(recursive = FALSE, full.names = FALSE))
会成功的。
【讨论】:
这是一种可能性:
all.files <- list.files(rec=F)
all.files[!file.info(all.files)$isdir]
另一种选择(带有扩展名的文件的模式,当然不是那么通用):
Sys.glob("*.*")
【讨论】:
include.dirs=FALSE 不排除目录????
base R 没有直接的方法来做到这一点的事实有点令人震惊。 BASH 没有直接的方式也有点奇怪。
在我看来,最好的 R 解决方案是简单地诉诸 shell:
filenames = system('ls -p | grep -v /', intern=T)
解释:
ls -p Append "/" to end of directory names
grep -v Exclude strings matching "/"
intern=T store the output in the variable rather then printing to stdout
【讨论】:
另一种选择:
Filter(function(x) file_test("-f", x), list.files())
如果您想充分利用库 functional 的功能,那么您可以节省一些按键操作:
Filter(Curry(file_test, "-f"), list.files())
后者将file_test 转换为第一个参数设置为“-f”的函数,这基本上是我们在第一种方法中所做的,但Curry 做得更干净,因为可悲的决定function 关键字这么长(为什么不f(x) {...}???)
【讨论】:
所以,我知道这些都是旧的,并且有一个公认的答案,但我尝试了其中的大多数,但没有一个真正奏效。
这是我得到的:
文件夹中所有文件的示例:
files <- list.files("Training/Out/")
该代码的输出:
[1] "Filtered" "Training_Chr01.txt" "Training_Chr02.txt" "Training_Chr03.txt"
[5] "Training_Chr04.txt" "Training_Chr05.txt" "Training_Chr06.txt" "Training_Chr07.txt"
[9] "Training_Chr08.txt" "Training_Chr09.txt" "Training_Chr10.txt"
第一个 [1] 是目录
运行此代码以仅获取文件:
files <- list.files("Training/Out",recursive = TRUE)
有了这个输出:
[1] "Training_Chr01.txt" "Training_Chr02.txt" "Training_Chr03.txt" "Training_Chr04.txt"
[5] "Training_Chr05.txt" "Training_Chr06.txt" "Training_Chr07.txt" "Training_Chr08.txt"
[9] "Training_Chr09.txt" "Training_Chr10.txt"
这或多或少是为了帮助那些看到这个并且和我一样困惑的人。
【讨论】:
我写了一个小包装函数来解决这个问题:
list_files <- function(path = ".", pattern = NULL, all.files = FALSE, full.names = TRUE,
recursive = FALSE, ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE,
incl_dirs = FALSE){
#Set incl_dirs = TRUE to revert to default list.files() behavior.
if(path == ".") { path = getwd() }
#Include directories if recursive is set.
if(incl_dirs & recursive) { include.dirs = TRUE }
#Needs to have full.names = TRUE in order to get full path to pass to dir.exists().
files <- list.files(path = path, pattern = pattern, all.files = all.files, full.names = TRUE,
recursive = recursive, ignore.case = ignore.case, include.dirs = include.dirs,
no.. = no..)
if(!incl_dirs){
files <- files[!dir.exists(files)]
}
if(!full.names){
return(basename(files))
} else{
return(files)
}
}
使用以下示例目录结构:
dir_test_lvl0/
├── dir_test_lvl1
│ ├── dir_test_lvl2
│ │ ├── dir_test_lvl3
│ │ │ ├── dir_test_lvl4
│ │ │ └── file_test_lvl4
│ │ └── file_test_lvl3
│ └── file_test_lvl2
└── file_test_lvl1
输出看起来像这样,取决于是否设置了incl_dirs 和recursive。
#No directories presented.
#Recursive.
list_files("dir_test_lvl0", incl_dirs = FALSE, recursive = TRUE, full.names = FALSE)
# [1] "file_test_lvl4" "file_test_lvl3" "file_test_lvl2" "file_test_lvl1"
#No directories presented.
#Non-Recursive.
list_files("dir_test_lvl0", incl_dirs = FALSE, recursive = FALSE, full.names = FALSE)
# [1] "file_test_lvl1"
#With directories presented (default list.files() behavior).
#Non-recursive.
list_files("dir_test_lvl0", incl_dirs = TRUE, recursive = FALSE, full.names = FALSE)
# [1] "dir_test_lvl1" "file_test_lvl1"
#With directories presented (default list.files() behavior).
#Recursive.
list_files("dir_test_lvl0", incl_dirs = TRUE, recursive = TRUE, full.names = FALSE)
# [1] "dir_test_lvl1" "dir_test_lvl2" "dir_test_lvl3" "dir_test_lvl4" "file_test_lvl4"
# [6] "file_test_lvl3" "file_test_lvl2" "file_test_lvl1"
所有其他list.files() 选项都由list_files() 忠实地传递给它。该函数没有外部依赖项(仅限base R)。
【讨论】:
【讨论】:
这是另一种使用正则表达式排除没有“。”的列表的解决方案
list.files("dir_path",pattern="\\.")
【讨论】: