我常常發現本身寫的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")