r - R中的Tabulizer包:如何在特定标题后抓取表格
问题描述
如何从PDF中刮取带有一些标题文本的表格?我正在尝试使用 tabulizer 包。这是从特定页面获取表格的示例(波兰语“公共卫生需求地图”)
library(tabulizer)
library(tidyverse)
options(java.parameters = "-Xmx8000m")
location<-"http://www.mpz.mz.gov.pl/wp-content/uploads/sites/4/2019/01/mpz_choroby_ukladu_kostno_miesniowego_woj_dolnoslaskie.pdf"
(out<-extract_tables(location, pages = 8,encoding = "UTF-8", method = "stream", outdir = getwd())[[4]] %>%
as.tibble())
这让我在特定页面获得一张桌子。但是我会从网站上刮掉很多这样的 pdf:http : //www.mpz.mz.gov.pl/mapy-dla-30-grup-chorob-2018/,然后是每个疾病都有很多链接的子页面,获取与 rvest 的链接,对于波兰的每个省,我需要在特定的标题字符串之后抓取表格,例如。
Tabela 1.2.2: Struktura zapadalnosci rejestrowanej w zależności od płci, miejsca zamieszkania oraz grupy wiekowej - Choroby układowe tkanki łącznej"
我需要检测 Tabela(...) Struktura zapadalnosci(...)",因为这些表格可能不在同一页面上。非常感谢您提前提供的任何指示和想法。
编辑:在我问了这个问题之后,到目前为止我成功地找到了表格可能所在的页面,可能非常无效:
library(pdfsearch)
pages <-
keyword_search(
location,
keyword = c(
'Tabela',
'Struktura zapadalnosci rejestrowanej'
),
path = TRUE,
surround_lines = FALSE
) %>%
group_by(page_num) %>%
mutate(keyword = paste0(keyword, collapse = ";")) %>%
filter(
str_detect(keyword, "Tabela") &
str_detect(keyword, "Struktura zapadalnosci rejestrowanej")
) %>%
pull(page_num) %>%
unique()
解决方案
我可以帮助您解决基本问题,但有一个问题(见最后)。我使用pdftools
而不是,pdfsearch
但在这种情况下它基本上做同样的事情(查找带有表格的页面)。为了节省时间,我一开始只下载一次PDF:
options(java.parameters = "-Xmx8000m")# needs to be set before loading tabulizer
library(tabulizer)
library(tidyverse)
location <- "http://www.mpz.mz.gov.pl/wp-content/uploads/sites/4/2019/01/mpz_choroby_ukladu_kostno_miesniowego_woj_dolnoslaskie.pdf"
download.file(location, "test.pdf", mode = "wb")
现在将 pdf 转换为 data.frame,其中每一行都在 df 的一行中:
raw <- pdftools::pdf_data("test.pdf")
pages <- lapply(seq_along(raw), function(p) {
if (nrow(raw[[p]]) > 0) {
raw[[p]]$page <- p
raw[[p]]
}
}) %>%
bind_rows() %>%
group_by(y, page) %>%
summarise(text = paste(text, collapse = " ")) %>%
arrange(page, y)
这个 data.frame 是可搜索的,我们只保留适合您关键字的行:
tables <- pages %>%
filter(grepl("Tabela .* Struktura zapadalnosci", text))
有 8 行适合关键短语。我们只从这些中提取表格。此外,lapply
循环内的函数只保留行数最多的矩阵。如果一页上有两个表,这可能是一个问题,但通常只使用tabulizer
找到表结构的“最佳猜测”会很好。
tables_list <- lapply(tables$page, function(p) {
cat(p, "\n")
out <- extract_tables("test.pdf",
pages = p,
encoding = "UTF-8",
method = "stream",
output = "matrix")
out <- as_tibble(out[[which.max(sapply(out, nrow) + sapply(out, ncol))]]) # keep the biggest table
attr(out, "caption") <- tables$text[tables$page %in% p]
return(out)
})
该对象tables_list
现在包含一个列表data.frames
,每个列表都是一个转换后的表:
> tables_list[[1]]
# A tibble: 16 x 8
V1 V2 V3 V4 V5 V6 V7 V8
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 dolnośląskie 77,05 74,65 4,04 10,59 13,37 27,87 44,14
2 kujawsko-pomorskie 78,12 65,93 4,29 14,96 14,82 27,01 38,92
3 lubelskie 76,50 56,83 2,67 14,83 17,00 29,00 36,50
4 lubuskie 79,10 76,23 4,92 12,70 12,70 30,74 38,93
5 łódzkie 74,37 67,77 6,45 13,84 15,09 30,03 34,59
6 małopolskie 72,71 55,35 6,99 14,63 12,01 25,87 40,50
7 mazowieckie 76,31 68,52 5,89 12,11 12,30 27,03 42,67
8 opolskie 79,55 54,65 4,83 10,04 17,47 26,02 41,64
9 podkarpackie 75,10 47,32 7,57 14,86 18,29 25,31 33,98
10 podlaskie 74,18 68,00 5,82 10,55 17,09 32,36 34,18
11 pomorskie 76,57 74,96 5,71 12,74 13,76 26,65 41,14
12 śląskie 73,51 81,15 4,89 14,96 14,43 26,64 39,08
13 świętokrzyskie 74,45 56,51 4,91 14,00 14,74 27,27 39,07
14 warmińsko-mazurskie 75,91 63,22 5,62 13,59 18,48 29,53 32,79
15 wielkopolskie 72,66 62,71 3,62 14,37 14,77 29,45 37,79
16 zachodniopomorskie 74,26 73,21 8,44 13,71 11,60 24,89 41,35
我还将每个表的(第一行)标题作为属性添加到data.frame
:
> attr(tables_list[[1]], "caption")
[1] "Tabela 1.2.2: Struktura zapadalnosci rejestrowanej w zależności od płci, miejsca zamieszkania oraz grupy"
将此与pdf进行比较:
似乎这很好用,只是列名不见了。不确定是否有办法保留它们,但你的问题中没有包含,所以也许你已经有了解决方案?
推荐阅读
- javascript - 为什么我的 ejs 模板无法正常显示?
- vba - 使用复选框使区域不可编辑
- c# - 从网络摄像头录制视频的速度有问题
- angular - 空体发送文件列表
- ios - 应用程序重新启动/重建后,文件 URL 无法从书签中解析
- react-native - React Navigation 5.x 版:将状态和功能传递给所有屏幕
- google-cloud-platform - 什么是 Cloud Firestore 实体写入配额?
- angular - Angular + 动态加载的 Fontawesome 图标错误
- javascript - 为什么这段代码无法修改 MongoDB 用户?
- python - Python:Elasticsearch 中的通配符查询