पैकेज लिखने के लिए R में संदेश () प्रिंट से बेहतर विकल्प क्यों है?


82

मुझे यह जानने की उम्मीद है कि जब यह नैदानिक ​​संदेशों को छापने की message()तुलना में बेहतर विकल्प है print()तो यह क्यों है ।

उदाहरण के लिए, print()फ़ंक्शन आर ऑब्जेक्ट को प्रिंट करने के लिए एक बेहतर विकल्प है 'iris', जबकि, message()बेहतर है जब हम स्ट्रिंग को समतल करना चाहते हैं जैसे message("a", "b")कि इससे छोटा है print(paste0("a", "b"))

हालांकि, मुझे लगता है कि ऊपर सूचीबद्ध उन साधारण लोगों की तुलना में अधिक अंतर हैं। मैंने दोनों विधियों के लिए प्रलेखन पढ़ा है

लेकिन, ऐसा लगता है कि वे उतनी जानकारीपूर्ण नहीं हैं जितनी मैंने अपने प्रश्न की आशा की थी।

मैं सराहना करूंगा अगर कोई हमें बताए कि कौन सा मामला message()बेहतर है print(), और क्यों।


1
@MartinMorgan, मैं ज्यादातर इससे सहमत हूं, लेकिन message()एक "संदेश" को भी इंगित करता है, जो कि suppressMessages()कब्जा है। suppressMessages()शुद्ध stderr उत्पादन को दबा नहीं है, उदाहरण के लिए suppressMessages(cat("hello\n", file=stderr()))अभी भी helloकंसोल में प्रदर्शित करता है।
हेनरिकबी

@HenrikB stop, warning, messageसभी संकेत की स्थिति है, जो है क्या उन्हें पकड़ / दबाने करने योग्य tryCatch(message("hello"), message=force); cat(file=stderr())यदि कोई उदाहरण नैदानिक ​​स्थिति को इंगित करने के लिए है तो खराब शैली (और अप्रभावी, जैसा कि आपका उदाहरण दिखाता है!) है।
मार्टिन मॉर्गन

जवाबों:


146

टी एल; डॉ

S3 ऑब्जेक्ट के लिए फ़ंक्शंस cat()बनाते समय आपको उपयोग करना चाहिए print.*()। बाकी सभी चीजों के लिए, आपको message()तब तक उपयोग करना चाहिए जब तक कि कार्यक्रम की स्थिति समस्याग्रस्त न हो। उदाहरण के लिए, खराब त्रुटि जो पुनर्प्राप्त करने योग्य है, warning()बनाम त्रुटि रोक उपयोग दिखाता है stop()

लक्ष्य

इस पोस्ट का उद्देश्य विभिन्न आउटपुट विकल्पों पर प्रतिक्रिया प्रदान करना है जो एक पैकेज डेवलपर की पहुंच है और किसी को एक नए ऑब्जेक्ट पर या स्ट्रिंग्स के आधार पर संभावित रूप से आउटपुट आउटपुट कैसे करना चाहिए।

आर आउटपुट अवलोकन

पारंपरिक उत्पादन कार्य हैं:

  1. print()
  2. cat()
  3. message()
  4. warning()
  5. stop()

अब, पहले दो फ़ंक्शन ( print()और cat()) अपने आउटपुट को stdoutया मानक आउटपुट पर भेजते हैं । अंतिम तीन फ़ंक्शन ( message(), warning()और, stop()) अपने आउटपुट को stderrया मानक त्रुटि पर भेजते हैं । यही है, जैसे कमांड से परिणाम आउटपुटlm() को एक फ़ाइल में भेजा जाता है और त्रुटि आउटपुट - यदि यह मौजूद है - पूरी तरह से अलग फ़ाइल में भेजा जाता है। यह विशेष रूप से उपयोगकर्ता के अनुभव के लिए महत्वपूर्ण है क्योंकि निदान तब लॉग फ़ाइलों में परिणामों के आउटपुट को अव्यवस्थित नहीं कर रहे हैं और त्रुटियों को जल्दी से खोजने के लिए उपलब्ध हैं।

