Sprawdź istnienie katalogu i utwórz, jeśli nie istnieje

Często piszę Skrypty R, które generują dużo danych wyjściowych. Uważam, że czystsze jest umieszczenie tego wyjścia w jego własnych katalogach. To, co napisałem poniżej, sprawdzi istnienie katalogu i przeniesie się do niego, lub utworzy Katalog, a następnie przeniesie się do niego. Czy jest lepszy sposób, aby to zrobić?

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

}
 421
r
Author: Rob, 2010-11-18

9 answers

Użycie showWarnings = FALSE:

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

dir.create() nie zawiesza się, jeśli katalog już istnieje, po prostu wypisuje Ostrzeżenie. Więc jeśli możesz żyć z wyświetlaniem ostrzeżeń, nie ma problemu z robieniem tego:

dir.create(file.path(mainDir, subDir))
setwd(file.path(mainDir, subDir))
 424
Author: robbrit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-15 08:42:41

Od 16 kwietnia 2015 roku, wraz z wydaniem {[2] }pojawiła się nowa funkcja o nazwie dir.exists(). Aby użyć tej funkcji i utworzyć katalog, jeśli nie istnieje, możesz użyć:

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

Zwróci FALSE jeśli katalog już istnieje lub jest nie do stworzenia, i TRUE jeśli nie istniał, ale został pomyślnie utworzony.

Zauważ, że aby po prostu sprawdzić, czy katalog istnieje, możesz użyć

dir.exists(file.path(mainDir, subDir))
 173
Author: Molx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-21 23:39:29

Jeśli chodzi o ogólną architekturę, polecam następującą strukturę w odniesieniu do tworzenia katalogów. Obejmuje to większość potencjalnych problemów, a wszelkie inne problemy związane z tworzeniem katalogu zostaną wykryte przez wywołanie 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
}

Należy również pamiętać, że jeśli ~/foo nie istnieje, to wywołanie dir.create('~/foo/bar') zakończy się niepowodzeniem, chyba że podasz recursive = TRUE.

 17
Author: zelanix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-12 16:18:25

Oto proste sprawdzenie, i tworzy katalog jeśli nie istnieje:

## 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!")
}
 16
Author: Surya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-01 21:19:46

One-liner:

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

Przykład:

dateDIR <- as.character(Sys.Date())
outputDIR <- file.path(outD, dateDIR)
if (!dir.exists(outputDIR)) {dir.create(outputDIR)}
 11
Author: den2042,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-15 14:39:55

Użycie pliku.exists () testowanie istnienia katalogu jest problemem w oryginalnym poście. Jeśli subDir zawiera nazwę istniejącego pliku (a nie tylko ścieżkę), plik.exists() zwróci TRUE, ale wywołanie setwd() nie powiedzie się, ponieważ nie można ustawić katalogu roboczego, aby wskazywał na plik.

Zalecałbym użycie file_test( op = "-d", subDir), które zwróci "TRUE", jeśli subDir jest istniejącym katalogiem, ale FALSE, jeśli subDir jest istniejącym plikiem lub nieistniejący plik lub katalog. Podobnie, sprawdzenie pliku może być wykonane za pomocą op=" - f".

Dodatkowo, jak opisano w innym komentarzu, katalog roboczy jest częścią środowiska R I powinien być kontrolowany przez użytkownika, a nie przez skrypt. Skrypty nie powinny, najlepiej, zmieniać środowiska R. Aby rozwiązać ten problem, mogę użyć opcji (), aby zapisać globalnie dostępny katalog, w którym chciałem wszystkie moje dane wyjściowe.

Rozważmy więc następujące rozwiązanie, gdzie someUniqueTag jest tylko zdefiniowanym przez programistę prefiksem dla nazwy opcji, co sprawia, że jest mało prawdopodobne, aby opcja o tej samej nazwie już istniała. (Na przykład, jeśli tworzysz pakiet o nazwie "filer", możesz użyć filera.mainDir i filer.subDir).

Poniższy kod będzie użyty do Ustawienia opcji, które są dostępne do użycia później w innych skryptach (unikając w ten sposób użycia setwd() w skrypcie), a w razie potrzeby do utworzenia folderu:

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

Następnie, w każdym kolejnym skrypt, który potrzebował manipulować plikiem w subDir, możesz użyć czegoś takiego jak:

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

To rozwiązanie pozostawia katalog roboczy pod kontrolą Użytkownika.

 9
Author: G Poole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-13 07:44:07

Miałem problem z R 2.15.3, w którym podczas próby stworzenia struktury drzewa rekurencyjnie na współdzielonym dysku sieciowym otrzymywałem błąd uprawnień.

Aby obejść tę dziwność ręcznie tworzę strukturę;

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

mkdirs("H:/foo/bar")
 8
Author: user425678,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-29 09:57:48

Aby sprawdzić, czy ścieżka jest poprawnym katalogiem, spróbuj:

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

file.info nie obchodzi mnie to.

file.exists w systemie Windows nie powiedzie się katalogowi, jeśli zakończy się ukośnikiem i powiedzie się bez niego. Nie można więc tego użyć do określenia, czy ścieżka jest katalogiem.

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"]
 2
Author: user3807179,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-15 08:43:15

Wiem, że to pytanie zostało zadane jakiś czas temu, ale w razie potrzeby pakiet here jest naprawdę pomocny, ponieważ nie musi odwoływać się do konkretnych ścieżek plików i sprawiać, że kod jest bardziej przenośny. Automatycznie zdefiniuje Twój katalog roboczy jako ten, w którym znajduje się Twój plik .Rproj, więc poniższe często wystarczą bez konieczności definiowania ścieżki pliku do twojego katalogu roboczego:

library(here)

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

 0
Author: Amy M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-01 09:36:46