2011-01-21 6 views
15

से बाहर किए बिना दो विशाल डेटा-फ्रेम को कैसे रेबिंड करें मेरे पास दो डेटा-फ्रेम df1 और df2 हैं जिनमें प्रत्येक के पास लगभग 10 मिलियन पंक्तियां और 4 कॉलम हैं। मैंने उन्हें RODBC/sqlQuery का उपयोग करके आर में कोई समस्या नहीं पढ़ी, लेकिन जब मैं rbind पर कोशिश करता हूं, तो मुझे लगता है कि आर त्रुटि संदेशों का सबसे डरावना संदेश है: cannot allocate memoryrbind अधिक कुशलता से करने के लिए और अधिक कुशल तरीके होने चाहिए - किसी के पास अपनी पसंदीदा चालें हैं जिन्हें वे साझा करना चाहते हैं? उदाहरण के लिए मैं sqldf के लिए दस्तावेज़ में इस उदाहरण पाया:आर: मेमोरी

# rbind 
a7r <- rbind(a5r, a6r) 
a7s <- sqldf("select * from a5s union all select * from a6s") 

है कि सबसे अच्छा/सुझाया गया तरीका यह करने के लिए है?

अद्यतन मैं इसे, इसलिए आयात इच्छित आकार का एक data.frame बनाने के लिए करने के लिए this question

+0

क्या आपने पूर्व-आवंटन करने का प्रयास किया था? – aL3xa

+0

अच्छा विचार - मैं यह कैसे कर सकता हूं - आपका मतलब है 'memory.limit (size = 4000)' जैसे कुछ का उपयोग करना? –

+0

सं। बीटीडब्ल्यू, जो केवल विंडोज़ में काम करता है। नीचे मेरा जवाब देखें। – aL3xa

उत्तर

23

बल्कि उन्हें शुरुआत में आर में पढ़ने और फिर उन्हें संयोजन आप SQLite उन्हें पढ़ने के लिए है और उन्हें आर को इस तरह फ़ाइलों को व्यक्तिगत रूप से आर में

# create two sample files 
DF1 <- data.frame(A = 1:2, B = 2:3) 
write.table(DF1, "data1.dat", sep = ",", quote = FALSE) 
rm(DF1) 

DF2 <- data.frame(A = 10:11, B = 12:13) 
write.table(DF2, "data2.dat", sep = ",", quote = FALSE) 
rm(DF2) 

# now we do the real work 
library(sqldf) 

data1 <- file("data1.dat") 
data2 <- file("data2.dat") 

sqldf(c("select * from data1", 
"insert into data1 select * from data2", 
"select * from data1"), 
dbname = tempfile()) 

कभी नहीं लोड किए गए हैं भेजने से पहले उन्हें जोड़ सकता से इस देता है:

sqldf("select * from data1 union select * from data2", dbname = tempfile()) 
:

> sqldf(c("select * from data1", "insert into data1 select * from data2", "select * from data1"), dbname = tempfile()) 
    A B 
1 1 2 
2 2 3 
3 10 12 
4 11 13 

यह छोटा संस्करण भी अगर पंक्ति आदेश महत्वहीन है काम करता है

अधिक जानकारी के लिए sqldf होम पेज http://sqldf.googlecode.com और ?sqldf देखें। फ़ाइल प्रारूप तर्कों पर विशेष ध्यान दें क्योंकि वे करीब हैं लेकिन read.table के समान नहीं हैं। यहां हमने डिफ़ॉल्ट का उपयोग किया है, इसलिए यह एक मुद्दा था।

+0

साफ दृष्टिकोण ... एसक्यूएल निश्चित रूप से कुछ बड़ा चबाने में सक्षम है! – aL3xa

+0

