निर्देशिका के अस्तित्व की जाँच करें और यदि मौजूद नहीं है तो बनाएं


388

मैं अक्सर अपने आप को आर स्क्रिप्ट लिखता हूं जो बहुत सारे आउटपुट उत्पन्न करता है। मुझे लगता है कि इस आउटपुट को स्वयं की निर्देशिका में रखना क्लीनर है। नीचे मैंने जो लिखा है वह किसी निर्देशिका के अस्तित्व की जाँच करेगा और उसमें चला जाएगा, या निर्देशिका बनाकर फिर उसमें चला जाएगा। क्या यह दृष्टिकोण करने का एक बेहतर तरीका है?

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))

}

1
मुझे यकीन है कि मैंने एक आर फ़ंक्शन देखा है जो एक अस्थायी रूप से उत्पन्न नाम के साथ एक अस्थायी निर्देशिका बनाता है और नाम देता है। मुझे लगता है कि एक समान एक है जो एक अस्थायी फ़ाइल बनाता है। मैं उन्हें ऑफहैंड नहीं कर सकता, लेकिन डेटाबेल पैकेज ( cran.r-project.org/web/packages/DatABEL/index.html ) में एक फ़ंक्शन get_temporary_file_name है।
पॉलहर्लुक

42
आपको setwd()आर कोड में कभी भी उपयोग नहीं करना चाहिए - यह मूल रूप से एक कार्यशील निर्देशिका का उपयोग करने के विचार को हरा देता है क्योंकि आप अब आसानी से कंप्यूटर के बीच अपने कोड को स्थानांतरित नहीं कर सकते।
हैडले

6
@ phadder के लिए दिलचस्प विषय, मैं अन्य तरीकों पर आपके विचारों की सराहना करूंगा। काम के समय, सभी कंप्यूटर एक ही नेटवर्क से सिंक होते हैं, इसलिए फ़ाइल पथ संगत होते हैं। यदि वे नहीं हैं, तो हमारे पास स्क्रिप्ट की पोर्टेबिलिटी से निपटने के लिए बड़े मुद्दे हैं। इस विशेष उदाहरण में, मैं एक स्क्रिप्ट लिख रहा था जिसे एक मशीन पर लोड किया जाएगा जिसे 2 साल के लिए हमारे राष्ट्रीय उद्यानों के आसपास ले जाया जाएगा। यह स्क्रिप्ट स्थानीय SQL उदाहरण से डेटा लेगी, कुछ प्रोसेसिंग करेगी, और एक .csv थूक देगी। अंतिम उत्पाद एक .batफ़ाइल होगी जिसे अंतिम उपयोगकर्ता को कभी भी संशोधित नहीं करना होगा।
चेस

@ देखें लेकिन आपको setwdनेटवर्क पथों के साथ काम करने की आवश्यकता नहीं है । आपको परिणामों को सहेजने के लिए पथ प्रदान करने की आवश्यकता है और अभी भी वर्तमान पथ के साथ काम करना है (जो कि आर सत्र शुरू होने पर स्थापित होता है)। या आर कामना निर्देशिका के साथ शुरू करें।
मारेक

5
हां। या पैरामीरीज़ out_dir <- "path/to/output/directory"और फिर उपयोग करें write.table(file = file.path(out_dir,"table_1.csv"), ...)। या यहां तक ​​कि out_file <- function(fnm) file.path("path/to/output/directory", fnm)और फिर write.table(file = out_file("table_1.csv"), ...)(इसी तरह की विधि जब मैं नेटवर्क ड्राइव के साथ काम करता हूं)।
मारेक

जवाबों:


403

उपयोग करें 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))

58
उपयोग करते समय ध्यान रखें showWarnings = FALSEकि यह अन्य चेतावनियों को भी छिपा देगा जैसे कि निर्देशिका अनुपलब्ध है।
zelanix

5
^ क्या केवल एक विशिष्ट चेतावनी को दबाने का एक तरीका है?
बास