उपयोगकर्ता और बाहरी पैकेज के लिए डिजाइनिंग

अब, उपरोक्त को I / O मानसिकता में अधिक फंसाया गया है और आवश्यक रूप से उपयोगकर्ता-सामना करने वाले फ़्रेमसेट के लिए नहीं। तो, आइए, इसके लिए एक रोज़ आर यूज़र के संदर्भ में कुछ प्रेरणा प्रदान करें। विशेष रूप से, 3-5 या stderrफ़ंक्शंस का उपयोग करके , उनका आउटपुट कंसोल टेक्स्ट के माध्यम से sink()या बिना टिंकर किए बिना दबाया जा सकता है capture.output()। दमन सामान्य रूप से के रूप में आता है suppressWarnings(), suppressMessages(), suppressPackageStartupMessages(), और पर इतना। इस प्रकार, उपयोगकर्ता केवल परिणाम का सामना करने वाले आउटपुट के साथ सामना कर रहे हैं। यह विशेष रूप से महत्वपूर्ण है अगर आप उन बंद पाठ आधारित उत्पादन मोड़ है जब या तो के माध्यम से गतिशील दस्तावेज़ बनाने के लचीलेपन की अनुमति के लिए योजना है knitr , rmarkdown , या Sweave

विशेष रूप से, knitrइस तरह के रूप हिस्सा विकल्प प्रदान करता है error = F, message = Fऔर warning = F। यह दस्तावेज़ में आदेश के साथ पाठ की कमी को सक्षम करता है। इसके अलावा, यह उस results = "hide"विकल्प के उपयोग से आवश्यकता को रोकता है जो सभी आउटपुट को अक्षम कर देगा।

आउटपुट की विशिष्टताएँ

प्रिंट करें ()

ऊपर पहले, हम, एक oldie लेकिन एक goodie है print()। इस फ़ंक्शन की कुछ गंभीर सीमाएँ हैं। उनमें से एक शर्तों के एम्बेडेड संघनन की कमी है। दूसरा, और शायद अधिक गंभीर, तथ्य यह है कि प्रत्येक आउटपुट से पहले [x]वास्तविक सामग्री के आसपास कोटेशन के बाद होता है। xइस मामले में तत्व संख्या मुद्रित किया जा रहा करने के लिए संदर्भित करता है। यह डीबगिंग उद्देश्यों के लिए सहायक है, लेकिन इसके बाहर यह किसी भी उद्देश्य की पूर्ति नहीं करता है।

जैसे

print("Hello!")

[1] "Hello!"

सहमति के लिए, हम paste()सिंक के साथ काम करने वाले फ़ंक्शन पर भरोसा करते हैं print():

print(paste("Hello","World!"))

[1] "Hello World!"

वैकल्पिक रूप से, एक का उपयोग कर सकते हैं paste0(...)जगह में समारोह के paste(...)एक के डिफ़ॉल्ट उपयोग से बचने के लिए spaceद्वारा नियंत्रित तत्वों के बीच paste()के sep = " "पैरामीटर। (रिक्त स्थान के बिना उर्फ ​​संघटन)

जैसे

print(paste0("Hello","World!"))

[1] "HelloWorld!"

print(paste("Hello","World!", sep = ""))

[1] "HelloWorld!"

बिल्ली()

फ्लिप की तरफ, cat()इन सभी समालोचनाओं को संबोधित करता है। सबसे विशेष रूप से, कार्यक्षमता का sep=" "पैरामीटर paste()एक को लिखने में सक्षम करने के लिए बनाया गया paste()है cat()। हालाँकि, cat()फ़ंक्शन का एकमात्र नकारात्मक पक्ष यह है कि आपको \nअंत में संलग्न या fill = TRUE(डिफ़ॉल्ट प्रिंट चौड़ाई का उपयोग करके) नई लाइनों को बाध्य करना होगा ।

