2010-02-13 29 views
7

Tôi có một quy trình trong R để tạo ra một loạt các đối tượng, sắp xếp chúng và đặt chúng thành các tệp văn bản thuần túy. Điều này có vẻ như là một cách thực sự tốt để xử lý mọi thứ kể từ khi tôi làm việc với Hadoop và tất cả các đầu ra cần truyền qua stdin và stdout.R: sắp xếp lại các đối tượng thành tập tin văn bản và ngược lại

Vấn đề tôi còn lại là cách đọc các đối tượng này ra khỏi tệp văn bản và quay lại R trên máy tính để bàn của tôi. Dưới đây là ví dụ hoạt động minh họa thử thách:

Hãy tạo tệp tmp và viết một đối tượng vào đó. Đối tượng này chỉ là một vector:

outCon <- file("c:/tmp", "w") 
mychars <- rawToChar(serialize(1:10, NULL, ascii=T)) 
cat(mychars, file=outCon) 
close(outCon) 

Đối tượng mychars trông như thế này:

> mychars 
[1] "A\n2\n133633\n131840\n13\n10\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" 

khi ghi vào tập tin văn bản nó trông như thế này:

A 
2 
133633 
131840 
13 
10 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

Tôi có thể nhìn thấy một cái gì đó khủng khiếp rõ ràng, nhưng làm thế nào để tôi đọc tập tin này trở lại vào R và unserialize đối tượng? Khi tôi thử quét() hoặc readLines() cả hai muốn xử lý các ký tự dòng mới như dấu phân cách ghi và tôi kết thúc với một vectơ trong đó mỗi phần tử là một hàng từ tệp văn bản. Những gì tôi thực sự muốn là một chuỗi văn bản với toàn bộ nội dung của tập tin. Sau đó, tôi có thể unserialize chuỗi.

Perl sẽ đọc ngắt dòng trở lại thành chuỗi, nhưng tôi không thể tìm ra cách ghi đè cách R xử lý ngắt dòng.

Trả lời

7

JD, chúng tôi làm điều đó trong gói digest qua serialize() đến/từ raw. Đó là tốt đẹp như bạn có thể lưu trữ các đối tượng serialized trong SQL và những nơi khác. Tôi thực sự sẽ lưu trữ này như RData cũng là cách nhanh hơn để load() (không phân tích cú pháp!) Và save().

Hoặc, nếu nó đã được RawToChar() và ascii sau đó sử dụng một cái gì đó như thế này (lấy trực tiếp từ help(digest) nơi chúng ta so sánh serialization của tập tin COPYING:

# test 'length' parameter and file input 
fname <- file.path(R.home(),"COPYING") 
x <- readChar(fname, file.info(fname)$size) # read file 
for (alg in c("sha1", "md5", "crc32")) { 
    # partial file 
    h1 <- digest(x , length=18000, algo=alg, serialize=FALSE) 
    h2 <- digest(fname, length=18000, algo=alg, serialize=FALSE, file=TRUE) 
    h3 <- digest(substr(x,1,18000) , algo=alg, serialize=FALSE) 
    stopifnot(identical(h1,h2), identical(h1,h3)) 
    # whole file 
    h1 <- digest(x , algo=alg, serialize=FALSE) 
    h2 <- digest(fname, algo=alg, serialize=FALSE, file=TRUE) 
    stopifnot(identical(h1,h2)) 
} 

như vậy với rằng ví dụ của bạn trở nên này:

R> outCon <- file("/tmp/jd.txt", "w") 
R> mychars <- rawToChar(serialize(1:10, NULL, ascii=T)) 
R> cat(mychars, file=outCon); close(outCon) 
R> fname <- "/tmp/jd.txt" 
R> readChar(fname, file.info(fname)$size) 
[1] "A\n2\n133633\n131840\n13\n10\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" 
R> unserialize(charToRaw(readChar(fname, file.info(fname)$size))) 
[1] 1 2 3 4 5 6 7 8 9 10 
R> 
+0

Nhìn lại, tôi nên giữ cho các đối tượng của tôi là thô. Tôi chắc chắn và lưu ý rằng khi tôi kết hợp các bài học của tôi học được từ việc sử dụng R trên Hadoop. Cảm ơn một lần nữa Dirk! –

+0

Phải. Và tôi _completely_ quên cắm gói RProtoBuf của chúng tôi mà tất nhiên cũng giúp! Mặc dù vậy, không có Windows nhị phân nào vì chúng tôi không có phiên bản được xây dựng của thư viện MinGW phù hợp để liên kết với R. –

Các vấn đề liên quan