तोड़ / बाहर निकलें स्क्रिप्ट


85

मेरे पास एक प्रोग्राम है जो कुछ डेटा विश्लेषण करता है और कुछ सौ लाइनें लंबी है।

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

मैं कोशिश की है break, browserऔर quitऔर उनमें से कोई कार्यक्रम के बाकी के निष्पादन को रोकने के (और quitसाथ ही पूरी तरह से छोड़ने आर, जो कुछ मैं क्या करना चाहते नहीं है के रूप में निष्पादन बंद हो जाता है)। मेरा अंतिम उपाय if-elseनीचे दिया गया एक बयान बना रहा है :

 if(n < 500){}
 else{*insert rest of program here*}

लेकिन यह बुरा कोडिंग अभ्यास की तरह लगता है। क्या मैं कुछ भूल रहा हूँ?


4
quitसबसे निश्चित रूप से कार्यक्रम के बाकी हिस्सों के निष्पादन को रोकता है। कृपया एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण प्रदान करें ।
जोशुआ उलरिच

@ जेकबर्कहेड - क्या मेरा कोड ऊपर है (खाली स्टेटमेंट के साथ) जाने का सबसे अच्छा तरीका है, फिर? @ जोशुआ उलरिच, quitआर के सभी से बाहर निकलता है, लेकिन मैं आर कंसोल पर लौटना चाहता हूं क्योंकि कार्यक्रम को मेरे उद्देश्यों के लिए खुला रहना चाहिए।
user2588829

एक कार्यक्रम से आपका क्या मतलब है? क्या आपका मतलब है कि आप एक फ़ंक्शन चला रहे हैं जो आपने लिखा है या आप एक स्क्रिप्ट में सोर्स कर रहे हैं?
गैविन सिम्पसन

if-else शायद इसे संभालने का सही तरीका है। अपवाद उन स्थितियों के लिए हैं जो सब कुछ सही तरीके से उपयोग किए जाने पर नहीं होना चाहिए। यदि यह कुछ ऐसा है जो हो सकता है और आप जानते हैं कि इसे कैसे संभालना है, तो सामान्य नियंत्रण प्रवाह का उपयोग करें।
मैथ्यू

जवाबों:


59

आप stopifnot()प्रोग्राम का उपयोग कर सकते हैं यदि आप चाहते हैं कि प्रोग्राम त्रुटि उत्पन्न करे:

foo <- function(x) {
    stopifnot(x > 500)
    # rest of program
}

+1! मुझे लगता है कि फ़ंक्शन fooको स्क्रिप्ट की शुरुआत कहा जाना चाहिए और इसमें अन्य सत्यापन नियंत्रण शामिल होना चाहिए ...
agstudy

22
stopifnotकाम है, लेकिन एक गढ़ी गई प्रतिक्रिया का उपयोग if(x < 500) { stop("Not enough observations in 'x': n < 500")}करना पसंद किया जा सकता है। इसके अलावा, अगर यह एक बैच की नौकरी के लिए कुछ है, तो त्रुटि को फेंकने के बिना मुद्दे को संभालना उपयोगी है।
गेविन सिम्पसन

4
ओपी को भ्रमित करने की कोशिश बंद करो। वह जो चाहता है उसे छोड़ दिया जाता है () या रोक (), स्टॉपिफ़नोट () नहीं।
stackoverflowuser2010

10
@ stackoverflowuser2010 वह नहीं चाहता है quit(प्रश्न देखें!) मैं भी नहीं लगता है stopकी stopifnotसबसे अच्छा तरीका यह संभाल करने के लिए है, stopएक त्रुटि फेंकता है, पूरी स्क्रिप्ट सिर्फ गर्भपात करेगी। जब भी stopifnot(या stop) उत्तर ओपी को सबसे अच्छा लगता है, बिना किसी त्रुटि के, सफाई से बाहर निकलने के लिए एक फ़ंक्शन लिखना, स्थितियों की एक विस्तृत श्रृंखला में अधिक फायदेमंद है। बड़ी डेटा विश्लेषण नौकरियों के लिए लंबे समय तक चलने वाली स्क्रिप्ट के बहुत सारे लिखे जाने के बाद, कुछ भी उन कार्यों की तुलना में अधिक कष्टप्रद नहीं है जो समस्या को संभालने के बजाय त्रुटियों को फेंक देते हैं और धीरे-धीरे वापस लौटते हैं। लेकिन स्पष्ट रूप से मैं नहीं जानता कि मैं किस बारे में बात कर रहा हूं ...
गैविन सिम्पसन

