Saya sering menemukan diri saya menulis skrip R yang menghasilkan banyak output. Saya merasa lebih bersih untuk menempatkan output ini ke dalam direktori itu sendiri. Apa yang saya tulis di bawah ini akan memeriksa keberadaan direktori dan pindah ke dalamnya, atau membuat direktori dan kemudian pindah ke dalamnya. Apakah ada cara yang lebih baik untuk mendekati ini?
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))
}
setwd()
kode R - itu pada dasarnya mengalahkan ide untuk menggunakan direktori yang berfungsi karena Anda tidak lagi dapat dengan mudah memindahkan kode di antara komputer..bat
file yang tidak akan pernah diubah oleh pengguna akhir.setwd
bekerja dengan jalur jaringan. Anda hanya perlu memberikan jalur untuk menyimpan hasil dan masih bekerja dengan jalur saat ini (yang ditetapkan saat sesi R dimulai). Atau mulai R dengan direktori kerja keinginan.out_dir <- "path/to/output/directory"
lalu gunakanwrite.table(file = file.path(out_dir,"table_1.csv"), ...)
. Atau bahkanout_file <- function(fnm) file.path("path/to/output/directory", fnm)
kemudianwrite.table(file = out_file("table_1.csv"), ...)
(metode yang sama saya gunakan ketika bekerja dengan drive jaringan).Jawaban:
Gunakan
showWarnings = FALSE
:dir.create()
tidak macet jika direktori sudah ada, itu hanya mencetak peringatan. Jadi jika Anda dapat hidup dengan melihat peringatan, tidak ada masalah dengan hanya melakukan ini:sumber
showWarnings = FALSE
bahwa ini juga akan menyembunyikan peringatan lain seperti direktori tidak dapat dibuat.dir.create("test1/test2/test3/", recursive=TRUE)
?suppressWarnings(<statement>)
akan menekan peringatan hanya untuk pernyataan itu.Pada 16 April 2015, dengan dirilisnya
R 3.2.0
ada fungsi baru yang disebutdir.exists()
. Untuk menggunakan fungsi ini dan membuat direktori jika tidak ada, Anda dapat menggunakan:Ini akan kembali
FALSE
jika direktori sudah ada atau tidak dapat dikelola, danTRUE
jika tidak ada tetapi berhasil dibuat.Perhatikan bahwa untuk cukup memeriksa apakah direktori tersebut ada, Anda dapat menggunakan
sumber
ifelse()
untuk percabangan non-vektor.|
bukan skalar||
. Ini bekerja tetapi merupakan praktik buruk.|
, apakah vektorisasi itu alasannya||
kadang tidak bekerja ? Saya tahu ini di luar topik, tetapi saya terlalu bersemangat untuk mencari tahu. Saya akan defo pergi dan membaca lebih lanjut tentang vektorisasi. Terima kasihifelse
?Dalam hal arsitektur umum saya akan merekomendasikan struktur berikut berkaitan dengan pembuatan direktori. Ini akan mencakup sebagian besar masalah potensial dan masalah lain dengan pembuatan direktori akan terdeteksi oleh
dir.create
panggilan.Perlu diketahui juga bahwa jika
~/foo
tidak ada maka panggilan kedir.create('~/foo/bar')
akan gagal kecuali Anda tentukanrecursive = TRUE
.sumber
Ini cek sederhana , dan buat dir jika tidak ada:
sumber
Penggunaan file.exists () untuk menguji keberadaan direktori adalah masalah dalam posting asli. Jika subDir menyertakan nama file yang ada (bukan hanya path), file.exists () akan mengembalikan TRUE, tetapi panggilan ke setwd () akan gagal karena Anda tidak dapat mengatur direktori kerja untuk menunjuk pada file.
Saya akan merekomendasikan penggunaan file_test (op = "- d", subDir), yang akan mengembalikan "TRUE" jika subDir adalah direktori yang sudah ada, tetapi FALSE jika subDir adalah file yang ada atau file atau direktori yang tidak ada. Demikian pula, memeriksa file dapat dilakukan dengan op = "- f".
Selain itu, seperti dijelaskan dalam komentar lain, direktori kerja adalah bagian dari lingkungan R dan harus dikontrol oleh pengguna, bukan skrip. Skrip seharusnya, idealnya, tidak mengubah lingkungan R. Untuk mengatasi masalah ini, saya mungkin menggunakan opsi () untuk menyimpan direktori yang tersedia secara global di mana saya ingin semua output saya.
Jadi, pertimbangkan solusi berikut, di mana someUniqueTag hanyalah awalan yang ditentukan programmer untuk nama opsi, yang membuatnya tidak mungkin bahwa opsi dengan nama yang sama sudah ada. (Misalnya, jika Anda mengembangkan paket yang disebut "filer", Anda dapat menggunakan filer.mainDir dan filer.subDir).
Kode berikut akan digunakan untuk mengatur opsi yang tersedia untuk digunakan nanti di skrip lain (sehingga menghindari penggunaan setwd () dalam skrip), dan untuk membuat folder jika perlu:
Kemudian, dalam skrip selanjutnya yang perlu memanipulasi file di subDir, Anda dapat menggunakan sesuatu seperti:
Solusi ini meninggalkan direktori kerja di bawah kendali pengguna.
sumber
Saya punya masalah dengan R 2.15.3 di mana ketika mencoba membuat struktur pohon secara rekursif pada drive jaringan bersama saya akan mendapatkan kesalahan izin.
Untuk menyiasati keanehan ini saya secara manual membuat struktur;
sumber
Satu-liner:
if (!dir.exists(output_dir)) {dir.create(output_dir)}
Contoh:
sumber
Untuk mengetahui apakah jalur adalah direktori yang valid coba:
file.info
tidak peduli tentang garis miring pada akhirnya.file.exists
pada Windows akan gagal untuk direktori jika berakhir dengan garis miring, dan berhasil tanpanya. Jadi ini tidak dapat digunakan untuk menentukan apakah path adalah direktori.sumber
dir.create()
bagian)? Apakah pernyataan itu salah atau hanya dianggap tidak membantu untuk menyelesaikan pertanyaan?