2012-03-26 18 views
11

Tôi muốn truyền một bảng dữ liệu lớn vào R LINE BY LINE và nếu dòng hiện tại có điều kiện cụ thể (cho phép nói các cột đầu tiên> 15), hãy thêm dòng vào dữ liệu trong bộ nhớ. Tôi đã viết mã sau:R - Đọc dòng STDIN theo dòng

count<-1; 
Mydata<-NULL; 
fin <- FALSE; 
while (!fin){ 
    if (count==1){ 
     Myrow=read.delim(pipe('cat /dev/stdin'), header=F,sep="\t",nrows=1); 
     Mydata<-rbind(Mydata,Myrow); 
     count<-count+1; 
    } 
    else { 
     count<-count+1; 
     Myrow=read.delim(pipe('cat /dev/stdin'), header=F,sep="\t",nrows=1); 
     if (Myrow!=""){ 
     if (MyCONDITION){ 
      Mydata<-rbind(Mydata,Myrow); 
     } 
     } 
     else 
     {fin<-TRUE} 
    } 
} 
print(Mydata); 

Nhưng tôi nhận được lỗi "dữ liệu không khả dụng". Xin lưu ý rằng dữ liệu của tôi lớn và tôi không muốn đọc tất cả cùng một lúc và áp dụng điều kiện của tôi (trong trường hợp này thật dễ dàng).

+0

Bạn có thể quan tâm đến câu trả lời và nhận xét về q này: http://stackoverflow.com/questions/9352887/strategies-for-reading-in-csv-files-in-pieces –

+0

xem '? Scan ','? readLines', 'nrows' đối số của' read.table', và lưu ý rằng giải pháp của bạn sẽ được ** rất ** chậm trong R - bạn có thể sử dụng Perl, hoặc thậm chí awk, để tiền xử lý? –

+1

Câu trả lời của tôi dưới đây về tốc độ như thế nào? Về bản chất tôi mở một tập tin và tiếp tục trích xuất các dòng từ nó mà không đóng tập tin. –

Trả lời

11

Tôi nghĩ sẽ khôn ngoan hơn khi sử dụng hàm R như readLines. readLines chỉ hỗ trợ đọc một số dòng được chỉ định, ví dụ: 1. Kết hợp rằng với việc mở một kết nối file trước tiên, và sau đó gọi readLines nhiều lần sẽ giúp bạn những gì bạn muốn. Khi gọi readLines nhiều lần, các dòng n tiếp theo sẽ được đọc từ kết nối. Trong mã R:

stop = FALSE 
f = file("/tmp/test.txt", "r") 
while(!stop) { 
    next_line = readLines(f, n = 1) 
    ## Insert some if statement logic here 
    if(length(next_line) == 0) { 
    stop = TRUE 
    close(f) 
    } 
} 

ý kiến ​​bổ sung:

  • R có một cách nội bộ của điều trị stdin như file: stdin(). Tôi đề nghị bạn sử dụng nó thay vì sử dụng pipe('cat /dev/stdin'). Điều này có thể làm cho nó mạnh mẽ hơn, và chắc chắn hơn nhiều nền tảng.
  • Bạn khởi tạo Mydata ngay từ đầu và tiếp tục phát triển nó bằng cách sử dụng rbind. Nếu số lượng các dòng mà bạn rbind trở nên lớn hơn, điều này sẽ rất chậm. Điều này phải làm với thực tế là khi đối tượng phát triển, hệ điều hành cần phải tìm một vị trí bộ nhớ mới cho nó, mà kết thúc lên lấy rất nhiều của thời gian. Tốt hơn là phân bổ trước MyData hoặc sử dụng vòng lặp kiểu áp dụng.
+0

Cảm ơn câu trả lời. Nhưng tôi có một câu hỏi liên quan đến nó: Như tôi đã đề cập, dữ liệu của tôi rất lớn và tôi không muốn đọc nó vào bộ nhớ. Trong dòng 3 của mã của bạn, có vẻ như bạn đang đọc toàn bộ dữ liệu và sau đó đi qua các dòng của nó. Tôi có đúng không? – user1250144

+0

Không, tôi mở một kết nối rồi đọc từ đó. 'next_line' chỉ chứa dòng hiện tại. Sử dụng 'file' chỉ mở một kết nối, nó chưa đọc bất cứ điều gì. –

+0

Ahan. cảm ơn. Tôi nên viết gì thay vì "/tmp/test.txt", đối số đầu tiên của tệp()? – user1250144