जैसे

cat("Hello!\n")
Hello!

cat("Hello","World!\n")
Hello World!

cat("Hello","World!\n", sep = "")
HelloWorld!

यह इस कारण से है कि आपको S3 विधि को cat()डिज़ाइन करते समय उपयोग क्यों करना चाहिए print.*()

संदेश()

message()समारोह एक कदम भी की तुलना में बेहतर है cat()! इसका कारण पारंपरिक सादे पाठ से अलग है क्योंकि इसके stderrबजाय इसका निर्देशन किया जाता है stdout। उदाहरण के लिए, उन्होंने उपयोगकर्ताओं की नज़र को पकड़ने के लिए मानक काले आउटपुट से लाल आउटपुट में रंग बदल दिया।

संदेश आउटपुट

इसके अलावा, आपके पास paste0()कार्यक्षमता में अंतर्निहित है ।

message("Hello ","World!") # Note the space after Hello
"Hello World!"

इसके अलावा, message()एक त्रुटि स्थिति प्रदान करता है जिसका उपयोग किया जा सकता हैtryCatch()

जैसे

 tryCatch(message("hello\n"), message=function(e){cat("goodbye\n")})
 goodbye

चेतावनी ()

warning()समारोह लापरवाही से उपयोग करने के लिए कुछ नहीं है। चेतावनी फ़ंक्शन को संदेश फ़ंक्शन से मुख्य रूप से अलग-अलग एक पंक्ति होती है, जिससे इसे ( "Warning message:") और इसके राज्य को समस्याग्रस्त माना जाता है।

चेतावनी उत्पादन

विविध: एक समारोह में आकस्मिक उपयोग अनजाने में हार्टब्रेक को ट्रिगर कर सकता है जबकि उदाहरण के चेक और चेतावनियों के कारण पैकेज को सीआरएएन में अपलोड करने की कोशिश की जाती है, जिसे आमतौर पर "त्रुटियों" के रूप में माना जाता है।

रुकें()

अंतिम लेकिन कम से कम, हमारे पास नहीं है stop()। यह कार्य को पूरी तरह से हाथ में लेने और उपयोगकर्ता पर नियंत्रण वापस करके चेतावनी को अगले स्तर तक ले जाता है। इसके अलावा, इसमें सबसे गंभीर उपसर्ग है, इस शब्द "Error:"को जोड़ा जा रहा है।

त्रुटि आउटपुट


प्रिंट डिजाइन करते समय message("hello world")और उसके बीच अंतर क्या है cat("hello world", sep="\n")। * S3 विधि?
एंटोनियो

1
@antonio: message()लाल पाठ होगा और दूसरा नहीं होगा। अब, यदि आप चर को जोड़ते हैं cat, उदाहरण के लिए cat("hello world", "antonio", sep="\n"), अंतर एक पंक्ति के साथ hello worldऔर दूसरा साथ होगा antonio। हालांकि, message()सब कुछ एक ही लाइन पर रखेगा।
कोटलेस

1
शानदार प्रतिक्रिया के लिए धन्यवाद। मैं कुछ इसी तरह की तलाश में था, लेकिन मेरे सवाल को "आलसी" लेबल किया गया था: stackoverflow.com/questions/36065232/…
बर्गर


1
@WaldirLeoncio "Diagnostic" आउटपुट वह है जो उदाहरण के लिए "स्तर की जानकारी" पर मुद्रित किया जा रहा है। दुर्भाग्य से, उस अवधारणा के साथ मौजूद नहीं है message()या cat()। मैंने देखा कि क्या आर के लिए एक परिपक्व लॉगिंग इंटरफ़ेस है जैसा कि आज अधिकांश प्रणालियों का मामला है (उदाहरण के लिए जावा के लिए slf4j एपीआई), और वहाँ है : futile.logger - CRAN पर
डेविड टोनहोफर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.