我常常发现本身写的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)) }
就通常体系结构而言,我建议在目录建立方面采用如下结构。 这将涵盖大多数潜在的问题,而且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
不存在,则除非指定recursive = TRUE
不然对dir.create('~/foo/bar')
recursive = TRUE
将失败。 app
要找出路径是否为有效目录,请尝试: 函数
file.info(cacheDir)[1,"isdir"]
file.info
不在乎最后的斜线。 测试
若是目录中以斜杠结尾,则Windows上的file.exists
将失败,若是没有该目录,则成功。 所以,这不能用于肯定路径是否为目录。 this
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"]
从2015年4月16日开始,随着R 3.2.0
的发布,有一个名为dir.exists()
的新函数。 要使用此功能并建立目录(若是目录不存在),可使用: spa
ifelse(!dir.exists(file.path(mainDir, subDir)), dir.create(file.path(mainDir, subDir)), FALSE)
若是目录已经存在或没法建立,则返回FALSE
若是目录不存在但建立成功,则返回TRUE
。 code
请注意,只需检查目录是否存在,便可使用 递归
dir.exists(file.path(mainDir, subDir))
在原始文章中,使用file.exists()来测试目录是否存在是一个问题。 若是subDir包含现有文件的名称(而不仅是路径),file.exists()将返回TRUE,可是对setwd()的调用将失败,由于您没法将工做目录设置为指向文件。 开发
我建议使用file_test(op =“-d”,subDir),若是subDir是现有目录,它将返回“ TRUE”,可是若是subDir是现有文件或不存在的文件或目录,则返回FALSE。 一样,可使用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")