आयात / निर्भरता का उपयोग करने के लिए बेहतर विवरण


148

" राइटिंग आर एक्सटेंशन्स " मैनुअल इम्पोर्ट या डिपेंड करने के लिए निम्नलिखित मार्गदर्शन प्रदान करता है:

सामान्य नियम हैं

  • वे पैकेज जिनके नामस्थान पर केवल लाइब्रेरी (pkgname) का उपयोग करके पैकेज लोड करने की आवश्यकता है, उन्हें 'आयात' क्षेत्र में सूचीबद्ध किया जाना चाहिए न कि 'डिपेंड्स' क्षेत्र में।
  • लाइब्रेरी (pkgname) का उपयोग करके सफलतापूर्वक लोड करने के लिए जिन पैकेजों को संलग्न करने की आवश्यकता है, उन्हें केवल 'डिपेंड्स' फ़ील्ड में सूचीबद्ध किया जाना चाहिए।

क्या कोई इस पर थोड़ी और स्पष्टता प्रदान कर सकता है? मुझे कैसे पता चलेगा कि जब मेरे पैकेज को केवल लोड किए गए नामस्थान की आवश्यकता होती है, जब मुझे संलग्न होने के लिए पैकेज की आवश्यकता होती है? दोनों के उदाहरण क्या हैं? मुझे लगता है कि विशिष्ट पैकेज केवल उन कार्यों का एक संग्रह है जो कभी-कभी अन्य पैकेजों में फ़ंक्शन को कॉल करते हैं (जहां कुछ काम पहले ही कोड-अप किया गया है)। क्या यह परिदृश्य 1 या 2 से ऊपर है?

संपादित करें

मैंने इस विशिष्ट विषय पर एक खंड के साथ एक ब्लॉग पोस्ट लिखा था ('इंपोर्ट्स वी डिपेंड्स की खोज')। विजुअल इसे समझने में बहुत आसान बनाते हैं।


1
आपके ब्लॉग पोस्ट ने मुझे पैकेज संरचना के बारे में सब कुछ बताया, जब मैंने मॉड्यूल की योजना बनाना शुरू किया । धन्यवाद!
कोनराड रुडोल्फ

जवाबों:


143

"Imports"की तुलना में सुरक्षित है "Depends"(और यह भी एक पैकेज का उपयोग करता है यह एक 'बेहतर नागरिक' के साथ अन्य पैकेजों के संबंध में है जो उपयोग करते हैं "Depends")।

"Depends"यह सुनिश्चित करने का एक निर्देश का प्रयास है कि दूसरे पैकेज से एक फ़ंक्शन दूसरे पैकेज को मुख्य खोज पथ (यानी पर्यावरण द्वारा लौटाई गई सूची search()) को संलग्न करके उपलब्ध है । हालांकि, यह रणनीति तब विफल हो सकती है जब बाद में लोड किया गया एक अन्य पैकेज, खोज पथ पर पहले से पहचाने गए फ़ंक्शन का नाम रखता है। चेम्बर्स ( SoDA ) फ़ंक्शन के उदाहरण का उपयोग करता है "gam", जो दोनों gamऔर mgcvपैकेज में पाया जाता है। यदि दो अन्य पैकेज लोड किए गए थे, उनमें से एक पर निर्भर करता है gamऔर एक के आधार पर mgcv, कॉल द्वारा पाया गया फ़ंक्शन gam()उस क्रम पर निर्भर करेगा जिसमें वे दो पैकेज संलग्न थे। अच्छा नही।

