代码之家  ›  专栏  ›  技术社区  ›  Chase

检查目录的存在和创建IF不存在

r
  •  332
  • Chase  · 技术社区  · 15 年前

    我经常发现自己编写的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))
    
    }
    
    7 回复  |  直到 10 年前
        1
  •  382
  •   David Arenburg Ulrik    11 年前

    使用 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))
    
        2
  •  154
  •   Molx    11 年前

    截至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))
    
        3
  •  17
  •   Stoffi Greto zelanix    12 年前

    就一般架构而言,我建议在目录创建方面采用以下结构。这将涵盖大多数潜在的问题,目录创建的任何其他问题都将由 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') 将失败,除非您指定 recursive = TRUE .

        4
  •  10
  •   Surya    8 年前

    这是 简单检查 , 如果不存在,则创建DIR:

    ## 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!")
    }
    
        5
  •  9
  •   G Poole    10 年前

    使用文件.Isvestor()来测试目录的存在是原始帖子中的一个问题。如果SUDIIR包含了现有文件的名称(而不仅仅是路径),文件.IsvsAd()将返回true,但是对SETWDE()的调用会失败,因为您不能将工作目录设置为指向文件。

    我建议使用“如果”是“一个已存在的目录”,但如果该文件是一个已存在的文件或一个不存在的文件或目录,则返回“true”。类似地,可以使用op=“-f”来完成文件检查。

    另外,如另一条注释所述,工作目录是R环境的一部分,应该由用户控制,而不是由脚本控制。理想情况下,脚本应该不会改变R环境。为了解决这个问题,我可以使用options()来存储一个全局可用的目录,在这里我需要所有的输出。

    因此,考虑下面的解决方案,其中某个UNIGITEAG只是一个程序员定义的选项名称前缀,这使得不可能有同名的选项存在。(例如,如果您正在开发一个名为“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))
    

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

        6
  •  6
  •   user425678    10 年前

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

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

    mkdirs <- function(fp) {
        if(!file.exists(fp)) {
            mkdirs(dirname(fp))
            dir.create(fp)
        }
    } 
    
    mkdirs("H:/foo/bar")
    
        7
  •  2
  •   David Arenburg Ulrik    11 年前

    若要确定路径是否有效,请尝试:

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

    file.info 不在乎结尾的斜线。

    file.exists 如果目录以斜线结尾,则在Windows上会失败,如果没有斜线则会成功。因此,这不能用于确定路径是否为目录。

    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"]
    
        8
  •  2
  •   den2042    6 年前

    一行:

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