Проверить наличие директории и создать, если не существует
Я часто нахожу, что пишу сценарии 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)) }
- R: Маскированные функции
- Удалите повторяющиеся пары столбцов, сортируйте строки на основе двух столбцов
- Что делает функция invisible ()?
- используя substitute для получения имени аргумента с помощью
- Найдите, сколько раз повторяющиеся строки повторяются в кадре данных R
- R: gsub, pattern = vector и replacement = vector
- Укажите количество последовательных значений
- Как опустить значения NA при одновременном вставке нескольких значений столбцов?
- Вычисление суммарной суммы для каждой строки
- Как увеличить количество столбцов с помощью R в Linux
- Суммировать строки в data.frame или matrix
- Импорт CSV-файла в R-числовые значения, считанные как символы
- Как автоматически включить все двухсторонние взаимодействия в модели glm в R
Использовать 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))
По состоянию на 16 апреля 2015 года с выпуском 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 }
Также имейте в dir.create('~/foo/bar')
что если ~/foo
не существует, вызов dir.create('~/foo/bar')
завершится неудачно, если вы не укажете recursive = TRUE
.
Использование file.exists () для проверки наличия каталога является проблемой в исходном сообщении. Если в subDir было указано имя существующего файла (а не только путь), file.exists () вернет TRUE, но вызов setwd () завершится неудачно, потому что вы не можете установить рабочий каталог в файл.
Я бы рекомендовал использовать file_test (op = “- d”, subDir), который вернет «TRUE», если subDir является существующим каталогом, но FALSE, если 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")
Вот простую проверку и создает каталог, если он не существует:
## Provide the dir name(ie 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.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"]