क्या आप @GavinSimpson में त्रुटि के बारे में अपनी टिप्पणी स्पष्ट कर सकते हैं? जब मैं कोशिश करता stop("my message")हूं तो मैं टर्मिनल में प्रिंट हो जाता हूं Error: "my message" Execution halted। तो यह एक त्रुटि संदेश आउटपुट दिखाता है, लेकिन क्या आप कह रहे हैं कि यह "त्रुटि" नहीं है? (यानी यह एक बैच जॉब को रोक नहीं पाएगा, जो अगर स्क्रिप्ट में से किसी को भी फेंक देता है, तो उसे एरर करना होगा)। धन्यवाद! (अभी मैं स्क्रिप्ट को रुपये के साथ कह रहा हूं)
आरआरआर

13

सुंदर नहीं है, लेकिन यहां exit()आर में एक कमांड को लागू करने का एक तरीका है जो मेरे लिए काम करता है।

exit <- function() {
  .Internal(.invokeRestart(list(NULL, NULL), NULL))
}

print("this is the last message")
exit()
print("you should not see this")

केवल हल्के से परीक्षण किया गया है, लेकिन जब मैं इसे चलाता हूं, तो मैं देखता हूं this is the last messageऔर फिर स्क्रिप्ट बिना किसी त्रुटि संदेश के समाप्त हो जाती है ।


नकारात्मक पक्ष यह है कि इसे सीआरएएन पैकेज में कोड के लिए अनुमति नहीं है। इसलिए यदि आप एक पैकेज में उपयोग करने का इरादा रखते हैं जिसे आप सीआरएएन पर अपलोड करना चाहते हैं, तो यह एक चेतावनी देगा R CMD CHECK
MS Berends

1
हां, यह सिस्टम फंक्शन की तरह दिखता है। यदि दुभाषिया के आंतरिक विवरण को बदल दिया जाता है, तो यह टूट सकता है, इसलिए एक अलग पैकेट के बजाय आर कोर का एक हिस्सा बेहतर हो सकता है? R स्रोत कोड के माध्यम से अलग-अलग रास्तों का अनुसरण करके मैंने यह पाया कि कैसे मैं एक त्रुटि संदेश उत्सर्जित किए बिना दुभाषिया से बाहर निकलने के लिए सही जगह पर समाप्त हो सकता हूं। वहाँ मुझे मिलने के लिए बहुत सारे तरीके नहीं थे; यही कारण है कि मैं .invokeRestartजो तब बदले में जरूरत का उपयोग करता है .Internal
जॉचेन

अरे हाँ, CRAN नीतियों से इतर, मुझे लगता है कि यह एक अच्छा समाधान है! मैं आपको +10 प्रतिनिधि
पहुंचाता हूं

अजीब। मैंने सिर्फ यह कोशिश की और अंतिम आउटपुट लाइन [1] थी "आपको यह नहीं देखना चाहिए" आर संस्करण 3.4.3 (2017-11-30) प्लेटफार्म: x86_64-pc-linux-gnu (64-bit) के तहत चल रहा है: Red Hat एंटरप्राइज लिनक्स सर्वर रिलीज 6.10 (सैंटियागो)
कोडिंगमैटर्स

@aspiringGuru मैंने बस कोशिश की और यह अभी भी मेरे लिए काम करता है। क्या आपने स्क्रिप्ट के रूप में कमांड्स चलाए? यदि आप उन्हें कमांड लाइन में एक के बाद एक चलाते हैं ( जैसे कॉपी और पेस्ट का उपयोग करते हुए), तो बेशक exit()अगले कमांड (जिसे अभी तक दर्ज नहीं किया गया है) को चलाने से नहीं रोका जा सकता है ...
jochen

12

अपने अगर-और निर्माण को उल्टा कर दें:

if(n >= 500) {
  # do stuff
}
# no need for else

2
पर्याप्त सरल है और मुझे लगता है कि यह सबसे अच्छा हो सकता है जो मैं कर सकता हूं, धन्यवाद
user2588829

9

संपादित करें: ऐसा लगता है कि ओपी एक लंबी पटकथा पर चल रहा है, उस स्थिति में गुणवत्ता नियंत्रण के बाद केवल स्क्रिप्ट के भाग को लपेटने की जरूरत है

if (n >= 500) {

.... long running code here

}

यदि किसी फ़ंक्शन से बाहर निकल रहा है , तो आप शायद केवल return()या तो स्पष्ट रूप से या अंतर्निहित रूप से चाहते हैं ।

