使用 r 进行文件夹管理:检查目录是否存在,如果不存在则创建它

发布于 2024-10-03 04:10:19 字数 356 浏览 1 评论 0原文

我经常发现自己编写的 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))
    
}

I often find myself writing R scripts that generate a lot of output. I find it cleaner to put this output into its own directory(s). What I've written below will check for the existence of a directory and move into it, or create the directory and then move into it. Is there a better way to approach this?

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))
    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

南七夏 2024-10-10 04:10:20

要查明路径是否是有效目录,请尝试:

file.info(cacheDir)[1,"isdir"]

file.info 不关心末尾的斜杠。

Windows 上的 file.exists 如果目录以斜线结尾,则该目录将失败;如果没有斜线,则成功。所以这不能用来确定路径是否是目录。

file.exists("R:/data/CCAM/CCAMC160b_echam5_A2-ct-uf.-5t05N.190to240E_level1000/cache/")
[1] FALSE

file.exists("R:/data/CCAM/CCAMC160b_echam5_A2-ct-uf.-5t05N.190to240E_level1000/cache")
[1] TRUE

file.info(cacheDir)["isdir"]

To find out if a path is a valid directory try:

file.info(cacheDir)[1,"isdir"]

file.info does not care about a slash on the end.

file.exists on Windows will fail for a directory if it ends in a slash, and succeeds without it. So this cannot be used to determine if a path is a directory.

file.exists("R:/data/CCAM/CCAMC160b_echam5_A2-ct-uf.-5t05N.190to240E_level1000/cache/")
[1] FALSE

file.exists("R:/data/CCAM/CCAMC160b_echam5_A2-ct-uf.-5t05N.190to240E_level1000/cache")
[1] TRUE

file.info(cacheDir)["isdir"]
醉殇 2024-10-10 04:10:20

我偶然发现了另一种方式,我认为这不是最好的,但很有趣。

path <- "your/path"
dir.exists(path) || dir.create(path)

I found by chance another way, I don't think it's the best but it's interesting.

path <- "your/path"
dir.exists(path) || dir.create(path)
初懵 2024-10-10 04:10:19

使用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))

Use showWarnings = FALSE:

dir.create(file.path(mainDir, subDir), showWarnings = FALSE)
setwd(file.path(mainDir, subDir))

dir.create() does not crash if the directory already exists, it just prints out a warning. So if you can live with seeing warnings, there is no problem with just doing this:

dir.create(file.path(mainDir, subDir))
setwd(file.path(mainDir, subDir))
执手闯天涯 2024-10-10 04:10:19

自 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))

As of April 16, 2015, with the release of R 3.2.0 there's a new function called dir.exists(). To use this function and create the directory if it doesn't exist, you can use:

ifelse(!dir.exists(file.path(mainDir, subDir)), dir.create(file.path(mainDir, subDir)), FALSE)

This will return FALSE if the directory already exists or is uncreatable, and TRUE if it didn't exist but was succesfully created.

Note that to simply check if the directory exists you can use

dir.exists(file.path(mainDir, subDir))
作妖 2024-10-10 04:10:19

单行:

if (!dir.exists(output_dir)) {dir.create(output_dir)}

示例:

dateDIR <- as.character(Sys.Date())
outputDIR <- file.path(outD, dateDIR)
if (!dir.exists(outputDIR)) {dir.create(outputDIR)}

One-liner:

if (!dir.exists(output_dir)) {dir.create(output_dir)}

Example:

dateDIR <- as.character(Sys.Date())
outputDIR <- file.path(outD, dateDIR)
if (!dir.exists(outputDIR)) {dir.create(outputDIR)}
虚拟世界 2024-10-10 04:10:19

这是简单检查如果不存在则创建目录:

## Provide the dir name(i.e sub dir) that you want to create under main dir:
output_dir <- file.path(main_dir, sub_dir)

if (!dir.exists(output_dir)){
dir.create(output_dir)
} else {
    print("Dir already exists!")
}

Here's the simple check, and creates the dir if doesn't exists:

## Provide the dir name(i.e sub dir) that you want to create under main dir:
output_dir <- file.path(main_dir, sub_dir)