बहुत उपयोगी, धन्यवाद @ गैबर ... मेरे पास एक वास्तविक SQL डेटाबेस में डेटा है, और एक क्वेरी के साथ पूरी चीज को पढ़ने से मेरी याददाश्त हो रही है, यही कारण है कि मुझे 'आरओडीबीसी/एसक्ल्यूक्वियर' का उपयोग करके पहले प्रत्येक आर को पढ़ना पड़ा '(मुझसे मत पूछो कि यह पूरी चीज पर क्यों दबा हुआ है, लेकिन जब मैं प्रत्येक छमाही पढ़ता हूं तो चकित नहीं होता)। लेकिन मैं सहमत हूं कि मेरा मूल डेटा दो फ्लैट फाइलों में है, तो उन्हें पढ़ने के लिए आपका सबसे अच्छा तरीका है, और आर मेमोरी में दो हिस्सों को रखने से बचें। –

1

प्रयास करें, sqldf कॉल में महत्वपूर्ण dbname = tempfile() तर्क का उपयोग काम करने के लिए ऊपर अपने जवाब में जद लांग पता चलता है के रूप में मिला सबस्क्रिप्ट का उपयोग कर आपका डेटा।

dtf <- as.data.frame(matrix(NA, 10, 10)) 
dtf1 <- as.data.frame(matrix(1:50, 5, 10, byrow=TRUE)) 
dtf2 <- as.data.frame(matrix(51:100, 5, 10, byrow=TRUE)) 
dtf[1:5, ] <- dtf1 
dtf[6:10, ] <- dtf2 

मुझे लगता है कि rbind उसके आयाम पूर्व आवंटन बिना वस्तु होती है ... मैं सकारात्मक यकीन नहीं है, यह केवल एक अनुमान है। मैं आज रात "द आर इन्फर्नो" या "डेटा मैनिपुलेशन आर" के साथ मिल जाएगा। हो सकता है कि merge चाल करना होगा ...

संपादित

और तुम मन में नंगा होना चाहिए कि (शायद) आपके सिस्टम और/या अनुसंधान कुछ है कि बड़े से निपटने नहीं कर सकते। RevolutionR आज़माएं, शायद आप कुछ समय/संसाधनों को छोड़कर प्रबंधित करेंगे।

+0

दिलचस्प सुझाव, धन्यवाद। मुझे इसे आज़माना है। (मैं फ्री आर से परे नहीं जाना चाहता हूं, इसलिए रेवो मेरे लिए एक विकल्प नहीं है) –

+1

दिलचस्प सुझाव है, लेकिन यह rbind की तुलना में कहीं अधिक स्मृति का उपयोग करता है। –

15

data.table आर पैकेज पर ध्यान दें कि कई मिलियन से अधिक रिकॉर्ड वाले ऑब्जेक्ट्स पर कुशल संचालन के लिए।

उस पैकेज का संस्करण 1.8.2 rbindlist फ़ंक्शन प्रदान करता है जिसके माध्यम से आप जो कुछ हासिल करना चाहते हैं उसे प्राप्त कर सकते हैं। इस प्रकार rbind(a5r, a6r) के बजाय आप कर सकते हैं:

library(data.table) 
rbindlist(list(a5r, a6r)) 
+1

क्या आप पहले डेटा में डेटासेट को लोड किए बिना ऐसा कर सकते हैं? – panterasBox

1

संघ के विषय पर इस सूत्र में पूर्णता के लिए: बड़ी फ़ाइलों को ing, उन्हें गठबंधन करने के लिए फाइलों पर खोल आदेशों का उपयोग करके देखें। "/ B" ध्वज के साथ "COPY" कमांड वाली विंडो में।उदाहरण:

system(command = 
     paste0(
      c("cmd.exe /c COPY /Y" 
      , '"file_1.csv" /B' 
      , '+ "file_2.csv" /B' 
      , '"resulting_file.csv" /B' 
      ), collapse = " " 
     ) 
)#system 

आवश्यक है कि फ़ाइलों को बिना किसी शीर्ष लेख, और एक ही सीमांकक आदि आदि की गति और खोल आदेशों की बहुमुखी प्रतिभा कभी कभी एक महान लाभ है, इसलिए जब dataflows मानचित्रण मत भूलना CLI-आदेशों।