उदाहरण के लिए, एक स्पष्ट डबल रिटर्न

foo <- function(x) {
  if(x < 10) {
    return(NA)
  } else {
    xx <- seq_len(x)
    xx <- cumsum(xx)
  }
  xx ## return(xx) is implied here
}

> foo(5)
[1] 0
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55

द्वारा return()गर्भित किया जा रहा, मेरा मतलब है के रूप में यदि आप कर रहे अंतिम पंक्ति है कि return(xx)है, लेकिन यह थोड़ा और अधिक करने के लिए कॉल बंद छोड़ने के लिए कुशल है return()

कुछ लोग कई रिटर्न खराब शैली का उपयोग करने पर विचार करते हैं; लंबे कार्यों में, जहाँ कार्य से बाहर निकलता है, नज़र रखना मुश्किल या त्रुटि प्रवण हो सकता है। इसलिए एक विकल्प के लिए एक एकल वापसी बिंदु होना चाहिए, लेकिन if () else ()खंड का उपयोग करके वापसी वस्तु को बदलें । ऐसा संशोधन किया foo()जाएगा

foo <- function(x) {
  ## out is NA or cumsum(xx) depending on x
  out <- if(x < 10) {
    NA
  } else {
    xx <- seq_len(x)
    cumsum(xx)
  }
  out ## return(out) is implied here
}

> foo(5)
[1] NA
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55

मैंने इस बारे में भी सोचा, लेकिन यह स्पष्ट नहीं है कि ओपी एक समारोह से बाहर निकलने की बात कर रहा है।
थॉमस

हाँ, थॉमस सही है - मैं एक समारोह से बाहर निकलने के बारे में बात नहीं कर रहा हूं।
14:25 बजे user2588829

1
@ user2588829 आप 100+ लाइन स्क्रिप्ट के बजाय R में एक फंक्शन के रूप में रखना ज्यादा बेहतर होगा।
गैविन सिम्पसन

@GavinSimpson ओह, मैं अभी भी आर के लिए नया हूँ इसलिए मुझे नहीं पता था कि। अगर मैं इसे 100+ लाइन फ़ंक्शन के रूप में परिभाषित करता हूं तो क्या यह बेहतर अभ्यास है?
user2588829

1
@ user2588829 हाँ, बेहतर है। आप फ़ंक्शन के तर्कों को नियंत्रित करते हैं ताकि जो आवश्यक हो उसमें पास हो सके। इसके अलावा, आप जो विश्लेषण करते हैं उसे चलाने के लिए कोड की 100+ लाइनों की सोर्सिंग के बजाय myFun(arg1, arg2, arg3)यह सिर्फ चीजों को व्यवस्थित करने का एक बेहतर तरीका है।
गैविन सिम्पसन

9

शायद आप किसी बिंदु पर एक लंबी स्क्रिप्ट को निष्पादित करना बंद करना चाहते हैं। अर्थात। जैसे आप C या Python में हार्ड कोड से बाहर निकलना चाहते हैं ()।

print("this is the last message")
stop()
print("you should not see this")

1
इस कोड के लिए मुझे त्रुटि संदेश मिलता है Error in eval(expr, envir, enclos) :
जोचेन

2
हां, निष्पादन वास्तव में बंद हो जाता है। संयोग से, यदि आप प्रतिस्थापित करते हैंstop() साथ exit()या please.stop.now(), स्क्रिप्ट भी बंद हो जाता है (केवल त्रुटि संदेश अलग हैं)।
13

1
@jochen stop()कमांड के अंदर एक उद्धृत वाक्यांश जोड़ना अन्य संदेशों से इस "त्रुटि" को अलग करने में मदद कर सकता है। उदाहरण के लिए: अकेले की stop("Manual break inserted here")तुलना में अधिक जानकारीपूर्ण हो सकता है stop()
उमर वासो

3

यह एक पुराना सवाल है लेकिन अभी तक कोई साफ समाधान नहीं है। यह शायद इस विशिष्ट प्रश्न का उत्तर नहीं दे रहा है, लेकिन जो 'एक आर स्क्रिप्ट से सुंदर तरीके से बाहर निकलने के लिए उत्तर' की तलाश कर रहे हैं, वे शायद यहां उतरेंगे। ऐसा लगता है कि आर डेवलपर्स एक निकास () फ़ंक्शन को लागू करना भूल गए। वैसे भी, मुझे जो ट्रिक मिली है वह है:

continue <- TRUE

