2013-10-06 7 views
5

मैं डेटा सफाई में लगी हुई हूं। मैं एक समारोह है कि एक बड़ा इनपुट फ़ाइल में बुरा पंक्तियों को दिखाता है (भी एक बार में पढ़ने के लिए बड़ा है, मेरे राम आकार दिया) और एक वेक्टर badRows के रूप में बुरा पंक्तियों की पंक्ति संख्या देता है। यह कार्य काम करता प्रतीत होता है।मैं "readLines" कमांड का उपयोग करके बड़ी फ़ाइलों से चयनित पंक्तियों को कैसे पढ़ सकता हूं और उन्हें डेटा फ्रेम में लिख सकता हूं?

अब मैं केवल डेटा पंक्ति में खराब पंक्तियों को पढ़ने की कोशिश कर रहा हूं, अब तक असफल रहा है।

मेरा वर्तमान दृष्टिकोण पढ़ने के लिए प्रत्येक पंक्ति के बीच छोड़ने के लिए पंक्तियों की संख्या के वेक्टर का उपयोग करके, मेरी फ़ाइल के खुले कनेक्शन पर read.table का उपयोग करना है। यह संख्या लगातार खराब पंक्तियों के लिए शून्य है।

मैं के रूप में skipVec गणना:

(badRowNumbers - c(0, badRowNumbers[1:(length(badRowNumbers-1]))-1 

लेकिन पल के लिए मैं बस सब शून्य के एक skipVec वेक्टर मेरी समारोह सौंपने कर रहा हूँ।

अगर मेरे तर्क सही है, तो यह सब पंक्तियों को वापस करना चाहिए। ऐसा नहीं होता। इसके बजाय मैं एक त्रुटि मिलती है:

"Error in read.table(con, skip = pass, nrow = 1, header = TRUE, sep = "") : no lines available in input"

मेरे वर्तमान समारोह शिथिल Miron Kursa ("MBq"), जो मैं here पाया द्वारा एक समारोह पर आधारित है।

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

मैं RStudio 0.97.551 के तहत एक क्रैकी पुरानी विंडोज एक्सपी एसपी 3 मशीन पर 3 जीआईजी रैम के साथ आर 3.0.1 चला रहा हूं। पाषाण युग, मुझे पता है।

# Make a small small test data frame, write it to a file, and read it back in 
# a row at a time. 
testThis.DF <- data.frame(nnn=c(2,3,5), fff=c("aa", "bb", "cc")) 
testThis.DF 

# This function will work only if the number of bad rows is not too big for memory 
write.table(testThis.DF, "testThis.DF") 
con<-file("testThis.DF") 
open(con) 
skipVec <- c(0,0,0) 
badRows.DF <- lapply(skipVec, FUN=function(pass){ 
    read.table(con, skip=pass, nrow=1, header=TRUE, sep="") }) 
close(con) 

त्रुटि पास आदेश से पहले होता है:

यहाँ कोड है कि इसके बाद के संस्करण त्रुटि संदेश पैदा करता है। अगर मैं लेटली और फ़ंक्शन से रीडलाइन कमांड को कम करता हूं और इसे अपने आप में चिपकाता हूं, तो मुझे अभी भी वही त्रुटि मिलती है।

उत्तर

5

बजाय lapply के माध्यम से read.table चलाने का तुम सिर्फ मैन्युअल रूप से पहले कुछ पुनरावृत्तियों चलाते हैं, तो आप क्या चल रहा है देखेंगे:

> read.table(con, skip=0, nrow=1, header=TRUE, sep="") 
    nnn fff 
1 2 aa 
> read.table(con, skip=0, nrow=1, header=TRUE, sep="") 
    X2 X3 bb 
1 3 5 cc 

क्योंकि header = TRUE यह एक पंक्ति है कि प्रत्येक दो यात्रा लेकिन कम से पढ़ा जाता है नहीं है है, तो आप अंत में लाइनों के बाहर तेजी से आपको लगता है, तीसरे यात्रा पर चलने यहाँ:

> read.table(con, skip=0, nrow=1, header=TRUE, sep="") 
Error in read.table(con, skip = 0, nrow = 1, header = TRUE, sep = "") : 
    no lines available in input 

अब यह अभी भी नहीं आपकी समस्या के हल के लिए एक बहुत ही कारगर तरीका हो सकता है, लेकिन यह आप कैसे है

write.table(testThis.DF, "testThis.DF") 
con <- file("testThis.DF") 
open(con) 
header <- scan(con, what = character(), nlines = 1, quiet = TRUE) 
skipVec <- c(0,1,0) 
badRows <- lapply(skipVec, function(pass){ 
    line <- read.table(con, nrow = 1, header = FALSE, sep = "", 
        row.names = 1) 
    if (pass) NULL else line 
    }) 
badRows.DF <- setNames(do.call(rbind, badRows), header) 
close(con) 

उच्च गति की दिशा में कुछ सुराग:

  1. उपयोग read.table के बजाय scan अपने वर्तमान कोड को ठीक कर सकते हैं। character के रूप में और केवल अंत में डेटा पढ़ें, के बाद आप एक चरित्र मैट्रिक्स या data.frame में अपने डेटा डाल दिया है, प्रत्येक कॉलम को type.convert लागू होते हैं।
  2. skipVec से अधिक लूपिंग के बजाय, rle पर लूप करें यदि यह बहुत छोटा है। तो आप एक समय में लाइनों के हिस्सों को पढ़ने या छोड़ने में सक्षम होंगे।
+0

प्रिय @ फ्लोडेल- यह कोड काम नहीं करता है, लेकिन मुझे लगता है कि यह सिर्फ एक टाइपो है, क्योंकि यह 0,1,0 के बजाय skipVec = 0,0,0 के लिए काम करता है। हालांकि यह काम करता है, मैं यह स्वीकार करने के लिए शर्मिंदा हूं कि मुझे कुछ तर्क याद आ रहा है। सबसे पहले, मुझे नहीं पता कि आप पहली पंक्ति क्यों स्कैन करते हैं और बाकी के लिए read.table का उपयोग करते हैं। लेकिन मेरा बड़ा भ्रम, शायद क्योंकि मुझे समझ में नहीं आता कि फ़ाइलों और कनेक्शनों को अलग तरीके से कैसे संसाधित किया जाता है, यह है कि मुझे नहीं लगता कि क्यों skipVec = 0,0,0 पहली पंक्ति में शुरू नहीं होता है। इसके अलावा, मुझे नहीं पता कि एक राल क्या है। मैंने फंक्शन डॉक पढ़ा है, लेकिन मुझे नहीं पता कि रन क्या है या रन लम्बाई है, या कैसे पता लगाना है। – andrewH

+0

* यह कोड काम नहीं करता है * मेरे लिए बहुत उपयोगी नहीं है जबतक कि आप मुझे बताएं कि यह क्यों काम नहीं करता है। अप्रत्याशित आउटपुट, त्रुटि संदेश? ध्यान दें कि यह आपके उदाहरण के साथ काम करता है, इसलिए हो सकता है कि आपकी वास्तविक डेटा फ़ाइल में एक उदाहरण है जो आप हमें इस उदाहरण में बना रहे हैं। – flodel

+0

एक कनेक्शन एक फ़ाइल की तरह है जो खुला रखा जाता है, इसलिए इसे पढ़ने या लिखने के लिए कई बार एक्सेस किया जा सकता है। कनेक्शन में एक पॉइंटर शामिल होता है जहां डेटा को अंतिम बार पढ़ा या लिखा गया था। जब आप पहली बार फ़ाइल खोलते हैं, तो फ़ाइल हैंडल फ़ाइल की शुरुआत को इंगित कर रहा है। 'Read.table (con, skip = 0, nrow = 1, header = TRUE, sep = "") का उपयोग करने के बाद, पहली बार, हेडर और आपकी फ़ाइल की पहली डेटा पंक्ति पढ़ी जाती है ताकि सूचक अब इंगित कर रहा हो दूसरी डेटा पंक्ति की शुरुआत के लिए। – flodel

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

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