आर में वैश्विक और स्थानीय चर


126

मैं आर के लिए एक नौसिखिया हूं, और मैं आर में स्थानीय और वैश्विक चर के उपयोग से काफी भ्रमित हूं।

मैं इंटरनेट पर कुछ पोस्ट पढ़ता हूं जो कहती हैं कि अगर मैं वर्तमान परिवेश में चर का उपयोग करूंगा =या <-करूंगा, और जब <<-मैं किसी फ़ंक्शन के अंदर एक वैश्विक चर का उपयोग कर सकता हूं।

हालाँकि, जैसा कि मुझे याद है C ++ में स्थानीय चर उठते हैं जब भी आप कोष्ठक के अंदर एक चर घोषित करते हैं {}, तो मैं सोच रहा था कि क्या यह आर के समान है? या यह सिर्फ आर में कार्यों के लिए है कि हमारे पास स्थानीय चर की अवधारणा है।

मैंने थोड़ा प्रयोग किया, जो यह बताता है कि केवल कोष्ठक पर्याप्त नहीं हैं, क्या मुझे कुछ गलत हो रहा है?

{
   x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4

इन उत्तरों के अलावा चलाने के लिए कुछ कोड:, globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env...
isomorphismes

@isomorphismes, Error: could not find function "%>%"। क्या यह असाइनमेंट का दूसरा रूप है?
हारून मैकडैड

1
R- मदद पर प्रासंगिक धागा: "<< -" ऑपरेटर का क्या अर्थ है?
हेनरिक

1
@AaronMcDaid हाय, जल्द जवाब न देने के लिए खेद है! वह से है require(magrittr)। यह बाईं ओर ( x | f1 | f2 | f3) के बजाय दाईं ओर ( ) कार्यों को लागू करने का एक तरीका है f3( f2( f1( x ) ) )
isomorphismes

जवाबों:


153

किसी फ़ंक्शन के अंदर घोषित चर उस फ़ंक्शन के लिए स्थानीय होते हैं। उदाहरण के लिए:

foo <- function() {
    bar <- 1
}
foo()
bar

निम्नलिखित त्रुटि देता है Error: object 'bar' not found:।

यदि आप barएक वैश्विक चर बनाना चाहते हैं , तो आपको यह करना चाहिए:

foo <- function() {
    bar <<- 1
}
foo()
bar

इस मामले barमें फ़ंक्शन के बाहर से पहुँचा जा सकता है।

हालांकि, सी, सी ++ या कई अन्य भाषाओं के विपरीत, ब्रैकेट चर के दायरे का निर्धारण नहीं करते हैं। उदाहरण के लिए, निम्नलिखित कोड स्निपेट में:

if (x > 10) {
    y <- 0
}
else {
    y <- 1
}

yif-elseकथन के बाद सुलभ रहता है ।

जैसा कि आप अच्छी तरह से कहते हैं, आप नेस्टेड वातावरण भी बना सकते हैं। आप इन दोनों लिंक पर एक नज़र डाल सकते हैं कि उन्हें कैसे उपयोग करना है:

  1. http://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html
  2. http://stat.ethz.ch/R-manual/R-devel/library/base/html/get.html

यहाँ आपके पास एक छोटा सा उदाहरण है:

test.env <- new.env()

assign('var', 100, envir=test.env)
# or simply
test.env$var <- 100

get('var') # var cannot be found since it is not defined in this environment
get('var', envir=test.env) # now it can be found

136

<- वर्तमान वातावरण में असाइनमेंट करता है।

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

ज्यादातर मामलों <<-में वैश्विक वातावरण में पहले से ही चर के लिए असाइन किया जाएगा या किसी फ़ंक्शन के अंदर होने पर भी वैश्विक वातावरण में एक चर बना सकते हैं। हालाँकि, यह उतना सीधा नहीं है जितना कि। यह क्या करता है ब्याज के नाम के साथ एक चर के लिए मूल वातावरण की जाँच करता है। यदि यह इसे आपके मूल वातावरण में नहीं मिलता है, तो यह मूल पर्यावरण के जनक के पास जाता है (उस समय समारोह बनाया गया था) और वहां दिखता है। यह वैश्विक पर्यावरण के लिए ऊपर की ओर जारी है और यदि यह वैश्विक वातावरण में नहीं पाया जाता है तो यह वैश्विक वातावरण में चर को असाइन करेगा।

यह बता सकता है कि क्या चल रहा है।

bar <- "global"
foo <- function(){
    bar <- "in foo"
    baz <- function(){
        bar <- "in baz - before <<-"
        bar <<- "in baz - after <<-"
        print(bar)
    }
    print(bar)
    baz()
    print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"

पहली बार जब हम बार प्रिंट करते हैं तो हमने उसे fooअभी तक नहीं बुलाया है इसलिए यह अभी भी वैश्विक होना चाहिए - यह समझ में आता है। दूसरी बार जब हम इसे प्रिंट करते हैं, तो fooइससे पहले कि यह baz"फू में" मूल्य कहे जाने से अंदर है। निम्नलिखित वह जगह है जहां हम देखते हैं कि <<-वास्तव में क्या कर रहा है। प्रिंट किया गया अगला मान "baz में - << से पहले" - भले ही प्रिंट स्टेटमेंट के बाद आता है <<-। इसका कारण यह है कि <<-वर्तमान परिवेश में नहीं दिखता है (जब तक कि आप वैश्विक वातावरण में नहीं हैं जिसमें मामला <<-काम करता है <-)। तो bazबार के मूल्य के अंदर "बाज में - << से पहले" के रूप में रहता है। एक बार जब हम बार bazकी कॉपी fooको "बाज़" में बदल देते हैं, लेकिन जैसा कि हम देख सकते हैं कि वैश्विक barअपरिवर्तित है।barfooजब हम bazइसे बनाते हैं, तो यह माता-पिता के वातावरण में अंदर से परिभाषित होता है, इसलिए यह barउस <<-देखने की पहली प्रति है और इस प्रकार वह प्रतिलिपि जो इसे असाइन करता है। तो <<-सिर्फ वैश्विक वातावरण के लिए सीधे काम नहीं है।

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

अब मैं <<-एक असाइनमेंट स्टेटमेंट में बदलाव करता हूं और हम देख सकते हैं कि क्या प्रभाव पड़ता है:

bar <- "global"
foo <- function(){
    bar <- "in foo"   
    baz <- function(){
        assign("bar", "in baz", envir = .GlobalEnv)
    }
    print(bar)
    baz()
    print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"

इसलिए दोनों बार जब हम बार को प्रिंट करते हैं, तो fooकॉल करने के बाद भी "फू में" होता है baz। ऐसा इसलिए है क्योंकि assignकभी भी barफू के अंदर की नकल पर विचार नहीं किया जाता है क्योंकि हमने यह बताया था कि वास्तव में कहां देखना है। हालांकि, इस बार वैश्विक वातावरण में बार का मूल्य बदल गया था क्योंकि हमने स्पष्ट रूप से वहां सौंपा था।

अब आपने स्थानीय वेरिएबल्स बनाने के बारे में भी पूछा और आप बिना किसी फंक्शन के भी आसानी से कर सकते हैं ... हमें केवल localफंक्शन का उपयोग करने की आवश्यकता है ।

bar <- "global"
# local will create a new environment for us to play in
local({
    bar <- "local"
    print(bar)
})
#[1] "local"
bar
#[1] "global"

2

उसी तर्ज पर थोड़ा और

attrs <- {}

attrs.a <- 1

f <- function(d) {
    attrs.a <- d
}

f(20)
print(attrs.a)

"1" प्रिंट करेगा

attrs <- {}

attrs.a <- 1

f <- function(d) {
   attrs.a <<- d
}

f(20)
print(attrs.a)

"20" प्रिंट करेगा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.