代码之家  ›  专栏  ›  技术社区  ›  89_Simple

在R中从pdf中提取表

pdf r
  •  0
  • 89_Simple  · 技术社区  · 8 年前

    我需要从pdf中提取表格。这是链接

    https://ainfo.cnptia.embrapa.br/digital/bitstream/item/155505/1/doc-202-1.pdf

    enter image description here

    Ciclo , Graus Dias/dias ,植物园 and 适应区`

    library(dplyr)
    library(tabulizer)
    
    out <- extract_tables("mydocument.pdf"), pages = c(15:21))
    
    # this gives me a list of 7 tables. 
    
    temp <- data.frame(out[[1]]) # taking the first table as an example
    temp %>% dplyr::select(X3, X4, X5, X12) # these are the columns corresponding to `Ciclo`, `Graus Dias/dias`, Epcaja de Plantion` and `Regiao de adaptacao`
    
    # this is a snapshot of first table
    

    enter image description here

    但是,当我提取第7个表时:

      temp <- data.frame(out[[7]])
    
    #  Column 1: 4 are merged into a single column. 
    

    enter image description here

    总而言之 extract_tables
    带有Ciclo列的组合表 , 格拉斯·迪亚斯/迪亚斯 , Epcaja de Plantion Regiao de adaptacao 在一个csv文件中。

    1 回复  |  直到 8 年前
        1
  •  2
  •   Steve    8 年前

    在我的经验中,这是一个数据准备和争论的问题,而不是一个解析问题,因为在本例中,tabulizer的解析算法除了在方法之间进行更改之外,没有提供太多的余地。从我所看到的,当我试图提取你的表,它不仅是第7页的表是错误的分析。每个页面的解析方式都不同,但所有的数据似乎都被保留了下来。我可以看到第一个表有13列,第二个17列,第三个12列,第四个10列,最后三个11列。我建议做的是单独解析每个页面,并根据每个页面上所需的输出执行数据清理,然后将它们绑定在一起。这是一个漫长的过程,对于解析的每个表都非常具体,因此我只提供一个示例脚本:

    library(dplyr)
    library(tidyr)
    library(tabulizer)
    # I create a dummy list to iterate through all the pages and push a data.frame in
    result <- list()
    for (i in 15:21){
      out <- as.data.frame(extract_tables("mydocument.pdf", page = i, method = 'stream'), stringsAsFactors = FALSE)
      result[[i]] <- out
    }
    # Remove excess list items -
    # there is probably a better way to do this from within the for loop
    result <- result[-(1:14)]
    
    ## ------- DATA CLEANING OPERATIONS examples:
    # Remove top 3x lines from the first page of table1 not part of data
    result[[1]] <- result[[1]][-(1:3),]
    # Perform data cleaning operations such as split/ merge columns according to your liking
    # for instance if you want to split column X1 into 4 (as in your original post), you can do that by splitting by whitespace
    result[[1]] <- separate(result[[1]], 1, into = c('X1.1','X1.2','X1.3', 'X1.4'),sep = ' ', remove = TRUE)
    
    ## ---- After data cleaning operations:
    # Bind all dataframes (they should have equal number of columns by now into one and make sure the colnames match as well)
    df <-bind_rows(result)
    # Write your output csv file
    write.csv(df, 'yourfilename.csv')
    

    另外,您可能想看看tabulizer的不同解析方法(我在这里将其设置为'stream',因为根据我的经验,这通常会产生最好的结果,但是也许'lattice'对某些表更有效)。