"Imports"किसी भी सहायक पैकेज के लिए एक निर्देश का उपयोग किया जाना चाहिए, जिनके कार्यों को नियमित खोज पथ पर करने के बजाय <imports:packageName>(तुरंत बाद खोजा गया <namespace:packageName>) में रखा जाना है। यदि ऊपर दिए गए उदाहरणों में से किसी एक ने "Imports"तंत्र का उपयोग किया (जिसमें फ़ाइल में भी निर्देश importया importFromनिर्देशों की आवश्यकता होती है NAMESPACE), तो मामलों में दो तरीकों से सुधार किया जाएगा। (1) पैकेज खुद को नियंत्रित करेगा कि कौन सा mgcvफ़ंक्शन उपयोग किया जाता है। (2) आयातित वस्तुओं के मुख्य खोज पथ को साफ रखने से, यह संभवतः दूसरे mgcvफ़ंक्शन पर अन्य पैकेज की निर्भरता को भी नहीं तोड़ पाएगा ।

यही कारण है कि नेमस्पेस का उपयोग करना एक अच्छा अभ्यास है, क्यों इसे अब सीआरएएन द्वारा लागू किया गया है, और (विशेष रूप से) क्यों उपयोग करने "Imports"से सुरक्षित है "Depends"


एक महत्वपूर्ण चेतावनी जोड़ने के लिए संपादित:

नहीं है एक ऊपर सलाह के लिए दुर्भाग्य से आम अपवाद: यदि आपके पैकेज एक पैकेज पर निर्भर करता है Aजो अपने आप में "Depends"एक और पैकेज पर B, अपने पैकेज की संभावना भी संलग्न करना होगा Aएक साथ "Dependsनिर्देश।

ऐसा इसलिए है क्योंकि पैकेज में कार्यों Aको इस उम्मीद के साथ लिखा गया था कि पैकेज Bऔर इसके कार्य search()पथ से जुड़े होंगे

एक "Depends"निर्देश पैकेज को लोड और अटैच करेगा A, जिस बिंदु पर एक पैकेज प्रतिक्रिया में पैकेज निर्देशन की Aअपनी "Depends"इच्छा है, पैकेज Bको लोड और संलग्न किया जा सकता है। पैकेज में फ़ंक्शंस Aतब पैकेज में उन कार्यों को खोजने में सक्षम होंगे Bजिन पर वे भरोसा करते हैं।

एक "Imports"निर्देश लोड होगा, लेकिन पैकेज को संलग्न नहींA करेगा और पैकेज को न तो लोड करेगा और ही संलग्न करेगा B। ( "Imports", सब के बाद, कि पैकेज लेखकों नाम स्थान प्रणाली का उपयोग कर रहे हैं, और है कि पैकेज की उम्मीद है Aका उपयोग करेंगे "Imports"किसी भी कार्यों के लिए बात करने के लिए में Bहै कि यह करने के लिए उपयोग की जरूरत है।) पैकेज में किसी भी कार्यों के लिए अपने कार्यों के द्वारा कॉल Aजो पैकेज में कार्यों पर भरोसा Bइच्छा फलस्वरूप विफल।

केवल दो समाधान या तो हैं:

  1. Aएक "Depends"निर्देश का उपयोग करके अपने पैकेज को संलग्न करें ।
  2. लंबे समय में बेहतर, पैकेज के अनुचर से संपर्क करें Aऔर उन्हें अपने नाम स्थान ( इस संबंधित उत्तर में मार्टिन मॉर्गन के शब्दों में) के निर्माण के लिए अधिक सावधानीपूर्वक काम करने के लिए कहें ।

1
इन मुद्दों के साथ हाल ही में एक समान प्रश्न और हाल ही में कुश्ती लड़ने के बाद, ये सूक्ष्म और अक्सर बीमार संचारित अवधारणाएं हैं। मैं आपको एक और स्पष्टीकरण के लिए यहाँ उल्लेख करूंगा: stackoverflow.com/questions/7880355/…
ब्रायन हैन्सन

@BryanHanson - उस लिंक पर नोट्स लिखने के लिए धन्यवाद। Importsऔर Dependsसंस्करण की आवश्यकताओं के बीच अंतर और .Rdफ़ाइलों में उदाहरण की जाँच वास्तव में सूक्ष्म और के बारे में जानने लायक है।
जोश ओ'ब्रायन

