r

Compruebe la existencia del directorio y cree si no existe



(7)

A partir del 16 de abril de 2015, con el lanzamiento de R 3.2.0 existe una nueva función llamada dir.exists() . Para usar esta función y crear el directorio si no existe, puede usar:

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

Esto devolverá FALSE si el directorio ya existe o es increable, y TRUE si no existió pero se creó con éxito.

Tenga en cuenta que para verificar simplemente si existe el directorio puede usar

dir.exists(file.path(mainDir, subDir))

A menudo me encuentro escribiendo scripts R que generan mucha salida. Me parece más limpio poner esta salida en su propio directorio (s). Lo que he escrito a continuación comprobará la existencia de un directorio y se moverá a él, o creará el directorio y luego se moverá a él. ¿Hay una mejor manera de abordar esto?

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


Aquí está la comprobación simple , y crea el directorio si no existe:

## 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!") }


El uso de file.exists () para probar la existencia del directorio es un problema en la publicación original. Si subDir incluye el nombre de un archivo existente (en lugar de solo una ruta), file.exists () devolverá TRUE, pero la llamada a setwd () fallará porque no puede configurar el directorio de trabajo para que apunte a un archivo.

Recomendaría el uso de file_test (op = "- d", subDir), que devolverá "TRUE" si subDir es un directorio existente, pero FALSE si subDir es un archivo existente o un archivo o directorio no existente. De forma similar, la comprobación de un archivo se puede realizar con op = "- f".

Además, como se describe en otro comentario, el directorio de trabajo es parte del entorno R y debe ser controlado por el usuario, no por un script. Los scripts deberían, idealmente, no cambiar el entorno R Para solucionar este problema, podría usar las opciones () para almacenar un directorio disponible globalmente en el que quería todos mis resultados.

Entonces, considere la siguiente solución, en la que someUniqueTag es solo un prefijo definido por el programador para el nombre de la opción, lo que hace que sea poco probable que ya exista una opción con el mismo nombre. (Por ejemplo, si estaba desarrollando un paquete llamado "archivador", podría usar filer.mainDir y filer.subDir).

El siguiente código se usaría para configurar las opciones que estarán disponibles más adelante en otros scripts (evitando así el uso de setwd () en un script), y para crear la carpeta si es necesario:

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

Luego, en cualquier secuencia de comandos posterior que necesite manipular un archivo en subdir, puede usar algo como:

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

Esta solución deja el directorio de trabajo bajo el control del usuario.


En términos de arquitectura general, recomendaría la siguiente estructura con respecto a la creación de directorios. Esto cubrirá la mayoría de los problemas potenciales y cualquier otro problema con la creación del directorio será detectado por la llamada 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 }

También tenga en cuenta que si ~/foo no existe, la llamada a dir.create(''~/foo/bar'') fallará a menos que especifique recursive = TRUE .


Para averiguar si una ruta es un directorio válido, intente:

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

file.info no le importa una barra al final.

file.exists en Windows fallará para un directorio si termina en una barra y tiene éxito sin él. Por lo tanto, esto no se puede usar para determinar si una ruta es un directorio.

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"]


Tuve un problema con R 2.15.3, por lo que al intentar crear una estructura de árbol de forma recursiva en una unidad de red compartida obtendría un error de permiso.

Para sortear esta rareza creo manualmente la estructura;

mkdirs <- function(fp) { if(!file.exists(fp)) { mkdirs(dirname(fp)) dir.create(fp) } } mkdirs("H:/foo/bar")


Utilice showWarnings = FALSE :

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

dir.create() no se dir.create() si el directorio ya existe, simplemente imprime una advertencia. Entonces, si puedes vivir viendo advertencias, no hay problema con solo hacer esto:

dir.create(file.path(mainDir, subDir)) setwd(file.path(mainDir, subDir))