2010-02-13 14 views
7

Mam proces w R, który tworzy wiązkę obiektów, serializuje je i umieszcza je w zwykłych plikach tekstowych. Wydaje się, że to dobry sposób na radzenie sobie z sytuacjami, ponieważ pracuję z Hadoop i wszystkie wyjścia muszą być przesyłane strumieniowo przez stdin i stdout.R: serializuje obiekty do pliku tekstowego iz powrotem

Problemem, który pozostało mi jest, jak odczytać te obiekty z pliku tekstowego iz powrotem do R na moim komputerze stacjonarnym. Oto działający przykład ilustrujący wyzwanie:

Stwórzmy plik tmp i napiszmy do niego pojedynczy obiekt. Ten obiekt znajduje się w odległości wektor:

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

Przedmiotem mychars wygląda następująco:

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

kiedy zapisywane do pliku tekstowego wygląda to tak:

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

Jestem chyba z widokiem czegoś niesamowicie oczywistego, ale jak mogę odczytać ten plik z powrotem do R i odserializować obiekt? Kiedy próbuję scan() lub readLines(), obydwa chcą traktować nowe znaki linii jako ograniczniki rekordów, a ja otrzymuję wektor, w którym każdy element jest wierszem z pliku tekstowego. Tym, czego naprawdę chcę, jest ciąg tekstowy z całą zawartością pliku. Następnie mogę odserializować ciąg.

Perl odczytuje podziały wiersza z powrotem na ciąg znaków, ale nie mogę wymyślić, jak zmienić sposób, w jaki R traktuje podziały wiersza.

Odpowiedz

7

JD, robimy to w pakiecie przez serialize() do/od raw. To miłe, ponieważ możesz przechowywać serializowane obiekty w SQL i innych miejscach. Właściwie przechowywałbym to również jako RData, co jest szybsze do load() (bez parsowania!) I save().

Lub, jeśli ma być RawToChar() i ASCII następnie użyć czegoś takiego (rodem z help(digest) gdzie porównamy szeregowanie pliku 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)) 
} 

więc z tym Twój przykład staje się w ten sposób:

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

Z perspektywy czasu powinienem był zachować moje obiekty jako surowe, będę pewny i zauważę, że kiedy zbieram razem moje lekcje z używania R na Hadoopie, wygląda na to, że brakowało mi funkcji readChar() Dzięki jeszcze raz Dirk! –

+0

Prawo. I zupełnie zapomniałem podłączyć nasz pakiet RProtoBuf, co oczywiście pomaga! Nie ma jeszcze binarnego systemu Windows, ponieważ nie mamy zbudowanej przez MinGW wersji biblioteki odpowiedniej do połączenia z R. –

Powiązane problemy