[r] 디렉토리의 존재를 확인하고 존재하지 않는 경우 생성

나는 종종 많은 출력을 생성하는 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))


답변

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


답변

일반적인 아키텍처 측면에서 디렉토리 생성과 관련하여 다음 구조를 권장합니다. 이것은 대부분의 잠재적 인 문제를 다루며 디렉토리 생성과 관련된 다른 문제는 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.


답변

다음은 간단한 check 이며 존재하지 않는 경우 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!")
}


답변

디렉토리의 존재를 테스트하기 위해 file.exists ()를 사용하는 것은 원래 게시물의 문제입니다. subDir에 경로가 아닌 기존 파일의 이름이 포함 된 경우 file.exists ()는 TRUE를 반환하지만 파일을 가리 키도록 작업 디렉토리를 설정할 수 없기 때문에 setwd () 호출이 실패합니다.

subDir이 기존 디렉토리 인 경우 “TRUE”를 반환하고, subDir이 기존 파일이거나 존재하지 않는 파일 또는 디렉토리 인 경우 FALSE를 반환하는 file_test (op = “-d”, subDir)를 사용하는 것이 좋습니다. 마찬가지로 파일 확인은 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))

이 솔루션은 작업 디렉토리를 사용자가 제어합니다.


답변

R 2.15.3에 문제가있어서 공유 네트워크 드라이브에서 반복적으로 트리 구조를 만들려고 할 때 권한 오류가 발생합니다.

이 이상한 점을 극복하기 위해 수동으로 구조를 만듭니다.

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

mkdirs("H:/foo/bar")


답변

짧막 한 농담:

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