从R

时间:2016-09-16 17:40:47

标签: r zip text-files extract

我正在尝试从位于一个文件夹中的每个zip文件中提取一个文本文件。然后我想将这些文本文件合并到一个数据帧中。

该文件夹有多个Zip文件:

pf_0915.zip
pf_0914.zip
pf_0913.zip
.....

这些zip文件中有多个文本文件。我只对名为abc.txt的那个感兴趣。这是一个没有标题的固定宽度格式文件。我已经使用read_fwd为此文件设置了读取。由于所有提取的文本文件都具有相同的名称,因此最好根据其归档的名称重命名它们。即来自pf_0915.zip的abc.txt可以称为abc_0915.txt。一旦它们全部被读取,它们应该组合成一个名为abcCombined.txt的大文件。

或者,当读取每个新的abc.txt文件时,我们可以将其添加到abcCombined.txt。

我尝试过各种版本的unzip()和unz()但没有取得多大成功。这是在没有遍历所有zip文件的情况下完成的。最后,这个目录包含很多zip文件,有没有办法只使用像grep这样的模式匹配来读取其中的一些。例如,我只想阅读9月份的文件,那些是.._ 09 ... txt。

任何提示都将不胜感激。

2 个答案:

答案 0 :(得分:1)

由于声誉不佳而无法发表评论,所以虽然这是一个部分答案:

如果您知道各种拉链中的文件名,那么获取该文件的语法将如下所示:

my_data<-read.csv(unz("pf_0915.zip","abc.txt"))

这显然是csv的代码,而不是固定宽度的文本,但是如果你已经有了这个设置,它就像是

my_data<-read_fwd(unz("pf_0915.zip","abc.txt") ... ) 

包含所有其他参数...

如果您有很多拉链,可以在循环中执行此操作,并将它们累积在数据框,数据表中,无论您的船上有什么结构......

答案 1 :(得分:1)

以下内容:

  1. 在目录
  2. 中创建文件的向量
  3. 使用list参数unzip()查看内容的元数据
  4. 构建正则表达式以仅查找目标文件(如果您的用例概括为更广泛的模式,我会这样做)
  5. 测试是否有任何文件符合您的条件
  6. 仅将这些文件保留为结果向量
  7. 迭代那个向量和
    • 仅将目标文件提取到临时目录
    • 将其读入data.frame
    • 最终将个人data.frame绑定为一个大的
  8. 您可以根据自己的意愿写出结果data.frame

    library(purrr)
    
    target_dir <- "so"
    extract_file <- "abc.txt"
    
    list.files(target_dir, full.names=TRUE) %>% 
      keep(~any(grepl(sprintf("^%s$", extract_file), unzip(., list=TRUE)$Name))) %>% 
      map_df(function(x) {
        td <- tempdir()
        read.fwf(unzip(x, extract_file, exdir=td), widths=c(4,1,4,2))
      }) -> combined_df
    

    下面的版本只展开了上面的一些快捷方式:

    only_files_with_this_name <- function(zip_path, name) {
      zip_contents <- unzip(zip_path, list=TRUE)
      look_for <- sprintf("^%s$", name)
      any(grepl(look_for, zip_contents$Name))
    }
    
    list.files(target_dir, full.names=TRUE) %>% 
      keep(only_files_with_this_name, name=extract_file)) %>% 
      map_df(function(x) {
        td <- tempdir()
        file_in_zip <- unzip(x, extract_file, exdir=td)
        read.fwf(file_in_zip, widths=c(4,1,4,2))
        unlink(file_in_zip)
      }) -> combined_df