2009-12-28 16 views
22

मुझे आश्चर्य है कि R में संचालन की दक्षता के बारे में कोई दस्तावेज है, विशेष रूप से डेटा मैनिपुलेशन से संबंधित।आर डेटा संरचनाओं पर संचालन की क्षमता

उदाहरण के लिए:

  • मैं कल्पना यह, एक डेटा फ्रेम में कॉलम जोड़ने के लिए क्योंकि मैं तुम्हें सिर्फ एक लिंक की गई सूची में कोई तत्व जोड़ रहे अनुमान लगा रहा हूँ कुशल है।
  • मुझे लगता है कि पंक्तियों को जोड़ना धीमा है क्योंकि वेक्टर C level पर सरणी में आयोजित होते हैं और आपको n+1 की एक नई सरणी आवंटित करनी होगी और सभी तत्वों को प्रतिलिपि बनाना होगा।

डेवलपर्स शायद खुद को किसी विशेष कार्यान्वयन से जोड़ना नहीं चाहते हैं, लेकिन अनुमान लगाने के अनुमानों के मुकाबले कुछ और ठोस होना अच्छा लगेगा।

इसके अलावा, मुझे पता है कि मुख्य R प्रदर्शन संकेत loops के विपरीत होने पर वेक्टर ऑपरेशन का उपयोग करना है।

  • apply के विभिन्न स्वादों के बारे में क्या?
  • क्या वे सिर्फ hidden loops हैं?
  • matrices बनाम data frames के बारे में क्या?
+0

