【问题标题】:R Find element of the list to extract table from pdfR查找列表的元素以从pdf中提取表格
【发布时间】:2022-01-04 13:26:10
【问题描述】:

我正在尝试使用 pdftools 包从 pdf 中提取数据表。我的源文件在这里:https://hypo.org/app/uploads/sites/2/2021/11/HYPOSTAT-2021_vdef.pdf。比如说,我想从第 170 页的表 20 中提取数据(名义房价的变化)

我使用以下代码:

install.packages("pdftools")
library(pdftools)

report <- pdftools::pdf_data("https://hypo.org/app/uploads/sites/2/2021/11/HYPOSTAT-2021_vdef.pdf")

tab20 <- as.data.frame(report[170])

为了获得正确的表格,我必须手动指出我要提取列表的第 170 个元素(因为表格在第 170 页上)。如果明年在报表中添加一个带有表格的新页面,我将不得不修改代码以提取第 171 个元素。有没有办法以更自动化的方式做到这一点?

基本上,我需要做的是找到包含字符串“名义房价变化”的列表元素。有什么建议吗?

【问题讨论】:

  • 您要求 data.frame 采用什么格式?您加载的 data.frame 中有字符串,但表格的格式与 pdf 上显示的格式大不相同。
  • @Gowachin 最后,我希望 DF 看起来像报告中的表格。我可以进一步清理它并使用 dplyr 等重新调整为正确的格式。但我想知道如何在不手动指定“170”作为参数的情况下首先获得 DF

标签: r pdftools


【解决方案1】:

您可以找到具有相应模式的字符串。 通过使用多个过滤器,您可以收集这个单一的表格。

table <- report[grepl('Change', report) & grepl('Nominal', report) &
                grepl('house', report)]

我想一个更微妙的正则表达式可以工作。这也只能工作,因为没有其他表具有相同的标题,但最好检查它是否只返回如下值:

place <- grepl('Change', report) &
            grepl('Nominal', report) &
            grepl('house', report)
if(sum(place) != 1){
  stop("There is not only one pattern that match. Adjust pattern.")
} else {
  table <- report[place]
}

编辑:为了加快速度,您最好使用@Paul Smith 解决方案。 我用 grepl 和 lapply 对其进行了调整,它更快!但是,您需要确保标题完全没有改变。

system.time(
place <- unlist(lapply(report, function(x) grepl("Change in Nominal house price",
                                        paste(x$text, collapse = " "))))
)
#        user      system       spent 
#        0.07        0.00        0.08 
system.time(
place <- grepl('Change', report) & grepl('Nominal', report) &
            grepl('house', report)
)
#        user      system       spent 
#        1.99        0.01        2.03 

【讨论】:

  • 在不调用 3 次函数的情况下,我找不到 grep 多个单词的方法(对于大型数据集,这可能需要很长时间)。欢迎任何加快速度的想法!
【解决方案2】:

另一种解决方案,基于purrr::map_lgl

library(tidyverse)
library(pdftools)

report <- pdftools::pdf_data("https://hypo.org/app/uploads/sites/2/2021/11/HYPOSTAT-2021_vdef.pdf")

map_lgl(
  report,
  ~ str_detect(
    str_c(.x$text, collapse = " "),
    "Change in Nominal house price")) %>% report[.]

#> [[1]]
#> # A tibble: 606 × 6
#>    width height     x     y space text       
#>    <int>  <int> <int> <int> <lgl> <chr>      
#>  1    59     14    39    38 TRUE  STATISTICAL
#>  2    35     14   102    38 FALSE TABLES     
#>  3    25     26    33    81 TRUE  20.        
#>  4    60     26    65    81 TRUE  Change     
#>  5    15     26   129    81 TRUE  in         
#>  6    67     26   149    81 TRUE  Nominal    
#>  7    47     26   221    81 TRUE  house      
#>  8    41     26   272    81 FALSE price      
#>  9    30     14    65   103 TRUE  Annual     
#> 10     7     14    98   103 TRUE  %          
#> # … with 596 more rows

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2013-05-29
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多