ดังนั้นฉันจึงมีไฟล์ข้อมูล (คั่นด้วยอัฒภาค) ที่มีรายละเอียดจำนวนมากและแถวที่ไม่สมบูรณ์ (นำ Access และ SQL ไปสู่การสำลัก) เป็นชุดข้อมูลระดับเขตที่แบ่งออกเป็นกลุ่มกลุ่มย่อยและกลุ่มย่อย (รวมประมาณ 200 ปัจจัย) เป็นเวลา 40 ปี ในระยะสั้นมันใหญ่มากและมันจะไม่พอดีกับหน่วยความจำถ้าฉันพยายามอ่านมัน
คำถามของฉันก็คือสิ่งนี้เนื่องจากฉันต้องการมณฑลทั้งหมด แต่เพียงปีเดียว (และเป็นเพียงระดับสูงสุดของกลุ่ม ... นำไปสู่ประมาณ 100,000 แถวในตอนท้าย) วิธีที่ดีที่สุดในการรับ ค่าสะสมนี้เป็น R?
ตอนนี้ฉันกำลังพยายามตัดทอนปีที่ไม่เกี่ยวข้องกับ Python โดยหลีกเลี่ยงขีด จำกัด ขนาดไฟล์โดยการอ่านและดำเนินการทีละบรรทัด แต่ฉันต้องการโซลูชัน R-only (แพ็คเกจ CRAN OK) มีวิธีที่คล้ายกันในการอ่านไฟล์ทีละชิ้นใน R หรือไม่?
ความคิดใด ๆ ที่จะได้รับการชื่นชมอย่างมาก.
อัปเดต:
- ข้อ จำกัด
- จำเป็นต้องใช้เครื่องของฉันจึงไม่มีอินสแตนซ์ EC2
- R-only ให้มากที่สุด ความเร็วและทรัพยากรไม่น่ากังวลในกรณีนี้ ... หากเครื่องของฉันไม่ระเบิด ...
- ดังที่คุณเห็นด้านล่างข้อมูลมีหลายประเภทซึ่งฉันต้องดำเนินการในภายหลัง
- ข้อมูล
- ข้อมูลคือ 3.5GB โดยมีประมาณ 8.5 ล้านแถวและ 17 คอลัมน์
- สองพันแถว (~ 2k) ผิดรูปแบบโดยมีเพียงคอลัมน์เดียวแทนที่จะเป็น 17
- สิ่งเหล่านี้ไม่สำคัญเลยและอาจถูกทิ้งได้
- ฉันต้องการเพียง ~ 100,000 แถวจากไฟล์นี้ (ดูด้านล่าง)
ตัวอย่างข้อมูล:
County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ...
Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ...
Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ...
NC [Malformed row]
[8.5 Mill rows]
ฉันต้องการตัดคอลัมน์ออกและเลือกสองใน 40 ปีที่มีอยู่ (2552-2553 ตั้งแต่ปี 2523-2563) เพื่อให้ข้อมูลพอดีกับ R:
County; State; Year; Quarter; Segment; GDP; ...
Ada County;NC;2009;4;FIRE;80.1; ...
Ada County;NC;2010;1;FIRE;82.5; ...
[~200,000 rows]
ผล:
หลังจากแก้ไขข้อเสนอแนะทั้งหมดแล้วฉันตัดสินใจว่า readLines ที่แนะนำโดย JD และ Marek จะทำงานได้ดีที่สุด ฉันให้เช็คมาเร็คเพราะเขาให้ตัวอย่างการใช้งาน
ฉันได้จำลองการใช้งานของ Marek เวอร์ชันที่ดัดแปลงเล็กน้อยสำหรับคำตอบสุดท้ายของฉันที่นี่โดยใช้ strsplit และ cat เพื่อเก็บเฉพาะคอลัมน์ที่ฉันต้องการ
มันก็ควรจะตั้งข้อสังเกตนี้อยู่มากที่มีประสิทธิภาพน้อยกว่างูใหญ่ ... ในขณะที่งูหลาม chomps ผ่านไฟล์ 3.5GB ใน 5 นาทีในขณะที่อาร์จะใช้เวลาประมาณ 60 ... แต่ถ้าทั้งหมดที่คุณมี R แล้วนี้เป็นตั๋ว
## Open a connection separately to hold the cursor position
file.in <- file('bad_data.txt', 'rt')
file.out <- file('chopped_data.txt', 'wt')
line <- readLines(file.in, n=1)
line.split <- strsplit(line, ';')
# Stitching together only the columns we want
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
## Use a loop to read in the rest of the lines
line <- readLines(file.in, n=1)
while (length(line)) {
line.split <- strsplit(line, ';')
if (length(line.split[[1]]) > 1) {
if (line.split[[1]][3] == '2009') {
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
}
}
line<- readLines(file.in, n=1)
}
close(file.in)
close(file.out)
ความล้มเหลวโดยวิธีการ:
- sqldf
- นี่คือสิ่งที่ฉันจะใช้สำหรับปัญหาประเภทนี้ในอนาคตหากข้อมูลมีรูปแบบที่ดี อย่างไรก็ตามหากไม่เป็นเช่นนั้น SQLite chokes
- MapReduce
- บอกตามตรงว่าเอกสารข่มขู่ฉันเกี่ยวกับเรื่องนี้เล็กน้อยดังนั้นฉันจึงไม่ได้ลองทำ ดูเหมือนว่ามันต้องการให้วัตถุอยู่ในหน่วยความจำเช่นกันซึ่งจะเอาชนะจุดนั้นได้หากเป็นเช่นนั้น
- หน่วยความจำขนาดใหญ่
- วิธีนี้เชื่อมโยงกับข้อมูลอย่างสมบูรณ์ แต่สามารถจัดการได้ครั้งละหนึ่งประเภทเท่านั้น เป็นผลให้เวกเตอร์อักขระทั้งหมดของฉันลดลงเมื่อใส่ใน big.table หากฉันต้องการออกแบบชุดข้อมูลขนาดใหญ่สำหรับอนาคตฉันจะพิจารณาใช้ตัวเลขเพียงเพื่อให้ตัวเลือกนี้คงอยู่ต่อไป
- สแกน
- การสแกนดูเหมือนจะมีปัญหาประเภทเดียวกันกับหน่วยความจำขนาดใหญ่ แต่ด้วยกลไกทั้งหมดของ readLines ในระยะสั้นมันไม่พอดีกับใบเรียกเก็บเงินในครั้งนี้
sed
และ / หรือawk
สร้าง CSV เวอร์ชันที่สับลงมาซึ่งคุณสามารถอ่านได้โดยตรง เนื่องจากนี่เป็นวิธีแก้ปัญหามากกว่าคำตอบฉันจะทิ้งไว้เป็นความคิดเห็น