आर प्रदर्शन पर हाल की जानकारी के लिए, हैडली विकम के एडवांस्ड आर में [प्रदर्शन] (http://adv-r.had.co.nz/Performance.html) पर एक सूचनात्मक अनुभाग है और जेफरी हॉर्नर ने कुछ अद्भुत लिखा [आर में हैश टेबल प्रदर्शन] पर पोस्ट (http://jeffreyhorner.tumblr.com/post/114524915928/hash-table-performance-in-r-part-i)। – cbare

उत्तर

27

डाटा आईओ सुविधाओं मैं में से पहले मैं सीखने के लिए प्रतिबद्ध देखा में से एक था जा आर बेहतर या बदतर के लिए, यहाँ इन मुद्दों पर मेरी टिप्पणियों और समाधान/राहत दिला रहे हैं: आर हैंडल नहीं करता

1.कि बड़ा डेटा (> 2 जीबी?) मेरे लिए यह एक मिथ्या है। डिफ़ॉल्ट रूप से, सामान्य डेटा इनपुट फ़ंक्शंस आपके डेटा को रैम में लोड करता है। ग्लिब नहीं होना चाहिए, लेकिन मेरे लिए, यह एक सुविधा है जो एक बग नहीं है - कभी भी मेरा डेटा मेरी उपलब्ध रैम में फिट होगा, जहां मैं इसे चाहता हूं। इसी तरह, SQLite की सबसे लोकप्रिय सुविधाओं में से एक इन-मेमोरी विकल्प है - उपयोगकर्ता को पूरे डीबी को रैम में लोड करने का आसान विकल्प है। यदि आपका डेटा स्मृति में फिट नहीं होगा, तो आर सामान्य आरडीबीएमएस सिस्टम (आरओडीबीसी, आरएसक्लाइट, आरएमआईएसक्यूएल, इत्यादि) के कनेक्शन के माध्यम से, फ़ाइलशैश पैकेज जैसे नो-फ्रिल विकल्पों के माध्यम से, और इसके माध्यम से, इसे जारी रखने के लिए आश्चर्यजनक रूप से आसान बनाता है। सिस्टम जो वर्तमान तकनीक/प्रथाओं (उदाहरण के लिए, मैं ff की सिफारिश कर सकता हूं)। दूसरे शब्दों में, आर डेवलपर्स ने एक समझदार (और शायद इष्टतम) डिफ़ॉल्ट चुना है, जिससे इसे ऑप्ट आउट करना बहुत आसान है।

2. read.table (read.csv, read.delim, एट अल।) के प्रदर्शन, अनुसंधान में डेटा प्राप्त करने के लिए सबसे आम साधन, सुधार किया जा सकता 5x (और अक्सर बहुत मेरे अनुभव में और अधिक) केवल कुछ read.table के डिफ़ॉल्ट तर्कों को चुनकर - प्रदर्शन पर सबसे बड़ा प्रभाव वाले लोगों का उल्लेख आर की सहायता (? read.table) में किया गया है। संक्षेप में, आर डेवलपर्स हमें बताते हैं कि यदि आप पैरामीटर 'colClasses', 'nrows', 'sep', और 'comment.char' (विशेष रूप से, पास में '' के लिए मान प्रदान करते हैं, यदि आपको पता है कि आपकी फ़ाइल हेडर के साथ शुरू होती है या लाइन 1 पर डेटा), आप एक महत्वपूर्ण प्रदर्शन लाभ देखेंगे। मैंने पाया कि यह सच होना है।

यहाँ के टुकड़े मैं उन पैरामीटर के लिए उपयोग कर रहे हैं:

(अपनी डेटा फ़ाइल में पंक्तियों की संख्या प्राप्त करने के लिए पैरामीटर एक तर्क के रूप इस स्निपेट की आपूर्ति करने के लिए, 'nrows', अपने कॉल में read.table को):

as.numeric((gsub("[^0-9]+", "", system(paste("wc -l ", file_name, sep=""), intern=T)))) 

प्रत्येक स्तंभ के लिए कक्षाएं पाने के लिए:

function(fname){sapply(read.table(fname, header=T, nrows=5), class)} 

ध्यान दें: आप एक तर्क के रूप में इस स्निपेट पारित नहीं हो सकता है, आप इसे पहले कॉल करने के लिए है, तो मूल्य प्रेषित गीला करना urned - दूसरे शब्दों में, फ़ंक्शन को कॉल करें, लौटाए गए मान को एक चर में बाध्य करें, और उसके बाद वैरिएबल में मान को अपने कॉल में पैरामीटर 'colClasses' को पढ़ने के लिए टाइप करें। योग्य:

3। स्कैन का उपयोग करना। केवल थोड़ी अधिक परेशानी के साथ, आप 'read.table' ('read.table' के बजाय 'स्कैन' का उपयोग करके उस से बेहतर कर सकते हैं ('read.table' को अनुकूलित करना) वास्तव में 'स्कैन' के आसपास एक रैपर है)। एक बार फिर, यह करना बहुत आसान है। मैं व्यक्तिगत रूप से प्रत्येक कॉलम इनपुट करने के लिए 'स्कैन' का उपयोग करता हूं, फिर आर, यानी, df = data.frame (cbind (col1, col2, ....) के अंदर अपना डेटा.फ्रेम बनाएं।

4. साधारण फ़ाइल स्वरूपों (उदा।, 'Txt', 'csv') के स्थान पर दृढ़ता के लिए आर के कंटेनर का उपयोग करें। आर की मूल डेटा फ़ाइल '।RData 'एक बाइनरी प्रारूप है जो संपीड़ित (' .gz ') txt डेटा फ़ाइल से थोड़ा छोटा है। आप (,) को सहेजते हुए उन्हें बनाते हैं। आप लोड() के साथ इसे आर नेमस्पेस में वापस लोड करते हैं। 'Read.table' की तुलना में लोड समय में अंतर नाटकीय है। उदाहरण के लिए, डब्ल्यू/एक 25 एमबी फ़ाइल (असंपीड़ित आकार)

system.time(read.table("tdata01.txt.gz", sep=",")) 
=> user system elapsed 
    6.173 0.245 **6.450** 

system.time(load("tdata01.RData")) 
=> user system elapsed 
    0.912 0.006 **0.912** 

5. डेटा प्रकार पर ध्यान देना आप एक प्रदर्शन को बढ़ावा देने अक्सर देने के लिए और अपनी स्मृति पदचिह्न को कम कर सकते हैं। यह बिंदु शायद आर से डेटा प्राप्त करने में अधिक उपयोगी है। यहां ध्यान रखने के लिए महत्वपूर्ण बिंदु यह है कि डिफ़ॉल्ट रूप से, आर अभिव्यक्तियों में संख्या को डबल-परिशुद्धता फ़्लोटिंग पॉइंट के रूप में व्याख्या किया जाता है, उदाहरण के लिए,> टाइपोफ (5) रिटर्न "डबल। " प्रत्येक के उचित आकार के सरणी के ऑब्जेक्ट आकार की तुलना करें और आप महत्व देख सकते हैं (object.size() का उपयोग करें)। तो जब आप कर सकते हैं पूर्णांक करने के लिए मजबूर।

आखिरकार, 'लागू' परिवारों के कार्यों (दूसरों के बीच) "छुपे हुए लूप" या लूप रैपर नहीं हैं। वे सी में लागू लूप हैं - बड़े अंतर प्रदर्शन के अनुसार। [संपादित करें: एडब्ल्यूबी ने सही ढंग से बताया है कि 'sapply', 'tapply', और 'mapply' को सी में लागू किया गया है, 'लागू' बस एक रैपर फ़ंक्शन है।

+4

मैं डॉग (अन्यथा उत्कृष्ट) पोस्ट में एक कथन को सही करना चाहता हूं, और डेटा I/O गति पर एक अच्छा संदर्भ इंगित करता हूं। सबसे पहले, सी 'लापली' में लागू सभी 'लागू' फ़ंक्शंस को सी में लागू नहीं किया गया है, जैसा कि 'सैप्ली' (जो 'लापता' लपेटता है)। 'मैप्ली' को सी 'लागू' में भी लागू किया गया है, हालांकि, 'के लिए' के ​​लिए बस एक अच्छा रैपर है; उत्कृष्ट 'प्लीयर' पैकेज में कार्यों के बारे में भी यही सच है। दूसरा, आईओ दक्षता के बारे में अधिक जानकारी के लिए क्रांति ब्लॉग पर इस प्रविष्टि की जांच करें: http://blog.revolution-computing.com/2009/12/speedreading-files-revisited.html – AWB

+0

सुधार के लिए धन्यवाद AWB - मेरा आपकी टिप्पणी को दर्शाने के लिए संशोधित उत्तर। – doug

+0

मैं आपके पहले बिंदु का पालन नहीं करता हूं: क्या आप कह रहे हैं कि आर बड़े डेटा को संभालता या नहीं करता है? यह निश्चित रूप से करता है (जैसा कि आप इंगित करते हैं), तो हो सकता है कि आप इसे दूसरों द्वारा एक आम गलतफहमी के रूप में बता रहे हों? – Iterator

11

ये चीजें विशेष रूप से आर-डेवेल पर सूचियों पर पॉप अप करती हैं। एक काफी अच्छी तरह से स्थापित नगेट है कि उदा। matrix संचालन data.frame संचालन से तेज़ होते हैं। फिर ऐसे ऐड-ऑन पैकेज हैं जो अच्छी तरह से करते हैं - मैट का data.table पैकेज बहुत तेज़ है, और जेफ को xts त्वरित होने के लिए मिला है।

लेकिन यह "सभी निर्भर करता है" - इसलिए आपको आमतौर पर प्रोफ़ाइल पर आपके विशेष कोड पर सलाह दी जाती है। R में बहुत सारे प्रोफाइलिंग समर्थन हैं, इसलिए आपको इसका उपयोग करना चाहिए। मेरे Intro to HPC with R tutorials में कई प्रोफाइलिंग उदाहरण हैं।

6

मैं वापस आने और अधिक जानकारी प्रदान करने की कोशिश करूंगा। यदि आपके पास एक ऑपरेशन की दक्षता के बारे में कोई सवाल है, तो आप अपने कोड को प्रोफाइल करने के लिए सबसे अच्छा करेंगे (जैसा कि डिर्क सुझाव देता है)। system.time() फ़ंक्शन ऐसा करने का सबसे आसान तरीका है हालांकि कई और उन्नत सुविधाएं हैं (उदा। आरप्रोफ, दस्तावेज here के रूप में)।

अपने प्रश्न के दूसरे भाग के लिए एक त्वरित प्रतिक्रिया:

क्या लागू के विभिन्न जायके के बारे में? क्या वे छिपे हुए लूप हैं?

अधिकांश भाग के लिए हाँ, लागू कार्यों सिर्फ लूप और धीमी गति से for बयान हो सकता है कर रहे हैं। उनका मुख्य लाभ स्पष्ट कोड है। मुख्य अपवाद जो मैंने पाया है lapply है जो तेजी से हो सकता है क्योंकि इसे सी में सीधे कोड किया गया है।

और मैट्रिस बनाम डेटा फ्रेम के बारे में क्या?

मैट्रिस डेटा फ्रेम से अधिक कुशल हैं क्योंकि उन्हें भंडारण के लिए कम स्मृति की आवश्यकता होती है। ऐसा इसलिए है क्योंकि डेटा फ्रेम को अतिरिक्त विशेषता डेटा की आवश्यकता होती है। R Introduction से:

कई प्रयोजनों के लिए एक डेटा फ्रेम मई भिन्न मोड के संभवतः कॉलम के साथ एक मैट्रिक्स के रूप में माना और विशेषताएँ

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