R: сериализация объектов в текстовый файл и обратно - PullRequest
8 голосов
/ 13 февраля 2010

У меня есть процесс в R, который создает группу объектов, сериализует их и помещает их в текстовые файлы. Казалось, это действительно хороший способ справиться с ситуацией, так как я работаю с Hadoop и весь вывод должен проходить через stdin и stdout.

Проблема, с которой я остаюсь, заключается в том, как прочитать эти объекты из текстового файла и вернуться в R на моем настольном компьютере. Вот рабочий пример, который иллюстрирует проблему:

Давайте создадим файл tmp и запишем в него один объект. Этот объект является просто вектором:

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

Объект mychars выглядит так:

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

при записи в текстовый файл это выглядит так:

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

Я, вероятно, упускаю из виду нечто ужасно очевидное, но как мне прочитать этот файл обратно в R и десериализовать объект? Когда я пытаюсь использовать scan () или readLines (), оба хотят рассматривать символы новой строки как разделители записей, и я получаю вектор, где каждый элемент представляет собой строку из текстового файла. Что мне действительно нужно, так это текстовая строка со всем содержимым файла. Тогда я могу десериализовать строку.

Perl будет читать разрывы строк обратно в строку, но я не могу понять, как переопределить способ, которым R обрабатывает разрывы строк.

1 Ответ

8 голосов
/ 13 февраля 2010

JD, мы делаем это в пакете digest через serialize() в / из raw. Это хорошо, так как вы можете хранить сериализованные объекты в SQL и других местах. На самом деле я бы также сохранил это как RData, что намного быстрее до load() (без разбора!) И save().

Или, если это должно быть RawToChar() и ascii, используйте что-то вроде этого (взято прямо из help(digest), где мы сравниваем сериализацию файла 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) )
 }

Итак, ваш пример становится таким:

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> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...