I am trying to scrape the first table of multiple PDF's that look quite similar. So far I have isolated the page of the table, converted the table to a string and loaded it into R
. Additionally, I also managed to remove the parts of the table I am not interested in as well as the header since it seemed like it will cause trouble because of the awkward spacing.
x <- pdf_text("2010 Table.pdf") # x is the string that I have attached at below
x <- unlist(strsplit(x, "Männer\r\n", fixed = T))[1]
x <- unlist(regmatches(x, regexpr("Insgesamt", x), invert = TRUE))[2]
cat(x)
0 b. unter 2 564.855 356.279 13.019 191.169 128.236 38 14.135 9.682 208.190 386
2 b. unter 4 300.245 205.375 31.056 96.882 68.185 18 7.032 2.202 94.062 808
4 b. unter 6 279.717 167.463 10.312 78.783 69.751 33 6.886 1.698 111.252 1.002
6 b. unter 8 247.614 140.412 22.926 62.535 47.390 88 6.554 919 105.818 1.384
8 b. unter 10 268.805 144.298 21.682 66.518 48.945 140 6.278 735 123.181 1.326
10 b. unter 12 393.303 144.576 18.387 65.387 51.705 177 8.500 420 245.470 3.257
12 b. unter 15 433.705 216.278 13.858 97.828 88.199 432 15.485 476 210.658 6.769
15 b. unter 18 423.441 224.532 4.804 106.780 94.846 1.116 16.552 434 188.577 10.332
18 b. unter 20 273.151 156.661 1.426 74.867 67.740 1.260 11.177 191 107.232 9.258
20 b. unter 25 653.650 389.246 1.330 190.154 156.275 5.086 36.186 215 234.087 30.317
25 b. unter 30 607.956 408.773 - 189.718 162.837 9.942 46.086 190 166.255 32.928
30 b. unter 35 501.137 357.262 - 141.724 150.686 19.403 45.196 253 110.461 33.414
35 b. unter 40 356.800 269.775 - 84.928 127.510 24.572 32.501 264 61.994 25.031
40 b. unter 50 422.582 348.116 - 70.498 187.365 54.388 35.555 310 41.506 32.960
50 b. unter 70 368.803 318.168 - 19.958 201.735 70.950 25.001 524 23.373 27.262
70 b. unter 100 160.051 140.411 - 850 105.534 25.262 8.311 454 9.441 10.199
100 b. unter 150 55.966 50.910 - - 42.024 5.961 2.541 384 3.336 1.720
150 b. unter 200 11.776 10.977 - - 10.028 587 252 110 674 125
200 und mehr 9.654 9.146 - - 8.828 182 104 32 475 33
Insgesamt ... 6,333.211 4,058.658 138.800 1.538.579 1.817.819 219.635 324.332 19.493 2.046.042 228.511
At this point, I thought that the best way to get this into a data.frame()
was to use read.table()
, unfortunately, since the spacing in between the columns is so inconsistent I cannot get it to work.
I appreciate any ideas, hints or solutions. Thanks!
Data
"Steuerpflichtige 2010 nach Geschlecht, sozialer Stellung und Bruttobezugsstufen\r\n Tabelle 2\r\n Davon\r\n Unselb- Pensionisten u.\r\n Stufen der Steuer- Pers. m. Pensionistinnen Beamte und\r\n ständig Arbeiter und\r\n Bruttobezüge pflichtige Beamte und sonst. o. Beamten und Beamtinnen\r\n Erwerbs- Lehrlinge Arbeite- Angestellte VB\r\n in 1.000 EUR insgesamt Beamtinnen Aktiv- Beamtinnen i. R. i.R.\r\n tätige rinnen\r\n bezügen\r\n Insgesamt\r\n 0 b. unter 2 564.855 356.279 13.019 191.169 128.236 38 14.135 9.682 208.190 386\r\n 2 b. unter 4 300.245 205.375 31.056 96.882 68.185 18 7.032 2.202 94.062 808\r\n 4 b. unter 6 279.717 167.463 10.312 78.783 69.751 33 6.886 1.698 111.252 1.002\r\n 6 b. unter 8 247.614 140.412 22.926 62.535 47.390 88 6.554 919 105.818 1.384\r\n 8 b. unter 10 268.805 144.298 21.682 66.518 48.945 140 6.278 735 123.181 1.326\r\n 10 b. unter 12 393.303 144.576 18.387 65.387 51.705 177 8.500 420 245.470 3.257\r\n 12 b. unter 15 433.705 216.278 13.858 97.828 88.199 432 15.485 476 210.658 6.769\r\n 15 b. unter 18 423.441 224.532 4.804 106.780 94.846 1.116 16.552 434 188.577 10.332\r\n 18 b. unter 20 273.151 156.661 1.426 74.867 67.740 1.260 11.177 191 107.232 9.258\r\n 20 b. unter 25 653.650 389.246 1.330 190.154 156.275 5.086 36.186 215 234.087 30.317\r\n 25 b. unter 30 607.956 408.773 - 189.718 162.837 9.942 46.086 190 166.255 32.928\r\n 30 b. unter 35 501.137 357.262 - 141.724 150.686 19.403 45.196 253 110.461 33.414\r\n 35 b. unter 40 356.800 269.775 - 84.928 127.510 24.572 32.501 264 61.994 25.031\r\n 40 b. unter 50 422.582 348.116 - 70.498 187.365 54.388 35.555 310 41.506 32.960\r\n 50 b. unter 70 368.803 318.168 - 19.958 201.735 70.950 25.001 524 23.373 27.262\r\n 70 b. unter 100 160.051 140.411 - 850 105.534 25.262 8.311 454 9.441 10.199\r\n100 b. unter 150 55.966 50.910 - - 42.024 5.961 2.541 384 3.336 1.720\r\n150 b. unter 200 11.776 10.977 - - 10.028 587 252 110 674 125\r\n200 und mehr 9.654 9.146 - - 8.828 182 104 32 475 33\r\n Insgesamt ... 6,333.211 4,058.658 138.800 1.538.579 1.817.819 219.635 324.332 19.493 2.046.042 228.511\r\n Männer\r\n 0 b. unter 2 248.906 160.190 6.586 93.371 48.212 29 5.114 6.878 88.630 86\r\n 2 b. unter 4 125.032 89.536 19.507 44.637 21.775 14 2.271 1.332 35.221 275\r\n 4 b. unter 6 89.016 63.413 5.071 35.777 19.838 22 1.784 921 25.212 391\r\n 6 b. unter 8 82.674 58.262 13.407 29.985 12.776 54 1.506 534 23.882 530\r\n 8 b. unter 10 85.708 56.336 12.730 29.898 11.816 106 1.303 483 28.905 467\r\n 10 b. unter 12 113.358 56.129 13.686 29.542 11.193 69 1.414 225 56.581 648\r\n 12 b. unter 15 151.134 76.371 11.879 45.603 16.424 64 2.189 212 73.581 1.182\r\n 15 b. unter 18 165.399 74.808 4.262 51.314 16.662 77 2.331 162 87.632 2.959\r\n 18 b. unter 20 114.691 56.582 1.327 40.448 12.967 120 1.631 89 54.817 3.292\r\n 20 b. unter 25 333.825 180.786 1.253 132.966 37.908 1.335 7.212 112 137.384 15.655\r\n 25 b. unter 30 368.614 239.655 - 162.373 56.488 4.739 15.925 130 110.753 18.206\r\n 30 b. unter 35 329.970 230.335 - 131.377 68.331 12.250 18.175 202 79.989 19.646\r\n 35 b. unter 40 236.845 178.551 - 80.873 68.707 14.633 14.118 220 43.882 14.412\r\n 40 b. unter 50 280.849 234.429 - 68.109 119.325 31.658 15.089 248 27.331 19.089\r\n 50 b. unter 70 260.231 225.846 - 19.120 152.331 41.375 12.658 362 16.225 18.160\r\n 70 b. unter 100 128.140 112.891 - 802 88.423 18.037 5.277 352 7.340 7.909\r\n100 b. unter 150 47.894 43.663 - - 36.447 5.003 1.924 289 2.759 1.472\r\n150 b. unter 200 10.380 9.685 - - 8.888 507 205 85 584 111\r\n200 und mehr 8.813 8.353 - - 8.081 153 94 25 431 29\r\n Insgesamt ... 3,181.479 2,155.821 89.708 996.195 816.592 130.245 110.220 12.861 901.139 124.519\r\n Frauen\r\n 0 b. unter 2 315.949 196.089 6.433 97.798 80.024 9 9.021 2.804 119.560 300\r\n 2 b. unter 4 175.213 115.839 11.549 52.245 46.410 4 4.761 870 58.841 533\r\n 4 b. unter 6 190.701 104.050 5.241 43.006 49.913 11 5.102 777 86.040 611\r\n 6 b. unter 8 164.940 82.150 9.519 32.550 34.614 34 5.048 385 81.936 854\r\n 8 b. unter 10 183.097 87.962 8.952 36.620 37.129 34 4.975 252 94.276 859\r\n 10 b. unter 12 279.945 88.447 4.701 35.845 40.512 108 7.086 195 188.889 2.609\r\n 12 b. unter 15 282.571 139.907 1.979 52.225 71.775 368 13.296 264 137.077 5.587\r\n 15 b. unter 18 258.042 149.724 542 55.466 78.184 1.039 14.221 272 100.945 7.373\r\n 18 b. unter 20 158.460 100.079 99 34.419 54.773 1.140 9.546 102 52.415 5.966\r\n 20 b. unter 25 319.825 208.460 77 57.188 118.367 3.751 28.974 103 96.703 14.662\r\n 25 b. unter 30 239.342 169.118 - 27.345 106.349 5.203 30.161 60 55.502 14.722\r\n 30 b. unter 35 171.167 126.927 - 10.347 82.355 7.153 27.021 51 30.472 13.768\r\n 35 b. unter 40 119.955 91.224 - 4.055 58.803 9.939 18.383 44 18.112 10.619\r\n 40 b. unter 50 141.733 113.687 - 2.389 68.040 22.730 20.466 62 14.175 13.871\r\n 50 b. unter 70 108.572 92.322 - 838 49.404 29.575 12.343 162 7.148 9.102\r\n 70 b. unter 100 31.911 27.520 - 48 17.111 7.225 3.034 102 2.101 2.290\r\n100 b. unter 150 8.072 7.247 - - 5.577 958 617 95 577 248\r\n150 b. unter 200 1.396 1.292 - - 1.140 80 47 25 90 14\r\n200 und mehr 841 793 - - 747 29 10 7 44 4\r\n Insgesamt ... 3,151.732 1,902.837 49.092 542.384 1.001.227 89.390 214.112 6.632 1.144.903 103.992\r\n 38\r\n"
You could use tabulizer::extract_tables()
. strsplit
"weird-spaced" columns and cbind
the snippets.
link <- "my.pdf"
library(tabulizer)
ext <- el(extract_tables(link, encoding="UTF-8"))
res <- cbind(ext[, 1:5], do.call(rbind, strsplit(ext[, 6], " ")),
ext[, 7:12])[, -c(2, 8)]
# store information for dim. names
dim.nm <- list(res[1:20, 1],
c("insg", "uns", "lehrl", "arb",
"ang", "beam", "VB", "sonst",
"pens", "beam.ir"))
# I would divide in a lists here
res <- list(insg=res[1:20, -1],
mann=res[22:41, -1],
frau=res[43:62, -1])
# convert to numbers (using gsub() to get rid of separators)
res <- Map(function(x) apply(x, 2, function(i) as.numeric(gsub("\\D", "", i))), res)
res <- lapply(res, `dimnames<-`, dim.nm)
head(res$insg)
# insg uns lehrl arb ang beam VB sonst pens beam.ir
# 0 b. unter 2 564855 356279 13019 191169 128236 38 14135 9682 208190 386
# 2 b. unter 4 300245 205375 31056 96882 68185 18 7032 2202 94062 808
# 4 b. unter 6 279717 167463 10312 78783 69751 33 6886 1698 111252 1002
# 6 b. unter 8 247614 140412 22926 62535 47390 88 6554 919 105818 1384
# 8 b. unter 10 268805 144298 21682 66518 48945 140 6278 735 123181 1326
# 10 b. unter 12 393303 144576 18387 65387 51705 177 8500 420 245470 3257