आर

2010-04-12 3 views
94

में अपवाद हैंडलिंग क्या किसी के पास आर में अपवाद हैंडलिंग के उदाहरण/ट्यूटोरियल हैं? आधिकारिक दस्तावेज बहुत terse है।आर

+1

यह भी एक अच्छा उदाहरण है: http://stackoverflow.com/q/12193779/2026975। – imriss

+0

मुझे यह ब्लॉग पोस्ट काफी उपयोगी पाया गया: [http://mazamascience.com/WorkingWithData/?p=912 ](http://mazamascience.com/WorkingWithData/?p=912) –

+0

मैंने एक SO दस्तावेज़ विषय का अनुरोध किया इस सवाल के लिए। – Leonid

उत्तर

30

शेन के जवाब के अलावा आपको अन्य स्टैक ओवरफ्लो चर्चाओं के बारे में बताते हुए, आप कोड खोज सुविधा का प्रयास कर सकते हैं। यह मूल जवाब Google की कोड खोज की ओर इशारा किया के बाद से बंद कर दिया गया है, लेकिन आप जैसे के रूप में

बस रिकार्ड के लिए

, वहाँ भी है try लेकिन tryCatch बेहतर हो सकता है। मैंने Google Code Search पर त्वरित गणना की कोशिश की लेकिन क्रिया के लिए बहुत अधिक झूठी सकारात्मक कोशिशें - फिर भी ऐसा लगता है कि tryCatch अधिक व्यापक रूप से उपयोग किया जाता है।

+0

शायद यह उदाहरण मदद कर सकता है: [http://stackoverflow.com/a/12195574/2026975 ](httpoverflow.com/a/12195574/2026975) – imriss

+0

ए [गीथब खोज] (https: // github। कॉम/सर्च? q = tryCatch + भाषा% 3AR और टाइप = कोड और रेफरी = सर्च्रेसल्ट्स) निष्क्रिय लिंक के लिए शायद एक सभ्य प्रतिस्थापन है। – Gregor

58

असल में आप tryCatch() फ़ंक्शन का उपयोग करना चाहते हैं। अधिक जानकारी के लिए सहायता ("tryCatch") देखें।

यहाँ एक तुच्छ उदाहरण है (ध्यान रखें कि आप जो कुछ करना चाहते हैं कर सकते हैं एक त्रुटि के साथ):

+1

तीसरा लिंक एक लिंक नहीं है। – Marek

+8

शेन की गलती नहीं - तर्कसंगत रूप से regexp में एक बग एसओ पर सामग्री को चिह्नित करने का तरीका निर्धारित करता है। –

7

रिस्पर्ट फ़ंक्शन लिस्प से विरासत में आर में बहुत महत्वपूर्ण है। यह उपयोगी है अगर आप लूप बॉडी में कुछ फ़ंक्शन कॉल करना चाहते हैं और आप फ़ंक्शन कॉल को ध्वस्त होने पर प्रोग्राम को जारी रखना चाहते हैं। इस कोड का प्रयास करें:

for (i in 1:20) withRestarts(tryCatch(
if((a <- runif(1))>0.5) print(a) else stop(a), 
finally = print("loop body finished!")), 
abort = function(){}) 
6

समारोह trycatch() सीधे आगे काफी है, और उस पर अच्छा ट्यूटोरियल के बहुत सारे हैं। आर में से निपटने त्रुटि का एक उत्कृष्ट विवरण हैडली विकहैम की किताब Advanced-R में पाया जा सकता है, और क्या इस प्रकार एक बहुत withCallingHandlers() करने के लिए बुनियादी परिचय और withRestarts() के रूप में कुछ शब्दों में के रूप में संभव है:

चलें कहना एक निम्न स्तर प्रोग्रामर एक लिखता है पूर्ण मान की गणना करने के लिए फ़ंक्शन। वह यकीन है कि यह कैसे की गणना करने के लिए नहीं है, लेकिन how to construct an error जानता है और लगन से उसकी सरलता बता देते हैं:

low_level_ABS <- function(x){ 
    if(x<0){ 
     #construct an error 
     negative_value_error <- structure(
        # with class `negative_value` 
        class = c("negative_value","error", "condition"), 
        list(message = "Not Sure what to with a negative value", 
         call = sys.call(), 
         # and include the offending parameter in the error object 
         x=x)) 
     # raise the error 
     stop(negative_value_error) 
    } 
    cat("Returning from low_level_ABS()\n") 
    return(x) 
} 

एक मध्य स्तर प्रोग्रामर भी निरपेक्ष मूल्य की गणना करने के एक समारोह में लिखते हैं, बुरी तरह अधूरा low_level_ABS समारोह का इस्तेमाल कर रही ।वह जानता है कि कम स्तर कोड एक negative_value त्रुटि फेंकता है जब x का मान ऋणात्मक है और समस्या का एक समाधान एक restart जो mid_level_ABS के उपयोगकर्ताओं, जिसमें mid_level_ABS ठीक हो जाए (या तरह से नियंत्रित करने के लिए अनुमति देता है स्थापित करने का सुझाव देते हैं, द्वारा नहीं करता) negative_value त्रुटि से।

mid_level_ABS <- function(y){ 
    abs_y <- withRestarts(low_level_ABS(y), 
          # establish a restart called 'negative_value' 
          # which returns the negative of it's argument 
          negative_value_restart=function(z){-z}) 
    cat("Returning from mid_level_ABS()\n") 
    return(abs_y) 
} 

अंत में, एक उच्च स्तर प्रोग्रामर निरपेक्ष मूल्य की गणना करने के mid_level_ABS फ़ंक्शन का उपयोग करता है, और एक अवस्था संचालकों जो mid_level_ABS बताता पुनः आरंभ हैंडलर का उपयोग करके एक negative_value त्रुटि को ठीक करने के लिए स्थापित करता है।

high_level_ABS <- function(z){ 
    abs_z <- withCallingHandlers(
      # call this function 
      mid_level_ABS(z) , 
      # and if an `error` occurres 
      error = function(err){ 
       # and the `error` is a `negative_value` error 
       if(inherits(err,"negative_value")){ 
        # invoke the restart called 'negative_value_restart' 
        invokeRestart('negative_value_restart', 
            # and invoke it with this parameter 
            err$x) 
       }else{ 
        # otherwise re-raise the error 
        stop(err) 
       } 
      }) 
    cat("Returning from high_level_ABS()\n") 
    return(abs_z) 
} 

यह सब की बात यह है कि withRestarts() और withCallingHandlers(), समारोह high_level_ABS कैसे त्रुटियों से उबरने के लिए mid_level_ABS बता पा रहा था का उपयोग करके mid_level_ABS के निष्पादन, जो कुछ है रोके बिना low_level_ABS त्रुटि द्वारा उठाए गए आप tryCatch() साथ नहीं कर सकते:

> high_level_ABS(3) 
Returning from low_level_ABS() 
Returning from mid_level_ABS() 
Returning from high_level_ABS() 
[1] 3 
> high_level_ABS(-3) 
Returning from mid_level_ABS() 
Returning from high_level_ABS() 
[1] 3 

अभ्यास में, low_level_ABS एक समारोह है कि 01 का प्रतिनिधित्व करता है लॉट (शायद यहां तक ​​कि लाखों बार) भी कॉल करता है, जिसके लिए त्रुटि हैंडलिंग की सही विधि स्थिति से भिन्न हो सकती है, और विशिष्ट त्रुटियों को संभालने के तरीके की पसंद उच्च स्तर के कार्यों (high_level_ABS) पर छोड़ दी गई है।