1
निर्भरता के बारे में चेतावनी जो 'डिपेंड्स' का उपयोग करती है, एक भयानक बात है। इसका मतलब है कि मैं मूल रूप से अपने पैकेज में 'आयात' का उपयोग नहीं कर सकता, जब तक कि बाकी सभी भी। = (
केन विलियम्स

एक बात मैं अभी भी स्पष्ट नहीं हूं, अगर मैं एक पैकेज लिख रहा हूं, और मैं चाहता हूं Imports: ggplot2, तो मेरा पैकेज क्यों नहीं मिल रहा autoplotहै? स्पष्ट रूप Dependsसे पैकेज लाइब्रेरी को संलग्न करता है ggplot2और इसलिए कोई समस्या नहीं है। उदाहरण के लिए मेरे पास एक फ़ंक्शन है autoplot.myFunction() जो @import ggplot2टैग का उपयोग करता है और मेरे पैकेज में है, Imports: ggplot2लेकिन मुझे एक त्रुटि मिलती है: Error in eval(expr, envir, enclos) : could not find function "autoplot"जब मैं इसका उपयोग करने का प्रयास करता हूं।
नथ्नेस्टवुडवुड

1
@ धन्यवाद। आप निश्चित रूप से सही हैं, और मैंने भ्रामक सामग्री को साफ़ करने के लिए उत्तर को संपादित किया है। जवाब देने के लिए इसे जटिल बनाने का एक हिस्सा यह है कि, जबकि ओपी ने अपने प्रश्न को Dependsऔर उसके Importsवर्गों के संदर्भ में फंसाया DESCRIPTION, वह वास्तव में इस बारे में पूछ रहा था कि एक फ़ंक्शन "आयात" करना (इसके बजाय "निर्भर करता है") का मतलब है। चूंकि वह बाद वाला प्रश्न है, जिसका मैंने उत्तर देने का प्रयास किया (और - मुझे संदेह है - इस उत्तर को खोजने वाले अधिकांश लोग जानना चाहते हैं), मैं उत्तर को छोड़ दूंगा अन्यथा अपरिवर्तित नहीं होगा।
जोश ओ'ब्रायन

31

हेडली विकम एक आसान व्याख्या देता है ( http://r-pkgs.had.co.nz/namespace.html ):

किसी पैकेज को या तो सूचीबद्ध करना Dependsया Importsयह सुनिश्चित करना कि यह जरूरत पड़ने पर स्थापित हो। मुख्य अंतर यह है कि जहां Importsसिर्फ पैकेज लोड होता है, उसे Dependsसंलग्न करता है। कोई अन्य अंतर नहीं हैं। [...]

जब तक इसका कोई खास कारण नहीं तो है, तो आप में हमेशा सूची संकुल चाहिए Importsनहीं Dependsऐसा इसलिए है क्योंकि एक अच्छा पैकेज आत्म-निहित है, और वैश्विक पर्यावरण में परिवर्तन को कम करता है (खोज पथ सहित)। एकमात्र अपवाद यह है कि यदि आपका पैकेज किसी अन्य पैकेज के साथ संयोजन में उपयोग करने के लिए डिज़ाइन किया गया है। उदाहरण के लिए, एनालॉग पैकेज शाकाहारी के ऊपर बनाता है। यह शाकाहारी के बिना उपयोगी नहीं है, इसलिए इसकी जगह शाकाहारी Dependsहै Imports। इसी तरह, ggplot2 को वास्तव में आयात करने के बजाय तराजू पर निर्भर होना चाहिए।


15

SfDA में चेम्बर्स 'आयात' का उपयोग करने के लिए कहते हैं जब यह पैकेज एक 'नाम स्थान' तंत्र का उपयोग करता है और चूंकि सभी पैकेजों को अब उनके पास होना आवश्यक है, तो उत्तर अब हमेशा 'आयात' का उपयोग कर सकता है। पिछले पैकेजों में वास्तव में नेमस्पेस होने के बिना लोड किया जा सकता था और उस स्थिति में आपको डिपेंडेंस का उपयोग करना होगा।


2
जब एक पैकेज "आयात" में निर्दिष्ट होता है और मैं पैकेज में फ़ंक्शन का उपयोग करना चाहता हूं, तो क्या मेरे अपने कार्यों को लाइब्रेरी (...) को कॉल करने की आवश्यकता है या क्या सभी फ़ंक्शन पहले से ही खोज पथ में उपलब्ध हैं? इसके अलावा, SfDA क्या है? लिंक?
SFun28

2
डेटा विश्लेषण के लिए सॉफ्टवेयर : springer.com/statistics/computanional+statistics/book/… ... आपके सवालों के जवाब के लिए, मुझे उत्तर का पता नहीं है, लेकिन आप बहुत आसानी से एक न्यूनतम टेस्ट पैकेज हैक कर सकते हैं और उत्तर पा सकते हैं। आनुभविक रूप से ...
बेन बोल्कर

1
SfDA == "डेटा विश्लेषण के लिए सॉफ्टवेयर"। पर [65] r-project.org/doc/bib/R-books.html । यदि एक पैकेज दूसरे पैकेज को निर्दिष्ट करता है, तो आपको एक संदेश देखना चाहिए जो आपको निर्भरता (लोडिंग) और आयात (प्याज) के लोडिंग के बारे में बताता है जब आप या तो लाइब्रेरी () का उपयोग करते हैं या कंसोल पर आवश्यकता होती है। हां, उन्हें तब उपलब्ध होना चाहिए।
IRTFM

4
+1 - यह मेरी मजबूत धारणा है। इसके अलावा, आयात के निर्दिष्ट पैकेज को <namespace:packageName>, के भाग के तुरंत बाद खोजा जाएगा <imports:packageName>library()जब तक Importएड पैकेज नहीं मिल सकता है तब तक पैकेज लोड-टाइम पर कंसोल पर आपको और कॉल की आवश्यकता नहीं होगी और आर आपको कंसोल पर सूचित नहीं करेगा ।
जोश ओ'ब्रायन

5

यहाँ एक सरल प्रश्न है जो आपको यह तय करने में मदद करेगा कि किसका उपयोग करें:

क्या आपके पैकेज को अंतिम उपयोगकर्ता को किसी अन्य पैकेज के कार्यों तक सीधे पहुंच की आवश्यकता है ?

  • NO -> आयात (सबसे आम उत्तर)
  • हाँ -> निर्भर करता है

केवल 'डिपेंड्स' का उपयोग तब करना चाहिए जब आपका पैकेज किसी दूसरे पैकेज का ऐड-ऑन या साथी हो, जहां आपका अंतिम उपयोगकर्ता आपके पैकेज के कोड और 'डिपेंड्स' पैकेज दोनों के कार्यों का उपयोग कर रहा हो। यदि आपका अंतिम उपयोगकर्ता केवल आपके कार्यों में हस्तक्षेप कर रहा है, और दूसरा पैकेज केवल पर्दे के पीछे काम कर रहा है, तो इसके बजाय 'आयात' का उपयोग करें।

इसके लिए चेतावनी यह है कि यदि आप 'इम्पोर्ट्स' में एक पैकेज जोड़ते हैं, जैसा कि आप आमतौर पर करते हैं, तो आपके कोड को उस पैकेज से कार्यों को संदर्भित करना होगा, पूर्ण नाम स्थान वाक्यविन्यास का उपयोग करते हुए, जैसे dplyr::mutate(), बस mutate()। यह कोड को पढ़ने के लिए थोड़ा अव्यवस्थित बनाता है, लेकिन बेहतर पैकेज स्वच्छता के लिए भुगतान करने के लिए यह एक छोटी सी कीमत है।

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