
हाय, हब्रोज़ितेली! कई उपयोगकर्ता विशिष्ट कार्यों के लिए आर का उपयोग करते हैं - यहां एक हिस्टोग्राम बनाने के लिए, एक प्रतिगमन विश्लेषण करने के लिए या सांख्यिकीय डेटा प्रसंस्करण से संबंधित अन्य अलग-अलग संचालन करने के लिए। लेकिन यह पुस्तक उन लोगों के लिए लिखी गई है जो आर में सॉफ्टवेयर विकसित करना चाहते हैं। इस पुस्तक के अभिप्राय पाठकों के प्रोग्रामिंग कौशल को एक पेशेवर योग्यता से लेकर "मैंने कॉलेज में प्रोग्रामिंग कोर्स कर लिया" तक हो सकता है, लेकिन कुंजी विशिष्ट उद्देश्यों के लिए आर कोड लिखने की है । (सांख्यिकी का गहन ज्ञान आमतौर पर आवश्यक नहीं है।)
पाठकों के कुछ उदाहरण जो इस पुस्तक से लाभान्वित हो सकते हैं:
- एक विश्लेषक (उदाहरण के लिए, एक अस्पताल या सरकारी एजेंसी में काम करने वाले) जो नियमित रूप से सांख्यिकीय रिपोर्ट जारी करते हैं और इस उद्देश्य के लिए कार्यक्रम विकसित करते हैं।
- एक सांख्यिकीय पद्धति के विकास में शामिल एक वैज्ञानिक - एकीकृत प्रक्रियाओं में मौजूदा तरीकों को नया या एकीकृत करना। कार्यप्रणाली को इनकोड करने की आवश्यकता है ताकि अनुसंधान समुदाय में इसका उपयोग किया जा सके।
- विपणन में विशेषज्ञ, कानूनी समर्थन, पत्रकारिता, प्रकाशन, आदि डेटा के जटिल ग्राफिक अभ्यावेदन के निर्माण के लिए कोड के विकास में लगे हुए हैं।
- सॉफ्टवेयर विकास के अनुभव के साथ पेशेवर प्रोग्रामर सांख्यिकीय विश्लेषण से संबंधित परियोजनाओं को सौंपा।
- सांख्यिकी और डाटा प्रोसेसिंग का अध्ययन करने वाले छात्र।
इस प्रकार, यह पुस्तक अद्भुत पैकेज आर के अनगिनत सांख्यिकीय तरीकों का संदर्भ नहीं है। वास्तव में, यह प्रोग्रामिंग के लिए समर्पित है और यह प्रोग्रामिंग मुद्दों से संबंधित है जो आर पर अन्य पुस्तकों में शायद ही कभी पाए जाते हैं। यहां तक कि बुनियादी विषयों को प्रोग्रामिंग के कोण से माना जाता है। इस दृष्टिकोण के कुछ उदाहरण:
- इस पुस्तक में "उन्नत उदाहरण" के अनुभाग हैं। आमतौर पर, वे विशिष्ट डेटा के आधार पर कोड के अलग-अलग टुकड़ों के बजाय पूर्ण सामान्य-उद्देश्य वाले कार्य प्रदान करते हैं। इसके अलावा, इन कार्यों में से कुछ आर के साथ आपके दैनिक कार्यों में काम आ सकते हैं। इन उदाहरणों का अध्ययन करके, आप न केवल सीखेंगे कि आर कैसे विशिष्ट कार्य करता है, बल्कि यह भी सीखें कि उन्हें उपयोगी कार्यक्रमों में कैसे संयोजित किया जाए। कई मामलों में, मैं वैकल्पिक समाधानों का वर्णन प्रदान करता हूं और इस सवाल का जवाब देता हूं: "ऐसा क्यों किया गया?"
- सामग्री को प्रोग्रामर की धारणा को ध्यान में रखते हुए प्रस्तुत किया जाता है। उदाहरण के लिए, डेटा फ़्रेम का वर्णन करते समय, मैं न केवल दावा करता हूं कि R में डेटा फ़्रेम एक सूची है, लेकिन मैं इस तथ्य के परिणामों को भी एक प्रोग्रामिंग दृष्टिकोण से इंगित करता हूं। पाठ में भी, R की तुलना अन्य भाषाओं से की जाती है जहाँ यह उपयोगी हो सकता है (इन भाषाओं को बोलने वाले पाठकों के लिए)।
- डिबगिंग किसी भी भाषा में प्रोग्रामिंग में एक महत्वपूर्ण भूमिका निभाता है, लेकिन आर पर अधिकांश पुस्तकों में इस विषय का उल्लेख नहीं है। इस पुस्तक में, मैंने डिबगिंग टूल्स के लिए एक पूरा अध्याय समर्पित किया, "उन्नत उदाहरण" के सिद्धांत का उपयोग किया, और पूरी तरह से विकसित डेमो प्रस्तुत किया कि कैसे कार्यक्रमों को वास्तविकता में डीबग किया जाता है।
- आजकल, सभी घरों में मल्टी-कोर कंप्यूटर दिखाई दिए हैं, और ग्राफिक प्रोसेसर (जीपीयू) की प्रोग्रामिंग वैज्ञानिक कंप्यूटिंग के क्षेत्र में एक अगोचर क्रांति पैदा कर रही है। अधिक से अधिक R अनुप्रयोगों के लिए बहुत बड़ी मात्रा में संगणना की आवश्यकता होती है, और R प्रोग्रामर्स के लिए समानांतर प्रसंस्करण प्रासंगिक हो गया है। पुस्तक में इस विषय के लिए एक पूरा अध्याय समर्पित है, यांत्रिकी का वर्णन करने के अलावा, उन्नत उदाहरण भी दिए गए हैं।
- एक अलग अध्याय आर कोड के काम को तेज करने के लिए आंतरिक कार्यान्वयन और आर के अन्य पहलुओं के बारे में जानकारी का उपयोग करने के बारे में बात करता है।
- अध्यायों में से एक सी और पायथन जैसे अन्य प्रोग्रामिंग भाषाओं के साथ आर के इंटरफेस पर केंद्रित है। एक बार फिर, डिबगिंग के लिए उन्नत उदाहरणों और सिफारिशों पर विशेष ध्यान दिया जाता है।
अंश। 7.8.4। वैश्विक चर का उपयोग कब किया जाना चाहिए?
प्रोग्रामर समुदाय में वैश्विक चर के उपयोग पर कोई सहमति नहीं है। जाहिर है, इस खंड के शीर्षक में प्रस्तुत प्रश्न का कोई सही उत्तर नहीं है, क्योंकि यह व्यक्तिगत प्राथमिकताओं और शैली का सवाल है। फिर भी, कई प्रोग्रामर मानते हैं कि वैश्विक चर, जो कई प्रोग्रामिंग शिक्षकों की वकालत करते हैं, पर पूर्ण प्रतिबंध अनावश्यक रूप से कठिन होगा। इस खंड में, हम R. संरचनाओं के संदर्भ में वैश्विक चर के संभावित लाभों की जांच करते हैं। "वैश्विक चर" शब्द का अर्थ किसी भी चर से होगा जो पर्यावरण हितैषी के हित के स्तर से ऊपर है।
R में वैश्विक चर का उपयोग करना आपकी अपेक्षा से अधिक सामान्य है। आश्चर्यजनक रूप से, R अपने आंतरिक कार्यान्वयन (C कोड और R फ़ंक्शन दोनों में) में व्यापक रूप से वैश्विक चर का उपयोग करता है। तो, सुपर-असाइनमेंट ऑपरेटर << - का उपयोग R के कई लाइब्रेरी फ़ंक्शंस में किया जाता है (हालाँकि आमतौर पर इसका उपयोग वैरिएबल को लिखने के लिए किया जाता है जो वेरिएबल्स के पदानुक्रम में केवल एक स्तर पर स्थित होता है)। मल्टी-थ्रेडेड कोड और GPU कोड का उपयोग फास्ट प्रोग्राम लिखने के लिए किया जाता है (अध्याय 16 देखें) आमतौर पर वैश्विक चर का उपयोग करते हैं जो समानांतर निष्पादकों के बीच बातचीत का मुख्य तंत्र प्रदान करते हैं।
अब, संक्षिप्तता के लिए, आइए खंड 7.7 से एक पुराने उदाहरण पर लौटते हैं:
f <- function(lxxyy) { # lxxyy — , x y ... lxxyy$x <- ... lxxyy$y <- ... return(lxxyy) } # x y lxy$x <- ... lxy$y <- ... lxy <- f(lxy) # x y ... <- lxy$x ... <- lxy$y
जैसा कि पहले उल्लेख किया गया है, यह कोड बोझिल हो सकता है, खासकर अगर x और y स्वयं सूचियां हैं।
दूसरी ओर, वैश्विक चर का उपयोग करते हुए एक वैकल्पिक योजना पर एक नज़र डालें:
f <- function() { ... x <<- ... y <<- ... } # x y x <-... y <-... f() # x y # x y ... <- x ... <- y
शायद दूसरा संस्करण बहुत क्लीनर है, कम भारी है और सूची में हेरफेर की आवश्यकता नहीं है। स्पष्ट कोड आमतौर पर लेखन, डिबगिंग और रखरखाव में कम समस्याएं पैदा करता है।
इन कारणों के लिए - कोड की थोकता को सरल और कम करने के लिए - हमने पहले DES कोड में सूची वापस करने के बजाय वैश्विक चर का उपयोग करने का निर्णय लिया। इस उदाहरण पर अधिक विस्तार से विचार करें।
दो वैश्विक चर का उपयोग किया गया था (दोनों अलग-अलग जानकारी वाली सूची हैं): सिम चर पुस्तकालय कोड के साथ जुड़ा हुआ है, और mm1glbls चर विशिष्ट एप्लिकेशन कोड M / M / 1 के साथ जुड़ा हुआ है। सिम से शुरू करते हैं।
यहां तक कि प्रोग्रामर जो वैश्विक चर के बारे में संयमित हैं, सहमत हैं कि इस तरह के चर का उपयोग उचित हो सकता है यदि वे वास्तव में वैश्विक हैं - इस अर्थ में कि वे व्यापक रूप से कार्यक्रम में उपयोग किए जाते हैं। यह सब डीईएस उदाहरण से सिम चर से संबंधित है: इसका उपयोग लाइब्रेरी कोड (शेड्यूलवेंट (), गेटनेक्सवेंट () और डॉसिम ()) और एम / एम / 1 कोड (मिमीप्रैक्टेक्टवेंट ()) दोनों में किया जाता है। इस विशेष उदाहरण में, सिम के बाद की कॉलें पढ़ने तक सीमित हैं, लेकिन कुछ स्थितियों में रिकॉर्डिंग संभव है। इस तरह का एक विशिष्ट उदाहरण घटना रद्द करने का एक संभावित कार्यान्वयन है। उदाहरण के लिए, ऐसी स्थिति तब हो सकती है जब "दो के पहले" सिद्धांत को मॉडलिंग करते हैं: दो घटनाओं की योजना बनाई जाती है, और जब उनमें से एक होती है, तो दूसरे को रद्द कर दिया जाना चाहिए।
इस प्रकार, एक वैश्विक चर के रूप में सिम का उपयोग करना उचित लगता है। हालाँकि, अगर हमने वैश्विक चर का उपयोग करने से पूरी तरह इनकार कर दिया, तो सिम को डॉसिम () के अंदर एक स्थानीय चर में रखा जा सकता है। यह फ़ंक्शन पिछले पैराग्राफ (शेड्यूलेंट (), getnextevnt (), आदि) में उल्लिखित सभी फ़ंक्शन के तर्क में पास करेगा, और इनमें से प्रत्येक फ़ंक्शन एक संशोधित सिम वेरिएबल लौटाएगा।
उदाहरण के लिए, रेखा 94:
reactevnt(head)
निम्न रूप में परिवर्तित:
sim <- reactevnt(head)
उसके बाद, निम्नलिखित लाइन को mm1reactevnt () एक विशिष्ट एप्लिकेशन से जुड़े फ़ंक्शन में जोड़ा जाना चाहिए:
return(sim)
कुछ इसी तरह mm1glbls के साथ dosim () नाम के साथ एक स्थानीय चर शामिल किया जा सकता है (उदाहरण के लिए) appvars। लेकिन अगर यह दो चर के साथ किया जाता है, तो उन्हें सूची में रखा जाना चाहिए ताकि दोनों चर समारोह से वापस आ सकें, जैसा कि f () फ़ंक्शन के उपरोक्त उदाहरण में है। और फिर सूचियों के अंदर सूचियों की भारी संरचना उत्पन्न होती है, जिसका उल्लेख ऊपर किया गया था, या बल्कि, सूचियों के अंदर सूचियों के अंदर सूचीबद्ध करता है।
दूसरी ओर, वैश्विक चर का उपयोग करने के विरोधियों ने नोटिस किया कि कोड सादगी व्यर्थ नहीं है। वे चिंतित हैं कि डिबगिंग प्रक्रिया के दौरान उन स्थानों को खोजने में कठिनाइयां होती हैं जहां वैश्विक चर मूल्य बदलता है, क्योंकि कार्यक्रम में कहीं भी परिवर्तन हो सकता है। ऐसा लगता है कि आधुनिक पाठ संपादकों और एकीकृत विकास उपकरण की दुनिया में जो एक चर के सभी घटनाओं को खोजने में मदद करेंगे, समस्या इस तरह से होती है (वैश्विक चर के उपयोग को छोड़ने का आग्रह करने वाला मूल लेख 1970 में प्रकाशित हुआ था!)। फिर भी, इस कारक को ध्यान में रखा जाना चाहिए।
एक और समस्या जिसका आलोचकों ने उल्लेख किया है, वह एक प्रोग्राम के कई असंबंधित हिस्सों से विभिन्न मूल्यों के साथ एक फ़ंक्शन को कॉल करते समय होती है। उदाहरण के लिए, कल्पना करें कि फ़ंक्शन f () प्रोग्राम के विभिन्न हिस्सों से कहा जाता है, प्रत्येक कॉल के लिए प्रत्येक के लिए एक मान के बजाय अपने स्वयं के x और y मान प्राप्त करते हैं। समस्या को x और y मानों के वैक्टर बनाकर हल किया जा सकता है जिसमें आपके प्रोग्राम में f () के प्रत्येक उदाहरण का एक अलग तत्व होता है। हालांकि, यह वैश्विक चर का उपयोग करने की सरलता खो देगा।
इन समस्याओं का सामना न केवल आर, बल्कि एक अधिक सामान्य संदर्भ में भी किया जाता है। हालांकि, आर में ऊपरी स्तर पर वैश्विक चर का उपयोग एक अतिरिक्त समस्या पैदा करता है, क्योंकि इस स्तर पर उपयोगकर्ता के पास आमतौर पर कई चर होते हैं। एक खतरा है कि वैश्विक चर का उपयोग करने वाला कोड गलती से एक ही नाम के साथ पूरी तरह से बाहरी चर को बदल सकता है।
बेशक, समस्या आसानी से हल हो गई है - यह वैश्विक चर के लिए लंबे नामों को चुनने के लिए पर्याप्त है जो एक विशिष्ट एप्लिकेशन से बंधे हैं। हालांकि, डेस उदाहरण के लिए निम्न स्थिति में भी वातावरण एक उचित समझौता प्रदान करता है।
डॉसिम () फ़ंक्शन के अंदर, लाइन
sim <<- list()
एक स्ट्रिंग के साथ प्रतिस्थापित किया जा सकता है
assign("simenv",new.env(),envir=.GlobalEnv)
यह शीर्ष स्तर पर सिमेन चर द्वारा संदर्भित एक नया वातावरण बनाता है। यह वातावरण वैश्विक वैरिएबल को एन्हांस करने के लिए एक कंटेनर के रूप में कार्य करता है जिसे कॉल करने के लिए () और असाइन () किया जा सकता है। उदाहरण के लिए, तार
if (is.null(sim$evnts)) { sim$evnts <<- newevnt
अनुसूची में () फार्म ले लो
if (is.null(get("evnts",envir=simenv))) { assign("evnts",newevnt,envir=simenv)
हां, यह समाधान भी बोझिल है, लेकिन कम से कम यह उतना जटिल नहीं है जितना कि सूचियों के अंदर की सूचियों के अंदर। और यह शीर्ष स्तर पर एक बाहरी चर के लिए आकस्मिक लेखन से बचाता है। सुपर-असाइनमेंट ऑपरेटर का उपयोग करना अभी भी कम बोझिल कोड देता है, लेकिन इस ट्रेड-ऑफ को ध्यान में रखा जाना चाहिए।
हमेशा की तरह, कोई एकल प्रोग्रामिंग शैली नहीं है जो सभी स्थितियों में सर्वोत्तम परिणाम प्रदान करती है। वैश्विक चर के साथ एक समाधान एक और विकल्प है जिसे आपके प्रोग्रामिंग टूल के शस्त्रागार में शामिल किया जाना चाहिए।
7.8.5। शॉर्ट सर्किट
आपको याद दिलाता हूं कि कॉल के समय पर्यावरण के साथ आर के तर्कों और फ़ंक्शन बॉडी से मिलकर बनता है। तथ्य यह है कि पर्यावरण शामिल है प्रोग्रामिंग प्रतिमान में शामिल है, जो अवधारणा का उपयोग करता है, जिसे क्लोजर भी कहा जाता है (यहां शब्दावली का कुछ अधिभार है)।
एक क्लोजर एक फ़ंक्शन है जो एक स्थानीय चर बनाता है, और फिर एक अन्य फ़ंक्शन बनाता है जो इस चर को एक्सेस करता है। वर्णन बहुत सारगर्भित है, इसलिए मैं बेहतर उदाहरण देता हूं।
1 > counter 2 function () { 3 ctr <- 0 4 f <- function() { 5 ctr <<- ctr + 1 6 cat("this count currently has value",ctr,"\n") 7 } 8 return(f) 9 }
आइए देखें कि कार्यान्वयन विवरण में गोता लगाने से पहले यह कोड कैसे काम करता है:
> c1 <- counter() > c2 <- counter() > c1 function() { ctr <<- ctr + 1 cat("this count currently has value",ctr,"\n") } <environment: 0x8d445c0> > c2 function() { ctr <<- ctr + 1 cat("this count currently has value",ctr,"\n") } <environment: 0x8d447d4> > c1() this count currently has value 1 > c1() this count currently has value 2 > c2() this count currently has value 1 > c2() this count currently has value 2 > c2() this count currently has value 3 > c1() this count currently has value 3
यहां, काउंटर () फ़ंक्शन को दो बार कहा जाता है, और परिणाम सी 1 और सी 2 असाइन किए जाते हैं। जैसा कि अपेक्षित था, इन दो चर कार्यों से मिलकर बनता है, अर्थात् एफ की प्रतियां ()। हालाँकि, f () सुपर-असाइनमेंट ऑपरेटर के माध्यम से ctr वैरिएबल तक पहुँचता है, और यह वैरिएबल एक वेरिएबल है जिसका नाम निर्दिष्ट करने के लिए स्थानीय () है, क्योंकि यह पर्यावरण पदानुक्रम में पथ पर पहला होगा। यह पर्यावरण f () का हिस्सा है, और जैसे कि काउंटर के कॉल पक्ष () में क्या लौटाया जाता है। मुख्य बिंदु यह है कि काउंटर () के लिए अलग-अलग कॉल के साथ, ctr वैरिएबल अलग-अलग परिवेशों में होगा (उदाहरण के वातावरण में, इसे 0x8d445c0 और 0x8d447d4 पते पर मेमोरी में संग्रहीत किया गया था)। दूसरे शब्दों में, काउंटर () के लिए अलग-अलग कॉल ctr के भौतिक रूप से अलग-अलग उदाहरणों का निर्माण करेंगे।
नतीजतन, फ़ंक्शन सी 1 () और सी 2 () पूरी तरह से स्वतंत्र काउंटर के रूप में काम करते हैं। इसे उस उदाहरण से देखा जा सकता है जहां प्रत्येक फ़ंक्शन को कई बार कहा जाता है।
»पुस्तक की अधिक जानकारी
प्रकाशक की वेबसाइट पर पाई जा सकती है
»
सामग्री»
अंशफेरीवालों के लिए कूपन पर 25% -
आरपुस्तक के पेपर संस्करण के भुगतान पर, पुस्तक का एक इलेक्ट्रॉनिक संस्करण ई-मेल द्वारा भेजा जाता है।