【发布时间】:2018-05-17 14:28:50
【问题描述】:
我正在努力自学将不规则间距的 PDF 表格转换为 R 中整洁的数据框的过程。我的目标是从最近的巴基斯坦人口普查中提取人口数据,该人口普查目前分布在 137 个单独的 pdf 文件中. Here 是一个示例目标文件。我已经能够将其他指南中的一些必要步骤拼凑起来,将 pdf 分解为文本字符串,但我陷入了正则表达式中,我认为这是将文本进一步转换为数据框所必需的。
到目前为止我已经能够弄清楚的步骤:
# import file
district_import <- pdf_text("http://www.pbscensus.gov.pk/sites/default/files/bwpsr/kp/ABBOTTABAD_BLOCKWISE.pdf")
# convert text to string
data <- toString(district_import)
# convert text to character lines
data <- read_lines(data)
# clean up page headers and footers
header_row_1 <- grep("POPULATION AND HOUSEHOLD DETAIL FROM BLOCK TO DISTRICT LEVEL", data)
header_row_2 <- grep("KHYBER PAKHTUNKHWA", data)
header_row_3 <- grep("ADMIN UNIT", data)
footer_row <- grep("Page ", data)
data <- data[- c(header_row_1, header_row_2, header_row_3, footer_row)]
在这个阶段我可以产生以下内容:
> head(data, 15)
[1] "ABBOTTABAD DISTRICT 1,332,912 216,534"
[2] " ABBOTTABAD TEHSIL 981,590 161,445"
[3] " ABBOTTABAD CANTONMENT 138,311 21183"
[4] " CHARGE NO 01 138,311 21183"
[5] " CIRCLE NO 01 12,150 1847"
[6] " 023010101 5,131 705"
[7] " 023010102 2,654 435"
[8] " 023010103 1,004 173"
[9] " 023010104 2,216 349"
[10] " 023010105 94 14"
[11] " 023010106 1,051 171"
[12] " CIRCLE NO 02 15,383 2435"
[13] " 023010201 1,352 211"
[14] " 023010202 1,019 161"
[15] " 023010203 4,079 691"
(请注意,虽然它通过此处的截止点显示,但前导空格的长度在整个文档中对于各个街道行政部门并不一致,我预计在 137 个区之间不会一致我最终的目标是循环并整合到一个全国性的数据框架中。)
从这一点开始,我想要的输出是将其转换为一个整洁的数据框,如下所示,人口普查块(六位代码,在原始 pdf 中未按名称标识)作为基本的组织单位:
district sub_lvl01 sub_lvl02 sub_lvl03 sub_lvl04 census_block population household
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 ABBOTTABAD DISTRICT ABBOTTABAD TEHSIL ABBOTTABAD CANTONMENT CHARGE NO 01 CIRCLE NO 01 023010101 5,131 705
2 ABBOTTABAD DISTRICT ABBOTTABAD TEHSIL ABBOTTABAD CANTONMENT CHARGE NO 01 CIRCLE NO 01 023010102 2,654 435
3 ABBOTTABAD DISTRICT ABBOTTABAD TEHSIL ABBOTTABAD CANTONMENT CHARGE NO 01 CIRCLE NO 01 023010103 1,004 173
4 ABBOTTABAD DISTRICT ABBOTTABAD TEHSIL ABBOTTABAD CANTONMENT CHARGE NO 01 CIRCLE NO 01 023010104 2,216 349
5 ABBOTTABAD DISTRICT ABBOTTABAD TEHSIL ABBOTTABAD CANTONMENT CHARGE NO 01 CIRCLE NO 01 023010105 94 14
6 ABBOTTABAD DISTRICT ABBOTTABAD TEHSIL ABBOTTABAD CANTONMENT CHARGE NO 01 CIRCLE NO 01 023010106 1,051 171
... etc
我一直在尝试使用正则表达式来试图弄清楚如何提取它,但这样做却相当迷茫,特别是考虑到变量之间缺乏标准分隔符。
在 regex101.com 上玩耍,我认为这段代码至少可以让我提取人口和家庭数据:
pop_hh_str <- str_match_all(data, "(?!\\d{6})(?<=\\s)\\d*[,.]*\\d*[,.]*\\d*")
但这会创建一个很大的列表,其中仍然包含空格,我不清楚如何将其转换为类似于数据框的任何内容(或与其他行政区变量匹配)。
任何有关如何考虑解决此问题的指导将不胜感激!
【问题讨论】: