2012-12-05 22 views
20

अगर जब मैं आर कार्यों मैं अक्सर निम्नलिखित संरचना को खोजने पर नज़र डालें:/किसी और के अंदर निर्माण करती है और बाहर कार्यों

f <- function(exp=T) { 
    if (exp) 
    a <- 1 
    else 
    a <- 2 
} 
f() 
f(F) 

यह त्रुटि के बिना चलेंगे। लेकिन आंतरिक फ़ंक्शन कोड निष्पादित करने से त्रुटि उत्पन्न होती है क्योंकि आर शायद मान लेता है कि कथन पहले असाइनमेंट a <- 1 के बाद समाप्त हो गया है और निम्न को संभाल नहीं सकता है।

exp=T 
if (exp) 
    a <- 1 
else 
    a <- 2 

अब, यह मेरे लिए समझ में आता है, लेकिन मैं अभी भी समझने के लिए क्यों मार डाला कोड का व्यवहार में अंतर होता है जब अंदर या एक समारोह के बाहर मार डाला चाहते हैं।

पहली शाखा के बाद खोल एक पूरा बयान देखा है तो यह मानता है कि आप किया टाइप कर रहे हैं:

उत्तर

27

यह स्क्रिप्ट को चलाने के लिए एक इंटरैक्टिव खोल (REPL) के उपयोग के परिणामस्वरूप है। तो यहाँ तक कि जब आप किसी फ़ाइल के लिए if बयान बचाने के लिए और यह source (या पाइप आर में) आप else शाखा पर त्रुटि प्राप्त होगी - दुर्भाग्य से, आर लिपियों की व्याख्या भले ही वे सहभागी में टाइप नहीं कर रहे हैं के लिए एक ही खोल उपयोग करता है।

लेकिन निम्नलिखित ठीक काम करेगा:

if (exp) a <- 1 else a <- 2 

यहाँ, दुभाषिया लाइन निगल और इसे निष्पादित करता है।

अपने समारोह में एक ग्रहण करेंगे कि एक ही लागू होता है - और यह करता है! हालांकि, फ़ंक्शन स्वयं आपके मामले में खुले ब्रेस के साथ शुरू होता है, इसलिए आर को तब तक पढ़ना पड़ता है जब तक कि यह मिलान बंद होने वाला ब्रेस न हो। इसके विपरीत, इस समारोह की घोषणा करें:

f <- function (exp) 
    if (exp) 
     a <- 1 
    else 
     a <- 2 

आर में आप शरीर के चारों ओर ब्रेसिज़ के बिना कार्यों को परिभाषित कर सकते हैं। लेकिन उपरोक्त कोड उसी कारण से असफल हो जाएगा कि ब्रेसिज़ के बिना स्टैंडअलोन if विफल रहता है। इसके विपरीत, अगर मैंने एक ही पंक्ति पर if लिखा था तो यह कोड एक बार फिर काम करेगा।

संयोग से, अपने कार्य एक चर है कि इस्तेमाल नहीं करने के लिए एक काम का उपयोग करता है। एक ही जब खोल अंदर if का उपयोग कर

f <- function (exp) { 
    if (exp) 
     1 
    else 
     2 
} 

... और:: आप के बजाय निम्न कर सकते हैं (चाहिए)

a <- if (exp) 1 else 2 

क्योंकि आर में, if एक अभिव्यक्ति जो एक मान देता है।

+2

मुझे यकीन है कि आप के बारे में बताया क्यों नहीं कर रहा हूँ multiline 'if ... else ... 'को एक कथन के रूप में व्याख्या किया जाता है जब यह फ़ंक्शन के शरीर के अंदर होता है। ऐसा इसलिए होता है क्योंकि जब आप 'f <- function (exp = T) टाइप करते हैं {', आर पढ़ना जारी रखने जा रहा है जब तक कि संपूर्ण ब्लॉक मिलान के साथ बंद न हो'' '। इससे दुभाषिया को यह पता चल जाएगा कि 'अन्य' उपरोक्त शुरू होने वाली 'if'' की निरंतरता है। सही? – flodel

+0

@flodel आह हाँ, मुझे यह स्पष्ट करने की आवश्यकता हो सकती है। लेकिन आपका अनुमान स्पॉट-ऑन है। और अनुमान लगाएं कि जब आप फ़ंक्शन बॉडी के चारों ओर ब्रेसिज़ को हटाते हैं तो क्या होता है ... ;-) –

26

कार्यकारी सारांश:

वहाँ आर के लिए केवल दो तरीके पता चला है कि एक और को खंड यह ऊपर है, तो खंड के अंतर्गत आता है कर रहे हैं:

  1. पूरे करता है, तो ... किसी और बयान (और शायद अन्य बयान भी) ब्रेसिज़ में संलग्न है;
  2. शब्द अन्य खंड के अंत के समान रेखा पर दिखाई देता है।

साक्ष्य:

उपरोक्त चर्चा मुझे मदद मिली है, लेकिन मुझे आशा है कि मैं एक उपयोगी वक्रोक्ति पेशकश कर सकते हैं। हाँ, यह सही है कि

f <- function (exp) 
    if (exp) 
     1 
    else 
     2 

अतीत 1. दो तरीके पढ़ने रखने के लिए आर की विफलता की वजह से क्लासिक Error: unexpected 'else' in "else" संदेश के साथ विफल रहता है सही ढंग से अनुसंधान पिछले 1 पढ़ना जारी रखते हैं बनाने के लिए की पेशकश की गई है:

f <- function (exp) { 
    if (exp) 
     1 
    else 
     2 
} 

और

f <- function (exp) if (exp) 1 else 2 

लेकिन वहाँ एक तीसरा रास्ता अभी तक का उल्लेख नहीं किया --- सिर्फ एक लाइन अप else के लिए कदम है। इस प्रकार, निम्नलिखित भी काम करता है क्योंकि आर पिछले 1 पढ़ने रखने के लिए जानता है:

f <- function (exp) 
    if (exp) 
     1 else 
     2 

मुझे लगता है कि प्रमुख मुद्दा या तो समारोह के पूरे शरीर को संभालो, या सुनिश्चित करें else के रूप में एक ही लाइन पर होता है बनाने के लिए है अगर खंड जारी है तो आर पढ़ने के लिए जानता है। यही कारण है कि एक लाइन समाधान काम करता है।

f <- function (exp) 
    if (exp) { 
     1 
    } else 
     2 

लेकिन यह विफल रहता है: यह भी कारण है कि इस काम करता है

f <- function (exp) 
    if (exp) { 
     1 
    } 
    else 
     2 

और समारोह शरीर के अधिक मानक ब्रेसिंग का उपयोग कर, यह भी काम करता है:

f <- function (exp) { 
    if (exp) { 
     1 
    } 
    else 
     2 
} 

लेकिन चाहे या हम एक समारोह का निर्माण नहीं कर रहे हैं एक लाल हेरिंग है। क्या मायने रखता है केवल else का ब्रेसिज़ और स्थान है। इस प्रकार, इन काम:

{ 
    if (exp) { 
     1 
    } 
    else 
     2 
} 


if (exp) { 
    1 
} else 
    2 

लेकिन यह विफल रहता है:

if (exp) { 
    1 
} 
else 
    2 

और शीर्ष पर मेरी अभिकथन 1 प्रदर्शित करने के लिए, इस काम करता है:

{ 
x <- 4 
if (exp) 
    1 
else 
    2 
} 
+1

यह एक बहुत साफ स्पष्टीकरण है। धन्यवाद। –

संबंधित मुद्दे