tryCatch({
     # You do something here that needs to exit gracefully without error.
     ...

     # We now say bye-bye         
     stop("exit")

}, error = function(e) {
    if (e$message != "exit") {
        # Your error message goes here. E.g.
        stop(e)
    }

    continue <<-FALSE
})

if (continue) {
     # Your code continues here
     ...
}

cat("done.\n")

मूल रूप से, आप कोड के निर्दिष्ट ब्लॉक की निरंतरता या नहीं इंगित करने के लिए एक ध्वज का उपयोग करते हैं। फिर आप stop()फ़ंक्शन के त्रुटि हैंडलर को एक अनुकूलित संदेश पास करने के लिए फ़ंक्शन का उपयोग करते हैं tryCatch()। यदि त्रुटि हैंडलर आपके संदेश को इनायत से बाहर निकलने के लिए प्राप्त करता है, तो यह सिर्फ त्रुटि को अनदेखा करता है और निरंतरता ध्वज को सेट करता है FALSE


0

आप वर्तमान प्रक्रिया को बाधित करने और कंसोल पर लौटने के लिए "टूल" पैकेज pskillमें फ़ंक्शन का उपयोग कर सकते हैं R। इसके विपरीत, मेरे पास एक स्टार्टअप फ़ाइल में परिभाषित निम्न फ़ंक्शन है जो मैं प्रत्येक स्क्रिप्ट की शुरुआत में स्रोत करता हूं। आप इसे सीधे अपने कोड की शुरुआत में भी कॉपी कर सकते हैं। फिर halt()मक्खी पर स्क्रिप्ट निष्पादन को रोकने के लिए अपने कोड में किसी भी बिंदु पर डालें । यह फ़ंक्शन GNU / Linux पर अच्छी तरह से काम करता है और Rप्रलेखन से देखते हुए , यह विंडोज पर भी काम करना चाहिए (लेकिन मैंने जांच नहीं की)।

# halt: interrupts the current R process; a short iddle time prevents R from
# outputting further results before the SIGINT (= Ctrl-C) signal is received 
halt <- function(hint = "Process stopped.\n") {
    writeLines(hint)
    require(tools, quietly = TRUE)
    processId <- Sys.getpid() 
    pskill(processId, SIGINT)
    iddleTime <- 1.00
    Sys.sleep(iddleTime)
}

> pskill (processId, SIGINT) सत्र को बंद कर देता है और उपयोगकर्ता को RStudio से बाहर कर देता है। यह काफी खतरनाक लेकिन कार्यात्मक है ...
एस्पांटा

नहीं पता था कि यह RStudio को क्रैश करेगा, लेकिन एक ही मुद्दे पर चर्चा की जाती है: stackoverflow.com/questions/32820534/… हालांकि लिनक्स पर, मेरा समाधान ठीक काम करता है। Stopifnot पर इसका लाभ यह है कि stopifnot () त्रुटि संदेश दिखाई नहीं देता है।
फ़्राँस्वा टोंन्यू

मैंने विंडोज पर जाँच की और यह पागल व्यवहार करता है। फिर भी धन्यवाद। मुझे pskill पसंद है।
एस्पांटा

0

यहाँ:

if(n < 500)
{
    # quit()
    # or 
    # stop("this is some message")
}
else
{
    *insert rest of program here*
}

दोनों quit()और stop(message)अपनी स्क्रिप्ट बंद हो जाएगा। यदि आप R कमांड प्रॉम्प्ट से अपनी स्क्रिप्ट सोर्स कर रहे हैं, तो quit()R से भी बाहर निकल जाएंगे।


7
पहले से पोस्ट किए गए लोगों की नकल करने वाले उत्तर पोस्ट करना बुरा है।
थॉमस

@ थोमस किस उत्तर का यह डुप्लिकेट करता है? मैं केवल इस उत्तर को स्टॉप और छोड़ दोनों का उपयोग करके देखता हूं, और वास्तव में उनके बीच के अंतर को समझा रहा हूं।

@Thomas: बताइए कि वास्तव में मेरा उत्तर डुप्लिकेट क्या है।
stackoverflowuser2010

@ थोमस: मैंने आपकी आलोचना के संबंध में एक प्रश्न प्रस्तुत किया है। मैं आपको इसका जवाब देने की प्रतीक्षा कर रहा हूं।
stackoverflowuser2010

5
@ netskink के उत्तर का उपयोग करता है stop(), और ओपी ने पहले से ही टिप्पणियों में संकेत दिया है कि वे नहीं चाहते हैं quit()...
बेन बोल्कर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.