【问题标题】:write a gzip file from data frame从数据框中写入 gzip 文件
【发布时间】:2012-12-22 22:19:54
【问题描述】:

我正在尝试将数据框写入 gzip 文件但遇到问题。

这是我的代码示例:

df1 <- data.frame(id = seq(1,10,1), var1 = runif(10), var2 = runif(10))

gz1 <- gzfile("df1.gz","w" )
writeLines(df1)

writeLines(df1) 中的错误:“文本”参数无效

有什么建议吗?

编辑: 我正在尝试编写的字符向量的示例行是:

0 | var1:1.5 var2:.55 var7:1250

类标签 / y 变量通过“|”与 x-vars 分隔,变量名称与值通过“:”和变量之间的空格分隔。

编辑2: 对于问题的措辞/格式,我深表歉意,但结果如下: 老方法:

system.time(write(out1, file="out1.txt"))
#    user  system elapsed 
#   9.772  17.205  86.860 

新方法:

writeGzFile <- function(){
  gz1 = gzfile("df1.gz","w");
  write(out1, gz1);
  close(gz1) 
}

system.time( writeGzFile())
#    user  system elapsed 
#   2.312   0.000   2.478 

非常感谢大家帮我解决这个问题。

【问题讨论】:

  • 在 Rhelp 上经常被问到:“你想解决什么问题”。
  • 提示:@DWin 评论的答案不是“如何将数据框写入 gzip 文件?”
  • 更长的问题是“从 R 中写入 .txt 文件或 .gz 文件是否更快?”
  • 这取决于你的字符串有多长。在计算机方面,无论您的 CPU 还是 I/O 都是瓶颈。将大文件写入快速磁盘比在慢速 CPU 上计算压缩形式要快。
  • 我希望得到“以save 以外的方式处理 R 数据对象的目的”这个问题的答案?你需要它被 R 以外的程序读取吗?

标签: r zip compression gzip vowpalwabbit


【解决方案1】:

writeLines 需要一个字符串列表。将其写入 gzip 文件的最简单方法是

df1 <- data.frame(id = seq(1,10,1), var1 = runif(10), var2 = runif(10))
gz1 <- gzfile("df1.gz", "w")
write.csv(df1, gz1)
close(gz1)

这会将其写为压缩的 csv。另请参阅 write.tablewrite.csv2 了解写出文件的替代方法。

编辑:基于对所需格式的帖子的更新,我制作了以下助手(快速组合在一起,可能承认大量简化):

function(df) {
    rowCount <- nrow(df)
    dfNames <- names(df)
    dfNamesIndex <- length(dfNames)
    sapply(1:rowCount, function(rowIndex) {
        paste(rowIndex, '|', 
            paste(sapply(1:dfNamesIndex, function(element) {
                c(dfNames[element], ':', df[rowIndex, element])
            }), collapse=' ')
        )
    })
}

所以输出看起来像

a <- data.frame(x=1:10,y=rnorm(10))
writeLines(myser(a))
# 1 | x : 1 y : -0.231340933021948
# 2 | x : 2 y : 0.896777389870928
# 3 | x : 3 y : -0.434875004781075
# 4 | x : 4 y : -0.0269824962632977
# 5 | x : 5 y : 0.67654540494899
# 6 | x : 6 y : -1.96965253674725
# 7 | x : 7 y : 0.0863177759402661
# 8 | x : 8 y : -0.130116466571162
# 9 | x : 9 y : 0.418337557610229
# 10 | x : 10 y : -1.22890714891874

只需将 gzfile 传递给 writeLines 即可获得所需的输出。

【讨论】:

【解决方案2】:

要将某些内容写入 gzip 文件,您需要将其“序列化”为文本。对于 R 对象,您可以使用 dput 进行尝试:

gz1 = gzfile("df1.gz","w")
dput(df1, gz1)
close(gz1)

但是,您刚刚将数据框的文本表示形式写入文件。这很可能比使用save(df1,file="df1.RData") 将其保存到本机 R 数据文件效率低。问问自己:我为什么要将它保存为 .gz 文件?

在使用一些随机数的快速测试中,gz 文件为 54k,.RData 文件为 34k

【讨论】:

  • 谢谢。我写 .gz 的原因是输出是另一个读取 .gz 文件的程序的输入文件。换句话说,它正在离开 R 生态系统。否则我会使用 .RData。
  • 所以只是 gzip .RData 文件?不,那是行不通的,因为 gzip 是一种压缩方式,它不会告诉您未压缩时文件中数据的格式。它是压缩的 CSV 文件、压缩的 NetCDF 文件还是压缩的 RData 文件?你还没告诉我们。
  • 抱歉,我将它用作名为 vowpal wabbit 的程序的输入文件。它使用 '|'、':' 和 ' ' 进行了一些奇怪的分隔。
  • 我们离真正的问题越来越近了。想要编辑您的内容以更多地说明您想要做什么?似乎另一个答案(write.csv)可能会更好。但这是猜测。
  • 我正在使用'write(df1, file = "df1.txt")'。但它需要很长时间才能运行(大约 200k 行)。我很好奇使用 .gz 是否会更快,但无法让 R 编写 .gz 文件,这就是问题的原因。
【解决方案3】:

另一种非常简单的方法是:

# We create the .csv file
write.csv(df1, "df1.csv")

# We compress it deleting the .csv
system("gzip df1.csv")

想法来自:http://blog.revolutionanalytics.com/2009/12/r-tip-save-time-and-space-by-compressing-data-files.html

【讨论】:

    【解决方案4】:

    您可以使用 R.utils 中的 gzip 功能:

    library(R.utils)
    library(data.table)
    
    #Write gzip file
    df <- data.table(var1='Compress me',var2=', please!')
    fwrite(df,'filename.csv',sep=',')
    gzip('filename.csv',destname='filename.csv.gz')`
    
    #Read gzip file
    fread('gzip -dc filename.csv.gz')
              var1      var2
    1: Compress me , please!
    

    【讨论】:

      【解决方案5】:

      对于 tidyverse 方法,将压缩扩展名添加到文件名将执行压缩。从 https://readr.tidyverse.org/reference/write_delim.html

      如果给出了适当的扩展名,write_*() 函数将自动压缩输出。目前支持三种扩展,gzip压缩.gz,bzip2压缩.bz2,lzma压缩.xz。

      library(tidyverse)
      df <- data.table(var1='Compress me',var2=', please!')
      write_csv(df, "filename.csv.gz")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-25
        相关资源
        最近更新 更多