2
नमस्ते, मैं चाहता हूं कि ओटी नेस्टेड डायरेक्टरी बनाएं, जैसे अगर मैं फ़ोल्डर टेस्ट 1 में हूं तो इसके अंदर टेस्ट 2 इसके अंदर टेस्ट 3 ... लेकिन अभी मैं समस्या का सामना कर रहा हूं। वहाँ एक रास्ता है कि मैं निर्देशिका के 3 स्तर बना सकता है भले ही Directory1 बाहर नहीं निकलता है ??
प्रवीण केसानी

10
@PraveenKesani क्या आप इसे ढूंढ रहे हैं dir.create("test1/test2/test3/", recursive=TRUE):?
डीन।

6
@Bas वास्तव में देर से प्रतिक्रिया लेकिन suppressWarnings(<statement>)सिर्फ उस बयान के लिए चेतावनी को दबा देगा।
राम आरएस

163

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))

9
बस ध्यान दें कि ifelse()गैर-वेक्टरीकृत शाखाओं के लिए उपयोग करना अच्छा नहीं है ।
लियोनेल हेनरी

2
@Bas क्योंकि आपका कोड गलत तरीके से पढ़ता है जैसे कि कुछ वेक्टर हो रहा है। यह |अदिश के बजाय सदिश का उपयोग करने जैसा है ||। यह काम करता है लेकिन बुरा अभ्यास है।
लियोनेल हेनरी

1
अरे लानत है, इसलिए मैं अपने बयानों को गलत होने के साथ-साथ इस्तेमाल कर रहा हूं |, क्या वैश्वीकरण वह कारण है जो ||कभी-कभी काम नहीं करता है ? मुझे पता है कि यह बंद विषय है लेकिन मैं अभी पता लगाने के लिए बहुत उत्सुक हूं। मैं डिफ्यूज़ करूँगा और वैश्वीकरण के बारे में और अधिक पढ़ूँगा। धन्यवाद
बास

4
तो अगर हमें बचना चाहिए तो ऐसा करने का सबसे अच्छा अभ्यास तरीका क्या है ifelse?
किलर्सनैल

6
अगर और किसी का उपयोग कर रहे हैं;)
लियोनेल हेनरी

17

सामान्य वास्तुकला के संदर्भ में मैं निर्देशिका संरचना के संबंध में निम्नलिखित संरचना की सिफारिश करूंगा। यह अधिकांश संभावित मुद्दों को कवर करेगा और 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


3
वहाँ एक कारण है कि आप पेस्ट का उपयोग करें (...) फ़ाइल बनाम .पथ (mainDir, उपडायर)। इसके अलावा अगर आपने एक पथ <- file.path (mainDir, subDir) किया है तो आप इसे 5 बार पुन: उपयोग कर सकते हैं यदि कथन अधिक पठनीय हैं।
माइक एफएफ

14

यहाँ साधारण जाँच है , और अगर मौजूद नहीं है तो dir बनाता है:

## 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!")
}

9

निर्देशिका के अस्तित्व के परीक्षण के लिए file.exists () का उपयोग मूल पोस्ट में एक समस्या है। यदि उप-निर्देशिका में एक मौजूदा फ़ाइल (केवल एक पथ के बजाय) का नाम शामिल है, तो file.exists () TRUE लौटाएगा, लेकिन setwd () में कॉल विफल हो जाएगी क्योंकि आप किसी फ़ाइल पर इंगित करने के लिए कार्य निर्देशिका को सेट नहीं कर सकते।

मैं file_test (op = "- d", subDir) के उपयोग की सिफारिश करूंगा, जो कि "TRUE" वापस कर देगा यदि उप-निर्देशिका एक मौजूदा निर्देशिका है, लेकिन FALSE अगर उप-निर्देशिका एक मौजूदा फ़ाइल या गैर-मौजूद फ़ाइल या निर्देशिका है। इसी तरह, किसी फ़ाइल की जाँच op = "- f" से पूरी की जा सकती है।

