Когда вы конвертируете .1 или 1/10 в base 2 (двоичный), вы получаете повторяющийся шаблон после десятичной точки, точно так же, как пытаетесь представить 1/3 в базе 10. Значение не является точным, и поэтому вы можете 't делать точную математику с ней, используя обычные методы с плавающей запятой.
Чтобы выяснить, является ли путь действительным каталогом try:
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"]
Использование файла 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))
Это решение оставляет рабочий каталог под контролем пользователя .
По состоянию на 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
}
Также имейте в виду, что если ~/foo
не существует, то вызов dir.create('~/foo/bar')
, если вы не укажете recursive = TRUE
.
Вот простая проверка и создает каталог, если он не существует:
## 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!")
}
У меня возникла проблема с R 2.15.3, в результате чего при попытке создать рекурсивно структуру дерева на общем сетевом диске я получил бы ошибку разрешения.
Чтобы обойти эту странность, я вручную создаю структуру ;
mkdirs <- function(fp) {
if(!file.exists(fp)) {
mkdirs(dirname(fp))
dir.create(fp)
}
}
mkdirs("H:/foo/bar")