if (!dir.exists(output_dir)){
dir.create(output_dir)
} else {
    print("Dir already exists!")
}
日裸衫吸 2024-10-10 04:10:19

就一般架构而言,我会推荐以下关于目录创建的结构。这将涵盖大多数潜在问题,并且目录创建的任何其他问题都将通过 dir.create 调用检测到。

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') 的调用将会失败,除非您指定 递归= TRUE 。

In terms of general architecture I would recommend the following structure with regard to directory creation. This will cover most potential issues and any other issues with directory creation will be detected by the dir.create call.

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
}

Also be aware that if ~/foo doesn't exist then a call to dir.create('~/foo/bar') will fail unless you specify recursive = TRUE.

梓梦 2024-10-10 04:10:19

我在使用 R 2.15.3 时遇到了一个问题,在尝试在共享网络驱动器上递归创建树结构时,我会收到权限错误。

为了解决这个奇怪的问题,我手动创建了结构;

mkdirs <- function(fp) {
    if(!file.exists(fp)) {
        mkdirs(dirname(fp))
        dir.create(fp)
    }
} 

mkdirs("H:/foo/bar")

I had an issue with R 2.15.3 whereby while trying to create a tree structure recursively on a shared network drive I would get a permission error.

To get around this oddity I manually create the structure;

mkdirs <- function(fp) {
    if(!file.exists(fp)) {
        mkdirs(dirname(fp))
        dir.create(fp)
    }
} 

mkdirs("H:/foo/bar")
心欲静而疯不止 2024-10-10 04:10:19

使用 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 和 filer.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))

此解决方案将工作目录置于用户的控制之下。

The use of file.exists() to test for the existence of the directory is a problem in the original post. If subDir included the name of an existing file (rather than just a path), file.exists() would return TRUE, but the call to setwd() would fail because you can't set the working directory to point at a file.

I would recommend the use of file_test(op="-d", subDir), which will return "TRUE" if subDir is an existing directory, but FALSE if subDir is an existing file or a non-existent file or directory. Similarly, checking for a file can be accomplished with op="-f".

Additionally, as described in another comment, the working directory is part of the R environment and should be controlled by the user, not a script. Scripts should, ideally, not change the R environment. To address this problem, I might use options() to store a globally available directory where I wanted all of my output.

So, consider the following solution, where someUniqueTag is just a programmer-defined prefix for the option name, which makes it unlikely that an option with the same name already exists. (For instance, if you were developing a package called "filer", you might use filer.mainDir and filer.subDir).

The following code would be used to set options that are available for use later in other scripts (thus avoiding the use of setwd() in a script), and to create the folder if necessary:

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))
  }
}

Then, in any subsequent script that needed to manipulate a file in subDir, you might use something like:

mainDir = getOption(someUniqueTag.mainDir)
subDir = getOption(someUniqueTag.subDir)
filename = "fileToBeCreated.txt"
file.create(file.path(mainDir, subDir, filename))

This solution leaves the working directory under the control of the user.

街角迷惘 2024-10-10 04:10:19

我知道这个问题不久前就被问过,但如果有用的话,here 包对于不必引用特定文件路径并使代码更具可移植性确实很有帮助。它会自动将您的工作目录定义为 .Rproj 文件所在的目录,因此以下内容通常就足够了,而无需定义工作目录的文件路径:

library(here)

if (!dir.exists(here(outputDir))) {dir.create(here(outputDir))}

I know this question was asked a while ago, but in case useful, the here package is really helpful for not having to reference specific file paths and making code more portable. It will automatically define your working directory as the one that your .Rproj file resides in, so the following will often suffice without having to define the file path to your working directory:

library(here)

if (!dir.exists(here(outputDir))) {dir.create(here(outputDir))}

裸钻 2024-10-10 04:10:19

hutils (我编写的)具有用于检查目录/文件的函数 provide.dir(path)provide.file(path) path 存在,如果不存在则创建它们。

Package hutils (which I authored) has the functions provide.dir(path) and provide.file(path) to check the directories/files at path exist, creating them if they are absent.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文