【问题标题】:R: serialize objects to text file and back againR:将对象序列化为文本文件并再次返回
【发布时间】:2010-02-13 18:04:37
【问题描述】:

我在 R 中有一个进程,它创建一堆对象,将它们序列化,然后将它们放入纯文本文件中。这似乎是一种处理事情的好方法,因为我正在使用 Hadoop,所有输出都需要通过标准输入和标准输出流式传输。

我剩下的问题是如何从文本文件中读取这些对象并返回到我桌面机器上的 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 处理换行符的方式。

【问题讨论】:

    标签: r serialization


    【解决方案1】:

    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> 
    

    【讨论】:

    • 回想起来,我应该让我的对象保持原始状态。我肯定并注意到,当我拼凑从在 Hadoop 上使用 R 中学到的经验教训时。看起来我缺少的是 readChar() 函数。再次感谢德克!
    • 对。而且我完全忘了插入我们的 RProtoBuf 包,这当然也有帮助!还没有 Windows 二进制文件,因为我们没有适合与 R 链接的 MinGW 构建的库版本。
    猜你喜欢
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 2016-02-09
    • 2016-04-02
    相关资源
    最近更新 更多