इसके अतिरिक्त, जैसा कि एक अन्य टिप्पणी में वर्णित है, वर्किंग डायरेक्टरी आर पर्यावरण का हिस्सा है और इसे उपयोगकर्ता द्वारा नियंत्रित किया जाना चाहिए, न कि किसी स्क्रिप्ट पर। लिपियों को आदर्श रूप से, आर पर्यावरण को नहीं बदलना चाहिए। इस समस्या को हल करने के लिए, मैं विश्व स्तर पर उपलब्ध निर्देशिका को संग्रहीत करने के लिए विकल्पों () का उपयोग कर सकता हूं, जहां मैं अपने सभी आउटपुट चाहता था।

तो, निम्नलिखित समाधान पर विचार करें, जहां someUniqueTag विकल्प नाम के लिए सिर्फ एक प्रोग्रामर-परिभाषित उपसर्ग है, जिससे यह संभावना नहीं है कि समान नाम वाला विकल्प पहले से मौजूद है। (उदाहरण के लिए, यदि आप "फाइलर" नामक एक पैकेज विकसित कर रहे थे, तो आप filer.mainDir और filer.subDir का उपयोग कर सकते हैं)।

निम्नलिखित कोड का उपयोग उन विकल्पों को सेट करने के लिए किया जाएगा जो बाद में अन्य लिपियों में उपयोग के लिए उपलब्ध हैं (इस प्रकार स्क्रिप्ट में सेटवार्ड () के उपयोग से बचना), और यदि आवश्यक हो तो फ़ोल्डर बनाना:

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))
  }
}

उसके बाद, किसी भी बाद की स्क्रिप्ट में, जिसे उपडिर में किसी फ़ाइल में हेरफेर करने की आवश्यकता होती है, आप कुछ इस तरह का उपयोग कर सकते हैं:

mainDir = getOption(someUniqueTag.mainDir)
subDir = getOption(someUniqueTag.subDir)
filename = "fileToBeCreated.txt"
file.create(file.path(mainDir, subDir, filename))

यह समाधान उपयोगकर्ता के नियंत्रण में कार्यशील निर्देशिका को छोड़ देता है।


8

मेरे पास R 2.15.3 के साथ एक मुद्दा था जिसके द्वारा एक साझा नेटवर्क ड्राइव पर पुनरावर्ती रूप से एक पेड़ संरचना बनाने की कोशिश करते समय मुझे एक अनुमति त्रुटि मिलेगी।

इस विषमता को प्राप्त करने के लिए मैं स्वयं संरचना बनाता हूं;

mkdirs <- function(fp) {
    if(!file.exists(fp)) {
        mkdirs(dirname(fp))
        dir.create(fp)
    }
} 

mkdirs("H:/foo/bar")

5

एक लाइन:

if (!dir.exists(output_dir)) {dir.create(output_dir)}

उदाहरण:

dateDIR <- as.character(Sys.Date())
outputDIR <- file.path(outD, dateDIR)
if (!dir.exists(outputDIR)) {dir.create(outputDIR)}

2

यह पता लगाने के लिए कि क्या कोई पथ वैध निर्देशिका है:

file.info(cacheDir)[1,"isdir"]

file.info अंत में एक स्लेश के बारे में परवाह नहीं है।

file.existsअगर यह एक स्लैश में समाप्त होता है, तो विंडोज एक निर्देशिका के लिए विफल हो जाएगा, और इसके बिना सफल होता है। तो यह निर्धारित करने के लिए इस्तेमाल नहीं किया जा सकता है कि क्या कोई मार्ग एक निर्देशिका है।

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"]

इस उत्तर के बारे में क्या गलत है ( dir.create()भाग सहित नहीं )? क्या कथन गलत हैं या केवल प्रश्न को हल करने में मददगार नहीं माना जाता है?
एमएसचिल्ली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.