首页 文章

R:将对象序列化为文本文件并再次返回

提问于
浏览
8

我在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

    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>
    

相关问题