我经常发现自己在编写生成大量输出的R脚本。我发现把这个输出放到它自己的目录中更干净。我下面所写的内容将检查是否存在一个目录并移动到其中,或者创建一个目录然后移动到其中。有没有更好的解决办法?
mainDir <- "c:/path/to/main/dir"
subDir <- "outputDirectory"
if (file.exists(subDir)){
setwd(file.path(mainDir, subDir))
} else {
dir.create(file.path(mainDir, subDir))
setwd(file.path(mainDir, subDir))
}
使用showWarnings = FALSE:
dir.create(file.path(mainDir, subDir), showWarnings = FALSE)
setwd(file.path(mainDir, subDir))
如果目录已经存在,Dir.create()不会崩溃,它只是打印出一个警告。所以如果你能忍受看到警告,那么这样做是没有问题的:
dir.create(file.path(mainDir, subDir))
setwd(file.path(mainDir, subDir))
在通用架构方面,我推荐以下关于目录创建的结构。这将涵盖大多数潜在的问题,而与目录创建有关的任何其他问题将由dir检测到。创建调用。
mainDir <- "~"
subDir <- "outputDirectory"
if (file.exists(paste(mainDir, subDir, "/", sep = "/", collapse = "/"))) {
cat("subDir exists in mainDir and is a directory")
} else if (file.exists(paste(mainDir, subDir, sep = "/", collapse = "/"))) {
cat("subDir exists in mainDir but is a file")
# you will probably want to handle this separately
} else {
cat("subDir does not exist in mainDir - creating")
dir.create(file.path(mainDir, subDir))
}
if (file.exists(paste(mainDir, subDir, "/", sep = "/", collapse = "/"))) {
# By this point, the directory either existed or has been successfully created
setwd(file.path(mainDir, subDir))
} else {
cat("subDir does not exist")
# Handle this error as appropriate
}
还要注意,如果~/foo不存在,则调用dir.create('~/foo/bar')将失败,除非指定recursive = TRUE。
2015年4月16日,随着R 3.2.0的发布,出现了一个名为dir.exists()的新函数。要使用此函数并在目录不存在时创建该目录,您可以使用:
ifelse(!dir.exists(file.path(mainDir, subDir)), dir.create(file.path(mainDir, subDir)), FALSE)
如果目录已经存在或不可创建,则返回FALSE;如果目录不存在但已成功创建,则返回TRUE。
注意,只需检查目录是否存在就可以使用
dir.exists(file.path(mainDir, subDir))
在最初的文章中,使用file.exists()来测试目录是否存在是一个问题。如果subDir包含一个现有文件的名称(而不仅仅是一个路径),file.exists()将返回TRUE,但对setwd()的调用将失败,因为您不能将工作目录设置为指向文件。
我建议使用file_test(op="-d", subDir),如果subDir是一个现有的目录,它将返回"TRUE",但如果subDir是一个现有的文件或不存在的文件或目录,则返回FALSE。类似地,可以使用op="-f"来检查文件。
此外,正如在另一条评论中所描述的,工作目录是R环境的一部分,应该由用户控制,而不是脚本。理想情况下,脚本不应该改变R环境。为了解决这个问题,我可以使用options()来存储一个全局可用的目录,我希望在其中存储所有输出。
因此,考虑下面的解决方案,其中someUniqueTag只是一个程序员为选项名定义的前缀,这使得具有相同名称的选项不太可能已经存在。(例如,如果你正在开发一个名为“filer”的包,你可能会使用filer。mainDir和file . subdir)。
下面的代码将用于设置稍后在其他脚本中可用的选项(从而避免在脚本中使用setwd()),并在必要时创建文件夹:
mainDir = "c:/path/to/main/dir"
subDir = "outputDirectory"
options(someUniqueTag.mainDir = mainDir)
options(someUniqueTag.subDir = "subDir")
if (!file_test("-d", file.path(mainDir, subDir)){
if(file_test("-f", file.path(mainDir, subDir)) {
stop("Path can't be created because a file with that name already exists.")
} else {
dir.create(file.path(mainDir, subDir))
}
}
然后,在任何需要在subDir中操作文件的后续脚本中,您可以使用类似于:
mainDir = getOption(someUniqueTag.mainDir)
subDir = getOption(someUniqueTag.subDir)
filename = "fileToBeCreated.txt"
file.create(file.path(mainDir, subDir, filename))
这种解决方案将工作目录置于用户的控制之下。